Bot Framework Проактивные сообщения - PullRequest
0 голосов
/ 03 мая 2018

Я создаю систему событий, в которой чат-бот может использоваться для запуска задания во внешней системе. Как только задание получено внешней системой, она запускает то, что ей нужно для запуска, и затем уведомляет очередь в Azure о том, что задание завершено.

Далее у меня есть приложение-функция, которое просматривает эту очередь. Как только новая информация получена (содержит идентификатор, ConversationReferenceObject и ответ задания), она уведомляет бота через ProactiveMessage:

var conversationReference = JsonConvert.DeserializeObject<ConversationReference>(subscription.ConversationReference);

MicrosoftAppCredentials.TrustServiceUrl(conversationReference.ServiceUrl);

var client = new ConnectorClient(new Uri(conversationReference.ServiceUrl), new MicrosoftAppCredentials(appId, appPassword));

var result = conversationReference.GetPostToBotMessage().CreateReply($@"[ProactiveMessage] Your job response: {response.data}");

client.Conversations.ReplyToActivity((Activity)result);

Теперь, вместо того, чтобы публиковать этот ответ на активность бота, я хочу, чтобы чат-перехватчик перехватывал [ProactiveMessage], а затем отвечал бы пользователю, только если диалог в данный момент не активен - просто обычно правильно управлял потоком разговоров.

Теперь мне интересно, имеет ли client.Conversations другую функцию, где я могу публиковать сообщения в чат-боте, а не отвечать на текущий разговор? Я немного застрял.

1 Ответ

0 голосов
/ 24 мая 2018

Если вы хотите проверить текущий стек диалогов для пользователя, который первоначально отправил сообщение, вы можете использовать что-то вроде этого:

var fromConversation = conversationReference.GetPostToBotMessage();

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, fromConversation))
{
    var botData = scope.Resolve<IBotData>();
    await botData.LoadAsync(default(CancellationToken));

    var stack = scope.Resolve<IDialogTask>();
    if (stack.Frames != null && stack.Frames.Count > 0)
    {
        var lastFrame = stack.Frames[stack.Frames.Count - 1];
        var frameValue = lastFrame.Target.GetType().GetFields()[0].GetValue(lastFrame.Target);
        if (frameValue is NodeRootDialog) //<-- only reply if user is in NodeRootDialog
        {
            var reply = fromConversation.CreateReply("used converation reference to reply");
            var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
            await connector.Conversations.ReplyToActivityAsync(reply);
        }
    }
}
...