Inviare notifiche proattive agli utenti

SI APPLICA A: SDK v4

In genere, un bot invia un messaggio direttamente a un utente in risposta alla ricezione di un messaggio dall'utente. In alcuni casi, un bot potrebbe dover inviare un messaggio proattivo, un messaggio in risposta a stimoli che non provengono dall'utente.

I messaggi proattivi possono essere utili in vari scenari. Ad esempio, se l'utente ha richiesto precedentemente al bot di monitorare il prezzo di un prodotto, il bot può avvisare l'utente se il prezzo di quel prodotto è stato ridotto del 20%. In alternativa, se un bot ha bisogno di tempo per compilare la risposta a una domanda dell'utente, può informare l'utente del ritardo e consentire che la conversazione continui nel frattempo. Quando il bot termina di compilare la risposta alla domanda, condividerà tali informazioni con l'utente.

Questo articolo illustra le informazioni sui messaggi proattivi per i bot in generale. Per informazioni sui messaggi proattivi in Microsoft Teams, vedere

Nota

Gli SDK JavaScript, C# e Python di Bot Framework continueranno a essere supportati, ma Java SDK verrà ritirato con il supporto finale a lungo termine che termina a novembre 2023.

I bot esistenti creati con Java SDK continueranno a funzionare.

Per la creazione di nuovi bot, è consigliabile usare Microsoft Copilot Studio e leggere le informazioni sulla scelta della soluzione copilota appropriata.

Per altre informazioni, vedere Il futuro della compilazione di bot.

Prerequisiti

Informazioni sull'esempio proattivo

In generale, un bot come applicazione ha alcuni livelli:

  • L'applicazione Web che può accettare richieste HTTP e in particolare supporta un endpoint di messaggistica.
  • Adattatore che gestisce la connettività con i canali.
  • Gestore per il turno, in genere incapsulato in una classe bot che gestisce il ragionamento conversazionale per l'app bot.

In risposta a un messaggio in arrivo dall'utente, l'app chiama il metodo di attività del processo dell'adapter, che crea un contesto di turno e turno, chiama la pipeline middleware e quindi chiama il gestore dei turni del bot.

Per avviare un messaggio proattivo, l'applicazione bot deve essere in grado di ricevere altri input. La logica dell'applicazione per l'avvio di un messaggio proattivo non rientra nell'ambito dell'SDK. Per questo esempio, un endpoint di notifica, oltre a un endpoint di messaggi standard, viene usato per attivare il turno proattivo.

In risposta a una richiesta GET su questo endpoint di notifica, l'app chiama il metodo di conversazione continua dell'adapter, che si comporta in modo analogo al metodo di attività del processo. Metodo di conversazione continua:

  • Accetta un riferimento di conversazione appropriato per l'utente e il metodo di callback da usare per il turno proattivo.
  • Crea un'attività evento e un contesto di turno per il turno proattivo.
  • Chiama la pipeline middleware dell'adapter.
  • Chiama il metodo di callback fornito.
  • Il contesto del turno usa il riferimento alla conversazione per inviare eventuali messaggi all'utente.

L'esempio include un bot, un endpoint di messaggi e un endpoint aggiuntivo usato per inviare messaggi proattivi all'utente, come illustrato nella figura seguente.

Diagramma di interazione che illustra come il bot ottiene un riferimento alla conversazione e lo usa per inviare un messaggio proattivo.

Recuperare e archiviare il riferimento alla conversazione

Quando Bot Framework Emulator si connette al bot, il bot riceve due attività di aggiornamento della conversazione. Nel gestore di attività di aggiornamento della conversazione del bot, il riferimento alla conversazione viene recuperato e archiviato in un dizionario come illustrato di seguito.

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

Il riferimento alla conversazione include una proprietà di conversazione che descrive la conversazione in cui è presente l'attività. La conversazione include una proprietà utente che elenca gli utenti che partecipano alla conversazione e una proprietà URL del servizio che indica dove possono essere inviate risposte all'attività corrente. Per inviare messaggi proattivi agli utenti, è necessario un riferimento della conversazione valido. Per il canale di Teams, l'URL del servizio viene mappato a un server a livello di area.

Nota

in uno scenario reale i riferimenti delle conversazioni vengono salvati in modo permanente in un database invece di usare un oggetto in memoria.

Inviare un messaggio proattivo

Il secondo controller, il controller di notifica , è responsabile dell'invio del messaggio proattivo all'utente. Usa i passaggi seguenti per generare un messaggio proattivo.

  1. Recupera il riferimento per la conversazione a cui inviare il messaggio proattivo.
  2. Chiama il metodo di conversazione continua dell'adapter, fornendo il riferimento alla conversazione e il delegato del gestore dei turni da usare. Il metodo di conversazione continua genera un contesto di turno per la conversazione a cui si fa riferimento e quindi chiama il delegato del gestore dei turni specificato.
  3. Nel delegato usa il contesto dei turni per inviare il messaggio proattivo. In questo caso, il delegato viene definito nel controller di notifica e invia il messaggio proattivo all'utente.

