Поделиться через


Отправка упреждающих уведомлений пользователям

ОБЛАСТЬ ПРИМЕНЕНИЯ: ПАКЕТ SDK версии 4

Как правило, бот отправляет пользователю сообщение непосредственно в ответ на получение сообщения от пользователя. Иногда боту может потребоваться отправить упреждающее сообщение, сообщение в ответ на стимулы, не поступающие от пользователя.

Упреждающие сообщения могут быть полезны в различных сценариях. Например, если пользователь ранее попросил бот отслеживать стоимость продукта, то бот может оповестить пользователя в случае, если стоимость продукта опустилась на 20 %. Если боту требуется какое-то время, чтобы сформировать ответ на вопрос пользователя, он может проинформировать пользователя о задержке и продолжить диалог. Когда бот сформирует ответ на вопрос, он передаст его пользователю.

В этой статье рассматриваются сведения об упреждающих сообщениях для ботов в целом. Сведения об упреждающих сообщениях в Microsoft Teams см. в статье

Примечание.

Пакеты SDK для JavaScript, C# и Python для Bot Framework по-прежнему будут поддерживаться, однако пакет SDK java отменяется с окончательной долгосрочной поддержкой, заканчивающейся в ноябре 2023 года.

Существующие боты, созданные с помощью пакета SDK для Java, будут продолжать функционировать.

Для создания нового бота рекомендуется использовать Microsoft Copilot Studio и ознакомиться с выбором подходящего решения copilot.

Дополнительные сведения см. в статье "Будущее создания бота".

Необходимые компоненты

Сведения о примере с упреждающими сообщениями

Как правило, бот в качестве приложения имеет несколько уровней:

  • Веб-приложение, которое может принимать HTTP-запросы и специально поддерживает конечную точку обмена сообщениями.
  • Адаптер, который обрабатывает подключение к каналам.
  • Обработчик для поворота, как правило, инкапсулированный в классе бота, который обрабатывает беседную причину для приложения бота .

В ответ на входящее сообщение от пользователя приложение вызывает метод действия процесса адаптера, который создает контекст поворота и поворота, вызывает конвейер ПО промежуточного слоя, а затем вызывает обработчик поворота бота.

Чтобы инициировать упреждающее сообщение, приложение бота должно иметь возможность получать другие входные данные. Логика приложения для инициирования упреждающего сообщения выходит за рамки пакета SDK. В этом примере конечная точка уведомления в дополнение к стандартной конечной точке сообщений используется для активации упреждающего поворота.

В ответ на запрос GET на эту конечную точку уведомления приложение вызывает метод продолжения беседы адаптера, который ведет себя аналогично методу действия процесса. Метод продолжения беседы :

  • Принимает соответствующую ссылку на беседу для пользователя и метода обратного вызова, которые будут использоваться для упреждающего поворота.
  • Создает действие события и контекст поворота для упреждающего поворота.
  • Вызывает конвейер ПО промежуточного слоя адаптера.
  • Вызывает предоставленный метод обратного вызова.
  • Контекст поворота использует ссылку на беседу для отправки сообщений пользователю.

В примере есть бот, конечная точка сообщений и дополнительная конечная точка, которая используется для отправки упреждающих сообщений пользователю, как показано на следующем рисунке.

Схема взаимодействия, показывающая, как бот получает ссылку на беседу и использует ее для отправки упреждающего сообщения.

Получение и хранение ссылки на беседу

Когда эмулятор Bot Framework подключается к боту, бот получает два действия обновления беседы. В обработчике бота для действий обновления беседы извлекается ссылка на беседу, которая сохраняется в словаре, как показано ниже.

Bots\ProactiveBot.cs

private void AddConversationReference(Activity activity)
{
    var conversationReference = activity.GetConversationReference();
    _conversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);
}

protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    AddConversationReference(turnContext.Activity as Activity);

    return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);
}

Ссылка на беседу содержит свойство беседы , описывающее беседу, в которой существует действие. Беседа содержит свойство пользователя , которое перечисляет пользователей, участвующих в беседе, и свойство URL-адреса службы, указывающее, где могут отправляться ответы на текущее действие. Для отправки пользователям упреждающих сообщений нужно получить допустимую ссылку на беседу. (Для канала Teams URL-адрес службы сопоставляется с регионализованным сервером.)

Примечание.

В реальной системе ссылки на беседы следует хранить в базе данных, а не в объекте в памяти.

Отправить проактивное сообщение

Второй контроллер, контроллер уведомления , отвечает за отправку упреждающего сообщения пользователю. В нем используются следующие действия для создания упреждающего сообщения.

  1. Извлекает ссылку на беседу, в которую отправляется упреждающее сообщение.
  2. Вызывает метод продолжения беседы адаптера , предоставляя ссылку на беседу и делегат обработчика поворота для использования. (Метод продолжения беседы создает контекст поворота для указанной беседы, а затем вызывает указанный делегат обработчика поворота.)
  3. В делегате используется контекст поворота для отправки упреждающего сообщения. Здесь делегат определяется на контроллере уведомлений и отправляет пользователю упреждающее сообщение.

