使用ActivityPrompt从Webchat BOT Framework 4获取自定义事件

时间:2019-12-14 23:00:15

标签: c# botframework

我实现了抽象类ActivityPrompt来等待瀑布对话框中的自定义事件,该类的实现是这样的:

let index = require("../components/courses/index.vue").default;
let show = require("../components/courses/show.vue").default;

const routes = [
    {
        path: "/",
        name: "welcome",
        component: null
    },

    {
        path: "/courses",
        name: "courses.index",
        component: index
    },

    {
        path: "/course/show",
        name: "courses.show",
        component: show
    }
];

export default routes;

我在瀑布对话框中使用

public class EventActivityPrompt : ActivityPrompt
{
    public EventActivityPrompt(string dialogId, PromptValidator<Activity> validator) : base(dialogId, validator)
    {
    }
}

我正在通过网络聊天发送此消息:

AddDialog(new EventActivityPrompt(LoginSucessActivityPrompt, _validator));

var promptMessage = MessageFactory.Text("Wait for login", "", InputHints.IgnoringInput);
return await stepContext.PromptAsync(LoginSucessActivityPrompt, new PromptOptions { Prompt = promptMessage }, cancellationToken);

async Task<bool> _validator(PromptValidatorContext<Activity> promptContext, CancellationToken cancellationToken)
        {
            var activity = promptContext.Recognized.Value;

            if (activity.Type == ActivityTypes.Event && activity.Name == "LOGIN_SUCCESS")
            {
                promptContext.Recognized.Value = MessageFactory.Text("login sucess:" + activity.Value.ToString());
                return true;
            }
            else
            {
                await promptContext.Context.SendActivityAsync("Please send an 'event'-type Activity with a value of xxx.");
            }
            return false;
        }

此解决方案有效,但不适用于直接网上聊天发送的事件,我在OnTurnAsync上收到了该事件,但在验证程序中却没有,我从网上聊天发送了此事件。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

发送事件时未命中验证器的原因是因为WEB_CHAT/SEND_EVENT调度有效载荷未利用text属性(请参见here)。因此,尽管您在有效负载中包含了text属性,但是当它到达您的漫游器时,它已经被忽略/剥离了,如下所示:

store.dispatch( {
  type: 'WEB_CHAT/SEND_EVENT',
  payload: {
    name: 'LOGIN_SUCCESS',
    value: {
      name: 'LOGIN_SUCCESS',
      value: {
        userid: '123456789',
        session: '123456'
      }
    },
    text: 'yes'
  }
} )
{ type: 'event',
  id: 'EEzl4C4p6AHKfMwIuhmLTM-o|0000006',
  timestamp: 2019-12-17T20:31:46.276Z,
  serviceUrl: 'https://directline.botframework.com/',
  channelId: 'directline',
  from: { id: 'dl_123', name: 'johndoe', role: 'user' },
  conversation: { id: 'EEzl4C4p6AHKfMwIuhmLTM-o' },
  recipient: { id: 'b******@QaeuoeEamLg', name: 'D****** *****r' },
  locale: 'en-US',
  channelData:
   { clientActivityID: '15766147033627cr89fn0ns3',
     clientTimestamp: '2019-12-17T20:31:43.362Z' },
  value:
   { name: 'LOGIN_SUCCESS',
     value: { userid: '123456789', session: '123456' } },
  name: 'LOGIN_SUCCESS'
}

要解决此问题,您需要分派两个动作WEB_CHAT/SEND_MESSAGEWEB_CHAT/SEND_EVENT。第一个将在提示和验证器中注册。第二个是事件信息。如果您需要在验证成功后发送事件数据,则可以分派WEB_CHAT/SEND_EVENT来响应bot在验证时发送的一些返回值。在这种情况下,您将使用action.type === 'DIRECT_LINE/INCOMING_ACTIVITY',匹配返回值,然后发送事件(例如here)。

store.dispatch({
  type: 'WEB_CHAT/SEND_MESSAGE',
  payload: {
    text: 'yes'
  }
} ),
store.dispatch( {
  type: 'WEB_CHAT/SEND_EVENT',
  payload: {
    name: 'LOGIN_SUCCESS',
    value: {
      name: 'LOGIN_SUCCESS',
      value: {
        userid: '123456789',
        session: '123456'
      }
    },
    text: 'yes'
  }
} )

或者,根据您的用例,您可以通过Web Chat在已发布消息活动的channelData属性中发送事件数据。您可以像在任何事件上一样轻松地对此进行过滤,并将工作负载减少到一个动作。在下面的示例中,为简单起见,我将匹配文本输入。

<script src="https://unpkg.com/simple-update-in/dist/simple-update-in.production.min.js"></script>

if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
  if(action.payload.activity && action.payload.activity.text) {
    let text = action.payload.activity.text.toLowerCase();
    if(text === 'logged in') {
      const userid = 'xyz789';
      const session = '123456';
      action = window.simpleUpdateIn(
        action,
        ['payload', 'activity', 'channelData'],
        () => ({
          'userId': userid,
          'userDetails': session
        })
      )
    } 
  }
}

希望有帮助!