Skip to content

hubot-friends/hubot-ms-teams

Repository files navigation

Hubot MS Teams Adapter

This is a MS Teams Adapter for Hubot, a popular chatbot framework. With this adapter, you can connect your Hubot instance to MS Teams and interact with users through chat.

TLDR; Expert Summary

  • Create a Hubot codebase locally with npx hubot --create . -a @hubot-friends/hubot-ms-teams
  • Create a .env file at the root of the new codebase with required environment varialbes
  • Use CloudFalared to route a publicly accesseable domain to your local instance of Hubot
  • Create a new Application Registration in Azure
  • Create a new Bot Service with that new Application ID
  • Get the app id and secret from the Bot Service configuration and put them in the .env file
  • Create a manifest.json file with 2 icons, zip them up and upload a new application in MS Teams Developer Portal
  • Publish it to your organization and wait for a few hours for Azure's data to get caught up because the bot won't be immediately available in Teams

Installation

To use this adapter, you'll need to have Node.js and npm installed on your system. Then, you can install @hubot-friends/hubot-ms-teams using npm:

npm install @hubot-friends/hubot-ms-teams

Configuration

To configure hubot-ms-teams, you'll need to set a few environment variables:

  • TEAMS_BOT_CLIENT_SECRET: Your Application Password (Client Secret when you register a new application in Azure)
  • TEAMS_BOT_TENANT_ID: Your Azure Account Tenant ID
  • TEAMS_BOT_APP_ID: Application ID when you register a new Application in Azure.
  • TEAMS_BOT_APP_TYPE: SingleTenant || MultiTenant

You can set these environment variables in a .env file in your Hubot project directory, or by exporting them in your shell.

Usage

To start your Hubot instance with the adapter, run (if hubot is in your PATH):

TEAMS_BOT_CLIENT_SECRET=<secret> TEAMS_BOT_TENANT_ID=<tenantid> TEAMS_BOT_APP_ID=<appid> TEAMS_BOT_APP_TYPE=<apptype> hubot -a @hubot-friends/hubot-ms-teams -n jbot

Replace <...> with your values.

Once your Hubot instance is running, you can interact with it through chat in a channel you've added Hubot to.

Local Development

Make a directory for your Hubot and run the following in it:

npx hubot@latest --create . -a @hubot-friends/hubot-ms-teams

Note: The period after --create means, "create all the files in this directory".

You can now start Hubot with npm start but since the MS Teams Adapter isn't configured with secrets and stuff, it won't do anything but log a message and wait. You can visit http://localhost:8080 in your browser and it'll say something like "Can't GET /". But if you see that, you're good so far.

Leave Hubot running.

BotFramework-Emulator

If you want to start developing scripts and testing out your Hubot instance, download the BotFramework-Emulator. Start it, click Open Bot. Enter http://localhost:8080/api/messages and click Connect.

Type @hubot help and you should see a message from Hubot.

At this point, you can start creating scripts in the scripts folder. Reference Hubot's tests and Documentation for help.

Going Live Set Up Instructions

Summary

  • Domain name with valid SSL Cert
  • Azure account
  • Azure Resource Group
  • Azure Application Registration
  • Azure Bot Service
  • App ID, Tenant ID, Client Secret (password)

Steps

MS Azure really wants you to use their Bot Services and Azure resources for chat bots. All their documentation assumes your own that paved path. So utilizing Hubot for a MS Teams chat bot as a little bit off-road. Here's what worked as of 2023-10-20 4:53 PM CST.

The Azure Bot Service platform communicates with your bot via HTTPS. Thus, requires a publically accessible and addressable domain name which routes to your bot instance and has a valid SSL certificate.

Addresseable Local Hubot Instance

There are many approaches to enabling Azur's Bot Service platform to send HTTPS requests to your local Hubot instance.

TLDR; I'm going to use Cloudflare Tunnel because you can register a domain name, use their tools and they provide some level of security. You can jump to those instructions if you prefer.

Approaches

  • Port forwarding: Configure your home router to forward requests from port 80 to port 80 of the IP Address of the Hubot instance. Then search the internet for "what's my ip", get your publically visible IP Address and use that when entering the Messaging Endpoint referenced below in Bot Service Configuration.
  • Dynamic DNS (DDNS): Use a DDNS service to map a domain name to your Hubot instance via DDNS client software.
  • VPN and Reverse Proxy: Set up a VPN server on your network, configure a reverse proxy server (e.g. Nginx or Apache) to forward external requests to your local Hubot instance; Use the public IP of your VPN server in the Bot Service Configuration.
  • Third-Party Tools: Run a client app that creates a tunnel to a publicly accessible server which can be configured to route traffic to your Hubot instance

Signup for Cloud Flare.

