Partilhar via


Enviar notificações proativas aos usuários

APLICA-SE A: SDK v4

Normalmente, um bot envia uma mensagem para um usuário diretamente em resposta ao recebimento de uma mensagem do usuário. Ocasionalmente, um bot pode precisar enviar uma mensagem proativa, uma mensagem em resposta a estímulos não originários do usuário.

Mensagens proativas podem ser úteis em vários cenários. Por exemplo, se o usuário pediu anteriormente ao bot para monitorar o preço de um produto, o bot pode alertar o usuário se o preço do produto caiu 20%. Ou, se um bot precisar de algum tempo para compilar uma resposta à pergunta do usuário, ele pode informar o usuário do atraso e permitir que a conversa continue enquanto isso. Quando o bot terminar de compilar a resposta à pergunta, ele compartilhará essas informações com o usuário.

Este artigo aborda informações sobre mensagens proativas para bots em geral. Para obter informações sobre mensagens proativas no Microsoft Teams, consulte

Nota

Os SDKs JavaScript, C# e Python do Bot Framework continuarão a ser suportados, no entanto, o Java SDK está sendo desativado com suporte final de longo prazo terminando em novembro de 2023.

Os bots existentes construídos com o Java SDK continuarão a funcionar.

Para a criação de novos bots, considere usar o Microsoft Copilot Studio e leia sobre como escolher a solução de copilot certa.

Para obter mais informações, consulte O futuro da criação de bots.

Pré-requisitos

Sobre a amostra proativa

Em geral, um bot como aplicativo tem algumas camadas:

  • O aplicativo Web que pode aceitar solicitações HTTP e suporta especificamente um ponto de extremidade de mensagens.
  • Um adaptador que lida com a conectividade com os canais.
  • Um manipulador para o turno, normalmente encapsulado em uma classe de bot que lida com o raciocínio conversacional para o aplicativo de bot.

Em resposta a uma mensagem recebida do usuário, o aplicativo chama o método de atividade de processo do adaptador, que cria um contexto de turno e volta, chama seu pipeline de middleware e, em seguida, chama o manipulador de turnos do bot.

Para iniciar uma mensagem proativa, o aplicativo bot precisa ser capaz de receber outras entradas. A lógica do aplicativo para iniciar uma mensagem proativa está fora do escopo do SDK. Para este exemplo, um ponto de extremidade de notificação, além de um ponto de extremidade de mensagens padrão, é usado para disparar o turno proativo.

Em resposta a uma solicitação GET nesse ponto de extremidade de notificação, o aplicativo chama o método de conversação continue do adaptador, que se comporta de forma semelhante ao método de atividade do processo. O método de continuar conversa :

  • Usa uma referência de conversa apropriada para o usuário e o método de retorno de chamada a ser usado para o turno proativo.
  • Cria uma atividade de evento e contexto de turno para o turno proativo.
  • Chama o pipeline de middleware do adaptador.
  • Chama o método de retorno de chamada fornecido.
  • O contexto de turno usa a referência de conversa para enviar quaisquer mensagens ao usuário.

O exemplo tem um bot, um ponto de extremidade de mensagens e um ponto de extremidade extra que é usado para enviar mensagens proativas ao usuário, conforme mostrado na ilustração a seguir.

Diagrama de interação mostrando como o bot obtém uma referência de conversa e a usa para enviar uma mensagem proativa.

Recuperar e armazenar a referência de conversação

Quando o Bot Framework Emulator se conecta ao bot, o bot recebe duas atividades de atualização de conversa. No manipulador de atividades de atualização de conversa do bot, a referência de conversa é recuperada e armazenada em um dicionário, conforme mostrado abaixo.

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);
}

A referência de conversação inclui uma propriedade de conversação que descreve a conversação na qual a atividade existe. A conversa inclui uma propriedade de usuário que lista os usuários que participam da conversa e uma propriedade de URL de serviço que indica para onde as respostas à atividade atual podem ser enviadas. Uma referência de conversa válida é necessária para enviar mensagens proativas aos usuários. (Para o canal do Teams, a URL do serviço é mapeada para um servidor regionalizado.)

Nota

Em um cenário do mundo real, você persistiria referências de conversação em um banco de dados em vez de usar um objeto na memória.

Enviar uma mensagem proativa

O segundo controlador, o controlador de notificação , é responsável por enviar a mensagem proativa ao usuário. Ele usa as etapas a seguir para gerar uma mensagem proativa.

  1. Recupera a referência da conversa para a qual enviar a mensagem proativa.
  2. Chama o método continue conversation do adaptador, fornecendo a referência de conversação e o delegado do manipulador de turnos a ser usado. (O método continue conversation gera um contexto de turno para a conversa referenciada e, em seguida, chama o delegado do manipulador de turnos especificado.)
  3. No delegado, usa o contexto de turno para enviar a mensagem proativa. Aqui, o delegado é definido no controlador de notificação e envia a mensagem proativa para o usuário.