Nota

Mentre ogni canale deve usare un URL del servizio stabile, l'URL può cambiare nel tempo. Per altre informazioni sull'URL del servizio, vedere le sezioni Struttura attività di base e URL del servizio dello schema attività di Bot Framework.

Se l'URL del servizio cambia, i riferimenti di conversazione precedenti non saranno più validi e le chiamate per continuare la conversazione genereranno un errore o un'eccezione. In questo caso, il bot dovrà acquisire un nuovo riferimento di conversazione per l'utente prima di poter inviare nuovamente messaggi proattivi.

Controllers\NotifyController .cs

Ogni volta che viene richiesta la pagina di notifica del bot, il controller di notifica recupera i riferimenti delle conversazioni dal dizionario. Il controller usa quindi i metodi ContinueConversationAsync e BotCallback per inviare il messaggio proattivo.

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

Per inviare un messaggio proattivo, l'adattatore richiede un ID app per il bot. In un ambiente di produzione è possibile usare l'ID app del bot. Per testare il bot in locale con l'emulatore, è possibile usare la stringa vuota ("").

Esegui il test del tuo bot

  1. Se non è già stato fatto, installare Bot Framework Emulator.
  2. Eseguire l'esempio in locale nel computer.
  3. Avviare l'emulatore e connettersi al bot.
  4. Eseguire il caricamento nella pagina api/notifica del bot. Verrà generato un messaggio proattivo nell'emulatore.

Informazioni aggiuntive

Requisiti

Prima di poter inviare un messaggio proattivo, il bot necessita di un riferimento alla conversazione. Il bot può recuperare il riferimento alla conversazione da qualsiasi attività ricevuta dall'utente, ma in genere richiede all'utente di interagire con il bot almeno una volta prima che il bot possa inviare un messaggio proattivo.

Molti canali impediscono a un bot di messaggistica di un utente, a meno che l'utente non abbia inviato un messaggio almeno una volta al bot. Alcuni canali consentono eccezioni. Ad esempio, il canale di Teams consente al bot di inviare un messaggio proattivo (o 1 su 1) a singoli utenti in una conversazione di gruppo già stabilita che include il bot.

Considerazioni relative alla progettazione

Quando si implementano messaggi proattivi nel bot, non inviare più messaggi proattivi in un breve lasso di tempo. Alcuni canali applicano restrizioni sulla frequenza con cui un bot può inviare messaggi all'utente e disabiliteranno il bot se viola le restrizioni.

Per il tipo più semplice di messaggio proattivo, il bot inserisce il messaggio nella conversazione quando viene attivato, senza considerare lo stato corrente o l'argomento della conversazione. In questo scenario, il messaggio proattivo interrompe il normale flusso di conversazione.

Per gestire più agevolmente le notifiche, considerare altri modi per integrare la notifica nel flusso della conversazione, ad esempio impostando un flag nello stato della conversazione o aggiungendo la notifica a una coda.

Informazioni sul turno proattivo

Il metodo di conversazione continua usa il riferimento alla conversazione e un gestore di callback di turno per:

  1. Creare un turno in cui l'applicazione bot può inviare il messaggio proattivo. L'adapter crea un'attività event per questo turno, con il nome impostato su "ContinueConversation".
  2. Inviare il turno attraverso la pipeline middleware dell'adapter.
  3. Chiamare il gestore di callback di turno per eseguire la logica personalizzata.

Nell'esempio di messaggi proattivi il gestore di callback di turno viene definito nel controller di notifica e invia il messaggio direttamente alla conversazione, senza inviare l'attività proattiva tramite il gestore dei turni normale del bot. Il codice di esempio non accede né aggiorna lo stato del bot al turno proattivo.

Molti bot sono con stato e usano lo stato per gestire una conversazione su più turni. Quando il metodo di conversazione continua crea un contesto di turno, il turno avrà lo stato di utente e conversazione corretto associato a esso ed è possibile integrare i turni proattivi nella logica del bot. Se è necessario che la logica del bot sia consapevole del messaggio proattivo, sono disponibili alcune opzioni per farlo. È possibile:

  • Specificare il gestore dei turni del bot come gestore di callback di turno. Il bot riceverà quindi l'attività dell'evento "ContinueConversation".
  • Usare il gestore di callback di turno per aggiungere prima informazioni al contesto di turno e quindi chiamare il gestore dei turni del bot.

In entrambi questi casi, è necessario progettare la logica del bot per gestire l'evento proattivo.

Passaggi successivi