Imagine you want to create a chat bot for Microsoft Teams in order to automate tasks, enhance the discussion or just feeling lonely and want someone to talk to. There’s many ways of doing this; you can start from scratch building a bot, using the Microsoft Bot framework and/or using the Microsoft Teams Yeoman generator, you can use the Azure Bot Service, you can use the FAQ bots to essentially create a no code solution.
But, what if you need some logic to happen with your bot, what if you’re not that adverse in coding or have all the skills to build something using Microsoft Cognitive Services, such as language understanding and what not. What if you could use Microsoft Flow to automate tasks, initiated from a conversation in Microsoft Teams?
Then this is your lucky day, you can do this almost without any code (more on why a little bit later) and be up and running within minutes – and also without involvement of any admins that needs to approve of your solution!
The Flow!
First of all we need a Microsoft Flow to do the stuff we want to do. In this sample I’ll create a bot that I can use in a Teams discussion to create a task in my Microsoft To-Do task lists. The Flow is very simple and consists of one HTTP trigger (When a HTTP Request is recieved) and then a task that add a task to To-Do.
You should copy and store the URL, generated in the HTTP trigger upon save, as we will need that for our bot in just a minute.
For now the Subject is static, but for the Body Content I use the text property of the incoming JSON – that will be sent from the Microsoft Teams client. I use the Dynamic Expression to get text from the Teams message:
triggerBody()['text']
NOTE: If you want more help with what properties you can use, such as creating a link to the original message, you can use the HTTP trigger and import a sample paylod found in the Microsoft Teams documentation. However currently that page is not up to date with the latest schema, so the best way is to make sure this sample works, and then just take a look at the Flow history and copy-paste the JSON from a successful run.
Creating the Microsoft Teams bot
To create the bot in Microsoft Teams we take advantage of the feature called Outgoing webhook. This is a somple way that allows you to send an outgoing message when at-mentioning the bot in a Microsoft Teams team (there’s no personal equivalent at the moment). You can add a new outgoing webhook by going in to the Team settings and then click on the Apps tab. In the lower right corner you will find the link called “Create an outgoing webhook”. Click on that one to create it.
In the dialog that appears you need to fill in the name and description of your outgoing webhook (bot) and optionally upload an icon. What you also need to do is to add the Callback URL. Let’s add our URL generated for the MIcrosoft Flow and give it a shot.
When you click on create, you will get another popup with some vital information. It contains a security token, used for validating the message. This is the only time you will see it and if you forget it you have to create a new outgoing webhook. So copy-paste this into a notebook or remember it, you will need it shortly.
Let’s try this
So, now we should be able to chat to our outgoing webhook/bot by at-mentioning it in a channel in the Team where we added it.
Hmm, that was not what we expected, and this is where a lot of people have stopped trying this approach. It’s not that unexepcted though. Remember I just said the outgoing webhook has a security token, that we should validate, and also the Microsoft Flow does not send any message (JSON) back.
Azure Functions to the rescue
In order to get this to work, we need to smack some code up in sort of a proxy, that will sit between the outgoing webhook and the Microsoft Flow. The easiest and probably cheapest way is to use Azure Functions. So let’s do that.
Let’s create a new Azure Function, using the JavaScript runtime stack (if you prefer .net, it’s not my problem and you have to spend the time on your own writing the code). When creating the Azure function I choose to use HTTP Trigger (just as we did for the Microsoft Flow).
In this Azure Function we can now write some code that
- Accepts the webhook coming from Microsoft Teams
- Validates the Security Token (HMAC)
- Invokes the Microsoft Flow
- Sends a response back to the user
All the code you need can be found in this Gist: https://gist.github.com/wictorwilen/8ac6f9c167d70e4774e20f3c39a47a55. You need to do two modifications.
- On line 4 you need to add your Security/HMAC token generated when you created the outgoing webhook
- On line 5 you need to add the webhook URL for your Microsoft Flow
Since this example uses the request npm module, which is not by default installed in an Azure Function you need to go in to the Console located at the bottom of the Azure Function code editor and run
npm install request --save
Note: for production and real scenarios you might not want to build your Azure function directly in the Web UI and you should have a package.json file so any npm modules are properly restored.
Then, just save the Azure function and go back to Microsoft Teams and the same location where you created your outgoing webhook. Click on the outgoing webhook you created to edit it and then change the URL to the Azure Function URL (found next to the Save and Run buttons in the Azure Function code editor - Get function URL).
Let’s try it again
Head on back over to Microsoft Teams and into a channel, now try to at-mention the bot again!
Look at that! It’s working. I can even go over to To-Do and see that I have a new task!
Next steps…
This was the basics on how to get things working. You can of course make the bot far more advanced by injecting more logic to the Microsoft Flow (obviously) but also into the Azure Function. For instance you might want to invoke different flows, depending on the message. You have full access to the JSON in the Azure Function to do this.
One caveat is that right now you only have access to the message where the bot was at-mentioned. Hopefully Microsoft Flow gets some more Microsoft Teams features so we can extract the full conversation. Meanwhile you can always use the Microsoft Graph, but that involves a few extra steps for app permissions etc.
Summary
This approach has already today saved me and my team from having to manually do some steps in our daily routing, by simply at-mentioning a bot in our conversation. What cool stuff are you building with this?