Примечание.

Хотя каждый канал должен использовать стабильный URL-адрес службы, URL-адрес может меняться со временем. Дополнительные сведения о URL-адресе службы см. в разделах "Базовая структура действий" и "URL-адрес службы" схемы действий Bot Framework.

Если URL-адрес службы изменяется, предыдущие ссылки на беседы больше не будут допустимыми, и вызовы для продолжения беседы будут вызывать ошибку или исключение. В этом случае боту потребуется получить новую ссылку на беседу для пользователя, прежде чем он сможет отправить упреждающие сообщения еще раз.

Controllers\NotifyController.cs

При каждом запросе страницы уведомления бота соответствующий контроллер извлекает из словаря ссылки на беседы. Этот контроллер выполняет методы ContinueConversationAsync и BotCallback, чтобы отправить упреждающее сообщение.

[Route("api/notify")]
[ApiController]
public class NotifyController : ControllerBase
{
    private readonly IBotFrameworkHttpAdapter _adapter;
    private readonly string _appId;
    private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;

    public NotifyController(IBotFrameworkHttpAdapter adapter, IConfiguration configuration, ConcurrentDictionary<string, ConversationReference> conversationReferences)
    {
        _adapter = adapter;
        _conversationReferences = conversationReferences;
        _appId = configuration["MicrosoftAppId"] ?? string.Empty;
    }

    public async Task<IActionResult> Get()
    {
        foreach (var conversationReference in _conversationReferences.Values)
        {
            await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));
        }
        
        // Let the caller know proactive messages have been sent
        return new ContentResult()
        {
            Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
            ContentType = "text/html",
            StatusCode = (int)HttpStatusCode.OK,
        };
    }

    private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
    {
        await turnContext.SendActivityAsync("proactive hello");
    }
}

Для отправки упреждающего сообщения адаптеру нужен идентификатор приложения бота. В рабочей среде для этого можно использовать реальный идентификатор приложения бота. Для локального тестирования бота с помощью эмулятора можно использовать пустую строку ("").

Тестирование бота

  1. Если это еще не сделано, установите эмулятор Bot Framework.
  2. Выполните этот пример на локальном компьютере.
  3. Запустите эмулятор и подключитесь к боту.
  4. Загрузите страницу бота api/notify. Это создаст упреждающее сообщение в эмуляторе.

Дополнительная информация:

Требования

Перед отправкой упреждающего сообщения боту требуется ссылка на беседу. Бот может получить ссылку на беседу из любого действия, полученного от пользователя, но это обычно требует от пользователя взаимодействовать с ботом по крайней мере один раз, прежде чем бот может отправить упреждающее сообщение.

Многие каналы запрещают боту обмен сообщениями пользователя, если пользователь не отправляет боту по крайней мере один раз. Некоторые каналы разрешают исключения. Например, канал Teams позволяет боту отправлять упреждающее сообщение (или 1-по-1) отдельным лицам в уже установленной групповой беседе, включающей бота.

Рекомендации по проектированию

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

Для простого типа упреждающего сообщения бот пересекает сообщение в беседу при его активации без учета текущего состояния или темы беседы. В этом сценарии упреждающее сообщение прерывает обычный поток беседы.

Чтобы улучшить обработку уведомлений, рассмотрите другие варианты их интеграции в поток общения, например указав флаг в состоянии диалога или добавив уведомление в очередь.

О упреждающем повороте

Метод продолжения беседы использует ссылку на беседу и обработчик обратного вызова для:

  1. Создайте поворот, в котором приложение бота может отправлять упреждающее сообщение. Адаптер создает event действие для этого поворота, присвоив ей имя "ContinueConversation".
  2. Отправьте поворот через конвейер ПО промежуточного слоя адаптера.
  3. Вызовите обработчик обратного вызова для выполнения пользовательской логики.

В примере упреждающих сообщений обработчик обратного вызова определяется в контроллере уведомлений и отправляет сообщение непосредственно в беседу, не отправляя упреждающее действие через обычный обработчик поворота бота. Пример кода также не обращается к состоянию бота или не обновляет его состояние в упреждающем повороте.

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

  • Укажите обработчик поворота бота в качестве обработчика обратного вызова. Затем бот получит действие события "ContinueConversation".
  • Используйте обработчик обратного вызова, чтобы сначала добавить сведения в контекст поворота, а затем вызвать обработчик поворота бота.

В обоих случаях необходимо разработать логику бота для обработки упреждающего события.

Следующие шаги