我正在通过
StateBot访问器
我的多对话机器人。我注意到在
网络聊天
,通过_statebotaccessor.userprofileaccessor.getasync()检索用户配置文件时返回空值,但会话数据被持久化。通过Emulator和Directline进行的测试显示了正确填充的用户配置文件。
I created a git project built from EnterpriseBot template to show the problem.
下面是我的简单用户配置文件类:
public class UserProfile
{
public UserProfile(string name)
{
this.UserName = name;
}
public string UserName { get; set; }
}
下面是我的SimpleConversationData类:
public class ConversationData
{
public ConversationData(string channelId)
{
ChannelId = channelId;
}
// The ID of the user's channel.
public string ChannelId { get; set; }
}
这是我的statebotaccessor类:
public class StateBotAccessors
{
public StateBotAccessors(ConversationState conversationState, UserState userState)
{
ConversationState = conversationState ?? throw new ArgumentNullException("UserProfile");
UserState = userState ?? throw new ArgumentNullException("ConversationData");
}
public IStatePropertyAccessor<UserProfile> UserProfileAccessor { get; set; }
public IStatePropertyAccessor<ConversationData> ConversationDataAccessor { get; set; }
public IStatePropertyAccessor<DialogState> DialogStateAccessor { get; set; }
public ConversationState ConversationState { get; }
public UserState UserState { get; }
}
在startup.cs上,我注册statebotaccessors。我在这里使用了InMemory存储,我用Blob存储进行了测试,但是结果是相同的。
var dataStore = new MemoryStorage();
var userState = new UserState(dataStore);
var conversationState = new ConversationState(dataStore);
services.AddSingleton(dataStore);
var stateBotAccessors = new StateBotAccessors(conversationState, userState)
{
DialogStateAccessor = conversationState.CreateProperty<DialogState>("DialogState"),
ConversationDataAccessor = conversationState.CreateProperty<ConversationData>("ConversationData"),
UserProfileAccessor = userState.CreateProperty<UserProfile>("UserProfile"),
};
services.AddSingleton(stateBotAccessors);
在mainDialog.onStartAsync()上,我立即设置了用户配置文件和会话数据:
protected override async Task OnStartAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
var context = dc.Context;
// set userprofile and conversationdata
await _accessors.ConversationDataAccessor.SetAsync(context, new ConversationData(dc.Context.Activity.ChannelId));
await _accessors.UserProfileAccessor.SetAsync(context, new UserProfile("Elena"));
await dc.Context.SendActivityAsync($"ConversationData and UserProfile were set in MainDialog.OnStartAsync()");
// easier testing, I have this as a convenience method
var reply = context.Activity.CreateReply();
reply.Text = "Say 'print out state' or click the button.";
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction(type: ActionTypes.ImBack, title: "Test State", value: "print out state"),
}
};
await context.SendActivityAsync(reply);
}
我调用seconddialog如果用户的文本输入是“打印输出状态”,那么我将打印出会话数据和用户配置文件的内容,但在WebChat客户端上,用户配置文件始终为空:
var conversationState = await _accessors.ConversationDataAccessor.GetAsync(sc.Context, () => null);
var userProfile = await _accessors.UserProfileAccessor.GetAsync(sc.Context, () => null);
await sc.Context.SendActivityAsync($"conversationState.ChannelId: {conversationState?.ChannelId}");
await sc.Context.SendActivityAsync($"userProfile.UserName: {userProfile?.UserName}");
测试结果如下:
示例WebChat和Directline客户机位于Git项目的/clients文件夹下。
我的网络聊天客户端很简单:
const res = await fetch('https://directline.botframework.com/v3/directline/conversations',
{
method: 'POST',
headers: {
"Authorization": "Bearer mySecretKey",
},
});
const { token } = await res.json();
var dl = window.WebChat.createDirectLine({ token });
window.WebChat.renderWebChat({
directLine: dl,
user : user,
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
我希望用户配置文件像在Emulator和Directline频道上一样在网络聊天频道上保持不变。我有什么东西不见了吗?可能是对网络聊天频道的特殊处理?