Usually, for starting a conversation with a Microsoft Teams bot, the user has to initiate the conversation either by sending a personal message to the bot, or by mentioning the bot in a Teams channel or by invoking a messaging extension.
With proactive messaging, the bot can start a conversation with a user (or in a Teams channel) without anyone having to invoke the bot first. This conversation can be started based on any custom logic fit for your application e.g. The occurrence of an external event, or a webhook getting triggered or even on a scheduled periodical basis.
More about Bot Framework proactive messages here: https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-proactive-message?view=azure-bot-service-4.0&tabs=csharp
I should mention that the bot will first need to be installed in the Team, if you want to send a proactive message to a Teams channel, or to the users who are part of that team.
How to send proactive messages?
So in this post, let's look at a few code samples which make it very easy for our Teams Bot to send proactive messages to users or channels in a Team.
These code samples are based on a standalone .NET Core console app. This is mainly to show that as long as you have the necessary information, your code doesn't need to be running under the Bot messaging endpoint. Once you have the information from the Bot messaging endpoint, the proactive messaging code can run from any platform e.g. from an Azure Function.
If you have a look at the Bot Framework code samples published by Microsoft, they all use code which is running under the messaging endpoint. This initially led me to believe that even for proactive messaging, the code should live under the same endpoint. But as we will see in this post, that is not the case.
What are the prerequisites?
As mentioned before, our bot will need to be installed in a Team first. This will allow the bot messaging endpoint to receive the required values from Teams and send it to our proactive messaging code. If the bot is not installed in the Team, you will get a "Forbidden: The bot is not part of the conversation roster" error.
Base URL (serviceUrl)
This is the Url to which our proactive messaging code should send all the requests. This Url is sent by Teams in the Bot payload in the turnContext.Activity.serviceUrl property. For all intents and purposes this url will remain constant but after having a discussion with Microsoft, they have recommended that this url might change (very rarely) and our bot should have the logic for updating the stored base url periodically from the payload sent to the bot. More about the Base Url here: https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#base-uri
Internal Team Id
This is the internal team id which is not the same as the Office 365 Group Id. The internal team id is in the following format: 19:bf2b184e7cbb4f9f9ca1b47f755cd943@thread.skype
You can get the internal team id from the Bot payload in the channelData.team.id property. You can also get this id through the Microsoft Graph API: https://docs.microsoft.com/en-us/graph/api/resources/team?view=graph-rest-1.0#properties
Channel Id
If we want our bot to post to a specific channel in a Team, then we will need the channel id as well. The format for the channel id is exactly the same as the internal team id. Also, you can get the channel id from the bot payload as well as the Microsoft Graph api: https://docs.microsoft.com/en-us/graph/api/resources/channel?view=graph-rest-1.0#properties
Internal Teams User Id
This would only be needed if you want to send a proactive personal message to a specific user. For all users in a team, Teams maintains an encoded user id so that only bots installed in a team are able to message users. To get this user id, our bot needs to call the conversations/{conversationId}/members REST API endpoint. Fortunately for us the Bot Framework wraps this call in a handy SDK method as shown in the third code sample below.
So once we have all the required values from the Bot messaging endpoint, we are able to send proactive messages. For this sample code, I am using the Microsoft.Bot.Builder v4.7.2
https://www.nuget.org/packages/Microsoft.Bot.Builder/
1) Post a proactive message in a Teams channel
(click to zoom)
2) Post a proactive message in a Teams channel and mention a user in it
(click to zoom)
3) Post a proactive personal message to a user
This code has been updated for Bot Framework v4.12.2 NuGet Gallery | Microsoft.Bot.Builder 4.12.2
Also, before running this code, make sure that the user has installed the bot app in the personal scope or is a member of a Team which has the bot installed.
(click to zoom)
Hope you found the post useful!