Register a domain. I think you can use ngrok or pagekite if you don't want to register a domain. But remember that Azure's Bot Service platform needs the Hubot endpoint to have a valid SSL cert.

Download the cloudflared CLI and create a locally-managed tunnel. Their documentation is going to explain better than I can.

Create a new Resource Group

Once you're setup with a running instance of Hubot and it's publicly accessible, you're ready to start setting up the Azure side of things.

You need an Azure account. Signup if you don't already have one.

You need a Resource Group if you haven't created one already. Create one to use later if you don't have one.

Create a new App Registration

Create a new App Registration.

  • Single Tenant
  • No redirect URI is necessary to get started. I think it's if you're going to build a web app that utilizes SSO
  • Click the Register button

Create a new Bot Service

You can go to the Bot Services page, but it's easier to create a Bot Service by going to the creating a resource page, type azure bot in the search field on the page and hit enter. Then click/select the Azure Bot one.

On the next page, click the Create button.

Enter a Bot handle. It's like an ID, so no need to use the Hubot instance name that you intend to use for the Hubot name. Just pick some kind of identifier.

You'll need to have a Subscription. It should be automatically selected to the one you're assigned to. If you don't have a Subscription to pick, that's a whole 'nother story. Create a Github issue and we'll work our way through it.

Then pick a Resource Group.

The Pricing tier should be Standard. That's fine for now. Unless you have a different plan to pick from.

The Type of App can be Single Tenant. I think Multi Tenant is for the scenario where you're building a bot for people outside of your Azure Organization to use.

Select Use existing app registration in the Creation Type area. Open another tab to the Azure Portal. Go to "App Registrations" and click on the "All applications" tab. Then click on the application you just registered. Copy the Application (client) ID by mousing over the ID and click the Copy icon that shows up on the right.

Now go back to the browser tab where you're creating the new Bot Service and paste that Application (client) Id into the App ID field.

Go back to the App Registration browser tab that you opened earlier and copy the Directory (tenant) ID value.

Paste that value into the App tenant ID field in the page where you're creating the new Bot Service.

Click the Next button. If you want to add tags, feel free to do so on this next page.

Click the Next button. Review the info and then click the Create button.

The page will ask you if you want to "leave". Just click Ok.

Bot Service Configuration

Enter https://<your bot's domain name>/api/messages in the Messaging endpoint field. Remember making your Hubot instance accessible and addressable from above? It was for this moment when you have to fill in the Messaging endpoint.

Click Enable Streaming Endpoing. I'm not sure what this does, but it sounds like I want it.

Click Apply at the bottom.

Secret/Password - Documentation uses these interchangeably

Click on the Manage Password link next to Microsoft App ID.

Create a new Client Secret by clicking New client secret. Note that the secret will only be shown once. So copy it and paste it into your .env file if you have one. You will not be able to come back to this page to get it again. Make sure to copy the Value and not the Secret ID.

Add Application in MS Teams

The final step is to add the app to MS Teams. This requires creating a manifest.json file and 2 icons for Teams to use for your new application/bot. Edit the manifest.json file in this repo, replace the place holders with your values and then create a zip file of the manifest.json, icon-32.png and icon-192.png files. Ues this zip file when importing the app in MS Teams Developer Portal.

Go to MS Teams. Click on the elipses on the left hand side menu, towards the bottom.

Search for Developer Portal and click on that.

Click on the Apps tab in Developer Portal. Click Import app.

Hubot Setup

I run a local Hubot instance in my terminal. So I have a .env file with all the required environment variables to configure Hubot to connect with the MS Teams adapter. It looks like the following:

TEAMS_BOT_APP_ID=<Application ID from the registered application in Azure>
TEAMS_BOT_CLIENT_SECRET=<secret/password you created in Azure Bot Service Configuration>
TEAMS_BOT_TENANT_ID=<tenant id from Azure Bot Service Configuration>
TEAMS_BOT_APP_TYPE=SingleTenant
NODE_ENV=development
HUBOT_LOG_LEVEL=debug

If you're using npm run start:local to start your instance, make sure you're running Node.js version > 20.6 and that the "start:local" property in your package.json file scripts section looks like node --env-file=.env ./node_modules/hubot/bin/hubot.js --adapter @hubot-friends/hubot-ms-teams so the .env file is loaded into the session environment. I like to include --watch as a node option during development to restart every time I make code changes.

My package.json scripts section looks like:

{
    ...
    "scripts": {
        "start": "hubot -a @hubot-friends/hubot-ms-teams -n jbot",
        "start:local": "node --watch --env-file=.env ./node_modules/hubot/bin/hubot.js --adapter @hubot-friends/hubot-ms-teams",
        "test": "node --test"
    }
    ...
}

Contributing

If you find a bug or have a feature request, please open an issue on the GitHub repository. Pull requests are also welcome!

License

hubot-ms-teams is released under the MIT License.