从触发器启动对话框

时间:2017-03-08 14:37:55

标签: c# triggers dialog queue botframework

这是在C#上,在Skype频道上:

是否可以从触发器开始与用户对话?

场合: 在一个定时的时刻,我想向所有注册用户显示一个对话框(我有一个resumptioncookie) 所以我有一个azure函数来监视队列并触发我的机器人。在那个触发器上,我可以发送一条简单的消息,但我想在那一刻开始对话。

[BotAuthentication]
public class MessagesController: ApiController {
  public async Task < HttpResponseMessage > Post([FromBody] Activity activity) {
    if (activity != null) {
     switch (activity.GetActivityType()) {
      case ActivityTypes.Message:
       //some stuff here, not important for now
       break;

      case ActivityTypes.Trigger:
       //This does not work:
       await Conversation.SendAsync(activity, () => new ExceptionHandlerDialog < object > (new BroodjesDialog(), true));

       //But this does:
       IEventActivity trigger = activity;
       var message = JsonConvert.DeserializeObject < Message > (((JObject) trigger.Value).GetValue("Message").ToString());

       await Resume((Activity) message.ResumptionCookie.GetMessage());

       var messageactivity = (Activity) message.ResumptionCookie.GetMessage();
       client = new ConnectorClient(new Uri(messageactivity.ServiceUrl));
       var triggerReply = messageactivity.CreateReply();
       triggerReply.Text = $ "Let's do some talking";
       await client.Conversations.ReplyToActivityAsync(triggerReply);
       break;
     }
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

2 个答案:

答案 0 :(得分:1)

检查bot框架提供的这个AlarmBot示例,它显示了如何从外部事件开始对话。

namespace Microsoft.Bot.Sample.AlarmBot.Models
{
    /// <summary>
    /// This method represents the logic necessary to respond to an external event.
    /// </summary>
    public static class ExternalEvent
    {
        public static async Task HandleAlarm(Alarm alarm, DateTime now, CancellationToken token)
        {
            // since this is an externally-triggered event, this is the composition root
            // find the dependency injection container
            var container = Global.FindContainer();

            await HandleAlarm(container, alarm, now, token);
        }

        public static async Task HandleAlarm(ILifetimeScope container, Alarm alarm, DateTime now, CancellationToken token)
        {
            // the ResumptionCookie has the "key" necessary to resume the conversation
            var message = alarm.Cookie.GetMessage();
            // we instantiate our dependencies based on an IMessageActivity implementation
            using (var scope = DialogModule.BeginLifetimeScope(container, message))
            {
                // find the bot data interface and load up the conversation dialog state
                var botData = scope.Resolve<IBotData>();
                await botData.LoadAsync(token);

                // resolve the dialog stack
                var stack = scope.Resolve<IDialogStack>();
                // make a dialog to push on the top of the stack
                var child = scope.Resolve<AlarmRingDialog>(TypedParameter.From(alarm.Title));
                // wrap it with an additional dialog that will restart the wait for
                // messages from the user once the child dialog has finished
                var interruption = child.Void(stack);

                try
                {
                    // put the interrupting dialog on the stack
                    stack.Call(interruption, null);
                    // start running the interrupting dialog
                    await stack.PollAsync(token);
                }
                finally
                {
                    // save out the conversation dialog state
                    await botData.FlushAsync(token);
                }
            }
        }
    }
}

答案 1 :(得分:1)

自3.5.5起,

ResumptionCookie已弃用。 (翻录),从现在开始,如果您计划将来恢复对话,则应使用/跟踪ConversationReference

使用Autofac直接在控制器中获取ConversationReference我。

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    var convRef = scope.Resolve<ConversationReference>();

    StoreInSomewhere(convRef);
}

如果您想恢复对话,可以使用ResumeAsync或向用户发送直接消息,如下所示:

// this is the previously recorded CR
ConversationReference convRef = GetFromSomewhere();

ConnectorClient connector = new ConnectorClient(new Uri(convRef.ServiceUrl));
IMessageActivity newMessage = Activity.CreateMessageActivity();
newMessage.From = convRef.Bot;
newMessage.Conversation = convRef.Conversation;
newMessage.Recipient = convRef.User;
newMessage.Text = "This is the message";
await connector.Conversations.SendToConversationAsync((Activity)newMessage);