这是在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;
}
答案 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)
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);