代码之家  ›  专栏  ›  技术社区  ›  Oyen

用户配置文件状态在WebChat上为空,但在Directline和Emulator上为空

  •  0
  • Oyen  · 技术社区  · 5 年前

    我正在通过 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}");
    

    测试结果如下: enter image description here

    示例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频道上一样在网络聊天频道上保持不变。我有什么东西不见了吗?可能是对网络聊天频道的特殊处理?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Senen Jr Ebio    5 年前

    ...
    var user = {id: 'test@test.com',
                name: 'You'
    };
    ....
    var dl = window.WebChat.createDirectLine({ token });
    window.WebChat.renderWebChat({
          directLine: dl,
          userId : user.id,
        }, document.getElementById('webchat'));
        document.querySelector('#webchat > *').focus();