Nota

Embora cada canal deva usar uma URL de serviço estável, a URL pode mudar ao longo do tempo. Para obter mais informações sobre a URL de serviço, consulte as seções Estrutura de atividade básica e URL de serviço do Esquema de atividade do Bot Framework.

Se o URL do serviço for alterado, as referências de conversação anteriores deixarão de ser válidas e as chamadas para continuar a conversação gerarão um erro ou exceção. Nesse caso, seu bot precisará adquirir uma nova referência de conversa para o usuário antes de poder enviar mensagens proativas novamente.

Controllers\NotifyController .cs

Cada vez que a página de notificação do bot é solicitada, o controlador de notificação recupera as referências de conversa do dicionário. Em seguida, o controlador usa os ContinueConversationAsync métodos e BotCallback para enviar a mensagem proativa.

[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");
    }
}

Para enviar uma mensagem proativa, o adaptador requer uma ID de aplicativo para o bot. Em um ambiente de produção, você pode usar o ID do aplicativo do bot. Para testar o bot localmente com o emulador, você pode usar a string vazia ("").

Teste seu bot

  1. Se você ainda não fez isso, instale o Bot Framework Emulator.
  2. Execute a amostra localmente na sua máquina.
  3. Inicie o emulador e conecte-se ao seu bot.
  4. Carregue na api/página de notificação do seu bot. Isso gerará uma mensagem proativa no emulador.

Informações adicionais

Requisitos

Antes de enviar uma mensagem proativa, seu bot precisa de uma referência de conversa. Seu bot pode recuperar a referência de conversa de qualquer atividade que tenha recebido do usuário, mas isso normalmente exige que o usuário interaja com o bot pelo menos uma vez antes que o bot possa enviar uma mensagem proativa.

Muitos canais proíbem um bot de enviar mensagens a um usuário, a menos que o usuário tenha enviado mensagens ao bot pelo menos uma vez. Alguns canais permitem exceções. Por exemplo, o canal do Teams permite que seu bot envie uma mensagem proativa (ou 1 em 1) para indivíduos em uma conversa de grupo já estabelecida que inclui o bot.

Considerações de design

Ao implementar mensagens proativas em seu bot, não envie várias mensagens proativas em um curto período de tempo. Alguns canais impõem restrições sobre a frequência com que um bot pode enviar mensagens ao usuário e desativarão o bot se ele violar essas restrições.

Para o tipo mais simples de mensagem proativa, o bot interjeta a mensagem na conversa quando ela é acionada, sem levar em conta o estado atual ou o tópico da conversa. Nesse cenário, a mensagem proativa interrompe o fluxo normal de conversa.

Para lidar com as notificações de forma mais suave, considere outras maneiras de integrar a notificação ao fluxo de conversa, como definir um sinalizador no estado da conversa ou adicionar a notificação a uma fila.

Sobre a virada proativa

O método continue conversation usa a referência de conversação e um manipulador de retorno de chamada de turno para:

  1. Crie um turno em que o aplicativo bot possa enviar a mensagem proativa. O adaptador cria uma event atividade para esse turno, com seu nome definido como "ContinueConversation".
  2. Envie o turno através do pipeline de middleware do adaptador.
  3. Chame o manipulador de retorno de chamada de turno para executar a lógica personalizada.

No exemplo de mensagens proativas, o manipulador de retorno de chamada de turno é definido no controlador de notificação e envia a mensagem diretamente para a conversa, sem enviar a atividade proativa por meio do manipulador de turnos normal do bot. O código de exemplo também não acessa nem atualiza o estado do bot no turno proativo.

Muitos bots são stateful e usam o estado para gerenciar uma conversa em vários turnos. Quando o método continue conversation cria um contexto de turno, o turno terá o usuário correto e o estado de conversação associados a ele, e você pode integrar turnos proativos na lógica do seu bot. Se você precisa que a lógica do bot esteja ciente da mensagem proativa, você tem algumas opções para fazer isso. Pode:

  • Forneça o manipulador de turnos do bot como o manipulador de retorno de chamada de turno. O bot receberá a atividade do evento "ContinueConversation".
  • Use o manipulador de retorno de chamada de turno para adicionar informações ao contexto de turno primeiro e, em seguida, chame o manipulador de turnos do bot.

Em ambos os casos, você precisará projetar sua lógica de bot para lidar com o evento proativo.

Próximos passos