You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typically, each message that a bot sends to the user directly relates to the user's prior input.
19
-
In some cases, a bot may need to send the user a message that is not directly related to the current topic of conversation or to the last message the user sent. These types of messages are called _proactive messages_.
18
+
Typically, a bot sends a message to a user directly in response to receiving a message from the user.
19
+
Occasionally, a bot might need to send a _proactive message_, a message in response to stimulus not originating from the user.
20
20
21
21
Proactive messages can be useful in a variety of scenarios. For example, if the user has previously asked the bot to monitor the price of a product, the bot can alert the user if the price of the product has dropped by 20%. Or, if a bot requires some time to compile a response to the user's question, it may inform the user of the delay and allow the conversation to continue in the meantime. When the bot finishes compiling the response to the question, it will share that information with the user.
22
22
@@ -38,7 +38,27 @@ More information about proactive messages in Teams can be found in these resourc
38
38
39
39
## About the proactive sample
40
40
41
-
The sample has a bot and an additional controller that is used to send proactive messages to the bot, as shown in the following illustration.
41
+
In general, a bot as an application has a few layers:
42
+
43
+
- The web application that can accept HTTP requests and specifically supports a messaging endpoint.
44
+
- An adapter that handles connectivity with the channels.
45
+
- A handler for the turn, typically encapsulated in a _bot_ class that handles the conversational reasoning for the bot app.
46
+
47
+
In response to an incoming message from the user, the app calls the adapter's _process activity_ method, which creates a turn and turn context, calls its middleware pipeline, and then calls the bot's turn handler.
48
+
49
+
To initiate a proactive message, the bot application needs to be able to receive additional input.
50
+
The application logic for initiating a proactive message is outside the scope of the SDK.
51
+
For this sample, a _notify_ endpoint, in addition to a standard _messages_ endpoint, is used to trigger the proactive turn.
52
+
53
+
In response to a GET request on this notify endpoint, the app calls the adapter's _continue conversation_ method, which behaves similarly to the the _process activity_ method. The _continue conversation_ method:
54
+
55
+
- Takes an appropriate conversation reference for the user and the callback method to use for the proactive turn.
56
+
- Creates an event activity and turn context for the proactive turn.
57
+
- Calls the adapter's middleware pipeline.
58
+
- Calls the provided callback method.
59
+
- The turn context uses the conversation reference to send any messages to the user.
60
+
61
+
The sample has a bot, a messages endpoint, and an additional notify endpoint that is used to send proactive messages to the user, as shown in the following illustration.
42
62
43
63

44
64
@@ -76,11 +96,11 @@ The conversation reference includes a _conversation_ property that describes the
76
96
77
97
## Send proactive message
78
98
79
-
The second controller, the _notify_ controller, is responsible for sending the proactive message to the bot. It uses the following steps to generate a proactive message.
99
+
The second controller, the _notify_ controller, is responsible for sending the proactive message to the user. It uses the following steps to generate a proactive message.
80
100
81
101
1. Retrieves the reference for the conversation to which to send the proactive message.
82
102
1. Calls the adapter's _continue conversation_ method, providing the conversation reference and the turn handler delegate to use. (The continue conversation method generates a turn context for the referenced conversation and then calls the specified turn handler delegate.)
83
-
1. In the delegate, uses the turn context to send the proactive message.
103
+
1. In the delegate, uses the turn context to send the proactive message. Here, the delegate is defined on the notify controller, and it sends the proactive message to the user.
84
104
85
105
> [!NOTE]
86
106
> While each channel should use a stable service URL, the URL can change over time. For more information about the service URL, see the [Basic activity structure](https://github.com/microsoft/botframework-sdk/blob/master/specs/botframework-activity/botframework-activity.md#basic-activity-structure) and [Service URL](https://github.com/microsoft/botframework-sdk/blob/master/specs/botframework-activity/botframework-activity.md#service-url) sections of the Bot Framework Activity Schema.
@@ -136,43 +156,25 @@ An ad hoc proactive message is the simplest type of proactive message. The bot s
136
156
137
157
To handle notifications more smoothly, consider other ways to integrate the notification into the conversation flow, such as setting a flag in the conversation state or adding the notification to a queue.
138
158
139
-
### Avoiding 401 "Unauthorized" Errors
140
-
141
-
By default, the Bot Builder SDK adds a `serviceUrl` to the list of trusted host names if the incoming request is authenticated by BotAuthentication. They are maintained in an in-memory cache. If your bot is restarted, a user awaiting a proactive message cannot receive it unless they have messaged the bot again after it restarted.
159
+
### About the proactive turn
142
160
143
-
To avoid this, you must manually add the `serviceUrl` to the list of trusted host names.
161
+
The _continue conversation_ method uses the conversation reference and a turn callback handler to:
144
162
145
-
# [C#](#tab/csharp)
163
+
1. Create a turn in which the bot application can send the proactive message. The adapter creates an `event` activity for this turn, with its name set to "ContinueConversation".
164
+
1. Send the turn through the adapter's middleware pipeline.
165
+
1. Call the turn callback handler to perform custom logic.
In the **proactive messages** sample, the turn callback handler is defined in the notify controller and sends the message directly to the conversation, without sending the proactive activity through the bot's normal turn handler.
168
+
The sample code also does not access or update the bot's state on the proactive turn.
150
169
151
-
For proactive messaging, `serviceUrl` is the URL of the channel that the recipient of the proactive message is using and can be found in `Activity.ServiceUrl`.
170
+
Many bots are stateful and use state to manage a conversation over multiple turns.
171
+
When the continue conversation method creates a turn context, the turn will have the correct user and conversation state associated with it, and you can integrate proactive turns into your bot's logic.
172
+
If you need the bot logic to be aware of the proactive message, you have a few options for doing so. You can:
152
173
153
-
You'll want to add the above code just prior to the the code that sends the proactive message. In the [Proactive Messages Sample](https://aka.ms/proactive-sample-cs), you would put it in `NotifyController.cs` just before `await turnContext.SendActivityAsync("proactive hello");`.
154
-
155
-
# [JavaScript](#tab/javascript)
174
+
- Provide the bot's turn handler as the turn callback handler. The bot will then receive the "ContinueConversation" event activity.
175
+
- Use the turn callback handler to add information to the turn context first, and then call the bot's turn handler.
For proactive messaging, `serviceUrl` is the URL of the channel that the recipient of the proactive message is using and can be found in `activity.serviceUrl`.
162
-
163
-
You'll want to add the above code just prior to the the code that sends the proactive message. In the [Proactive Messages Sample](https://aka.ms/proactive-sample-js), you would put it in `index.js` just before `await turnContext.sendActivity('proactive hello');`.
For proactive messaging, `serviceUrl` is the URL of the channel that the recipient of the proactive message is using and can be found in `activity.serviceUrl`.
172
-
173
-
You'll want to add the above code just prior to the the code that sends the proactive message. In the [Proactive Messages Sample](https://aka.ms/bot-proactive-python-sample-code), you add it in `app.py` prior sending the *proactive hello* message.
174
-
175
-
---
177
+
In both of these cases, you will need to design your bot logic to handle the proactive event.
0 commit comments