Send private messages programmatically in MSTeams
This is a NodeJs service exposing:
- A messaging endpoint which routes to a MSTeams bot application
- Additional HTTP endpoints for triggering private notifications to users on demand.
Table of contents
- Our Use Case π―
- API π¨
- Configuration π
- Azure βοΈ
- Local Development π₯
- Upload to Teams π
- FAQ πββοΈ
- Additional Doc π
We used to have Slack as communication platform. When an event occur in our infra, we used to send private messages (as well as public ones) to interested people. When migrating to MSTeams, we loosed this.
We've implemented a MSTeams Bot that allows us to interact with users through text and cards while exposing a regular HTTP API.
msteams-private-messages
is a web service.- This web service is registered on Azure as a Bot Channel
- As conversational bot, when a user starts a conversation, the service saves a reference to that conversation as well as the name of the user.
- The bot offers the user a menu of topics to subscribe, if the user subscribes to any of those, the service saves the relation
user-topics
. - The web service exposes a regular API able to:
notify
a message to an specific user (we need that user to have started a conversation with the bot in first place)broadcast
a message related to a topic to every user subscribed to the topic
.env
file is read on startup (no hot loading).
A .env.template
file is provided, you may use it as reference:
cp .env.template .env
env var | default value | usage |
---|---|---|
LOCAL |
false |
flag: connect to a running BotApp on Azure or local development |
MICROSOFT_APP_ID |
undefined |
ClientId registered at Azure's ADD (app id) - apply if !LOCAL |
MICROSOFT_APP_PASSWORD |
undefined |
SecretId registered at Azure's ADD (app key) - apply if !LOCAL |
PORT |
3978 | listening port on startup |
LOG_LEVEL |
info | logging level (debug, info, warn...) |
tip: a minimal .env
file for production may looks like:
MICROSOFT_APP_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MICROSOFT_APP_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The cards that the bot sends as well as the available options to subscribe are configurable via .yaml
file. config.yaml
file is read on startup (no hot loading implemented).
An example file is provided at the root folder, just change the title
& value
strings to fit your needs.
Note: If no config.yaml
is provided, the service will use config.example.yaml
by default.
cp config.example.yaml config.yaml
Welcome message: welcomeCard
cards:
[...]
welcomeCard:
title: Welcome to the Private Notifications Center
text: ""
Unknown command: unknownCard
cards:
[...]
unknownCard:
title: ""
text: Unknown command...
Topics: menuCard
As we mentioned, the bot offers the user a menu of topics to subscribe. On broadcast requests (/api/v1/broadcast
), this service will check who is subscribed to the desired topic.
cards:
[...]
menuCard:
title: Available Options
checkButton:
title: Check my subscribed notifications π§Ύ
value: check
resetButton:
title: Reset all my subscribed notifications β
value: reset
subscriptionButtons:
- title: Subscribe to banana notifications π
value: banana
- title: Subscribe to apple notifications π
value: apple
- title: Subscribe to orange notifications π
value: orange
This .yaml
file would render as:
This section aims to be a quick summary of which are the minimal needs to have a bot application (Azure App registration) connected to an external web service.
msteams-private-messages
is, essentially, a server that can receive and send JSON. We'll need to register our service as a "Bot Channel" on Azure.
Note: It's possible to host also the service on Azure. There is official documentation regarding 'how to deploy'. In our case we're hosting the web service in our own platform, keeping the interaction with Azure to the minimum.
We'll need a few resources from the Azure portal
- Resource group.
- Whatever you want to name it.
- Bot Channel Registration.
- Go to the settings of your Bot Channel Registration
- Go back to the settings of your Bot Channel Registration
We've ended up with 2 values: Microsoft App Id & Microsoft App Secret.
Copy those values in your .env
file for enabling remote connection.
LOCAL=false
MICROSOFT_APP_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MICROSOFT_APP_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TODO
Q: Do I really need a whole service & db for just private notifications on MSTeams?
A: Yes. You can't send messages to the users but rather continue a prev. conversation they started. You need to store the reference of every conversation.
Q: I've tried to mention the user on Bot Framework Emulator and it doesn't work
A: We know. Appending a mention does work on Microsoft Teams but won't render on the Emulator. Probably this is a issue related to the Emulator itself.
Q: Getting 401 error all the time. Already checked my Azure App ID + pass
Error: BotFrameworkAdapter.processActivity(): 401 ERROR
Error: Unauthorized. Invalid AppId passed on token: <YOUR APP ID>
A: Assuming you've provided correct credentials (ID + pass), check that you aren't launching the server using LOCAL
mode (you wouldn't believe how many times this happened to me)
LOCAL=false
Q: Why the pixeled icon?
A: One of the devs thought it was cool.
- SO: Sending proactive messages to a channel in Teams
- SO: Send Proactive Adaptive Card Message to MS Teams Channel
- SO: Bot Channels Registration - Azure Bot Framework
- Docs: Bot basics
- Docs: Send proactive notifications to users
- Docs: Bot channels registration
- Code: microsoft/BotBuilder-Samples
- Post: Sequelize relationships - Ultimate guide