52

I want to run a script of Python and in the end send the results in a text format to a couple of employees through MS Teams

Is there any already build library that would allow me to send a message in Microsoft Teams through Python code?

Alan Kavanagh
  • 9,425
  • 7
  • 41
  • 65
Ricardo Vilaça
  • 846
  • 1
  • 7
  • 18

4 Answers4

119

1. Create a webhook in MS Teams

Add an incoming webhook to a Teams channel:

  1. Navigate to the channel where you want to add the webhook and select (•••) Connectors from the top navigation bar.
  2. Search for Incoming Webhook, and add it.
  3. Click Configure and provide a name for your webhook.
  4. Copy the URL which appears and click "OK".

2. Install pymsteams

pip install pymsteams

3. Create your python script

import pymsteams
myTeamsMessage = pymsteams.connectorcard("<Microsoft Webhook URL>")
myTeamsMessage.text("this is my text")
myTeamsMessage.send()

More information available here:

Add a webook to MS Teams

Python pymsteams library

Zev Averbach
  • 1,044
  • 1
  • 11
  • 25
Alan Kavanagh
  • 9,425
  • 7
  • 41
  • 65
  • Thank you. I realized i ignored the whole webhook deal because i can't find the webhook connector in my list of connectors to add on Teams.. Guess i'll have to ask the admin. Thank you :) – Ricardo Vilaça Dec 17 '19 at 10:49
  • 1
    One important thing while creating new webhook is: you need to select your team's `Settings => Member permissions => Allow members to create, update, and remove connectors`. If it is selected any team member can add, modify, or delete a connector. – Ankush Feb 11 '20 at 06:54
  • I've got permissions to create and edit a channel, I've still been unable to find the webhook connector in the _More options_ menu, and per @Ankush, I've asked and the admin has confirmed that I should be able to create/update/remove connectors. I've tried creating a new channel and still don't get that option. I suspect I'm missing something obvious, or has Microsoft changed the API and hidden that connector? – GerryC May 03 '20 at 14:33
  • @GerryC, I've just tried it out with Windows Teams v1.3 (64bit). Works fine. More options(...) -> Connectors -> search for "Webhook". – mailivres May 05 '20 at 12:27
  • @mailivres, I don't even see a 'Connectors' entry on that drop-down. Difference between Windows and Linux? I can try on the lone Windows 10 box I've got. Thanks for the response! – GerryC May 05 '20 at 15:51
  • @GerryC try it with the web version of teams. it is platform independent. – Ankush May 12 '20 at 06:43
  • Is it possible send a formatted text like change the font or size of the font in the webhook? – Kaushik May 19 '20 at 12:07
  • @Ankush, no luck with the web version either, but on more investigation there are several steps one has to take to enable webhooks, and they're not available to be seen by guests. – GerryC May 27 '20 at 21:10
  • @GerryC i tried and it worked for me. Yes one has to go through several steps to get this one. – Ankush Jun 02 '20 at 06:46
  • 1
    @Ankush -- While I'd prefer to be able to use RESTful techniques, I'm dropping back to sending the file contents (they're text files with weather information) to the channel via email. Until I can get the Webhook located/identified, and work with that, the email will have to do. Thanks for the ideas and help! – GerryC Jun 17 '20 at 21:51
  • Is it possible to send a message to the chat in this way? As this solution is only for teams channel. For groups and chats we don't have connectors. – Aakash aggarwal Oct 11 '22 at 05:14
18

Send Msteams notification without an additional package.

A simple way to send messages to teams without using any external modules. This is basically under the hood of pymsteams module. It is more useful when you are using AWS Lambda as you don't have to add layers in Lambda or supply pymsteams module as a deployment package.

import urllib3
import json


class TeamsWebhookException(Exception):
    """custom exception for failed webhook call"""
    pass


class ConnectorCard:
    def __init__(self, hookurl, http_timeout=60):
        self.http = urllib3.PoolManager()
        self.payload = {}
        self.hookurl = hookurl
        self.http_timeout = http_timeout

    def text(self, mtext):
        self.payload["text"] = mtext
        return self

    def send(self):
        headers = {"Content-Type":"application/json"}
        r = self.http.request(
                'POST',
                f'{self.hookurl}',
                body=json.dumps(self.payload).encode('utf-8'),
                headers=headers, timeout=self.http_timeout)
        if r.status == 200: 
            return True
        else:
            raise TeamsWebhookException(r.reason)


if __name__ == "__main__":
    myTeamsMessage = ConnectorCard(MSTEAMS_WEBHOOK)
    myTeamsMessage.text("this is my test message to the teams channel.")
    myTeamsMessage.send()

reference: pymsteams

Zev Averbach
  • 1,044
  • 1
  • 11
  • 25
nirojshrestha019
  • 2,068
  • 1
  • 10
  • 14
13

Here's a simple, third-party package-free solution inspired by @nirojshrestha019's solution, with fewer steps and updated instructions for Microsoft's ever-changing UIs:

1. Create a webhook in MS Teams

Add an incoming webhook to a Teams channel:

  1. Navigate to the channel where you want to add the webhook and select (•••) Connectors from the top navigation bar.
  2. Search for Incoming Webhook, and add it.
  3. Click Configure and provide a name for your webhook.
  4. Copy the URL which appears and click "OK".

2. Make a script!

import json
import sys
from urllib import request as req


class TeamsWebhookException(Exception):
    pass


WEBHOOK_URL = "https://myco.webhook.office.com/webhookb2/abc-def-ghi/IncomingWebhook/blahblah42/jkl-mno"


def post_message(message: str) -> None:
    request = req.Request(url=WEBHOOK_URL, method="POST")
    request.add_header(key="Content-Type", val="application/json")
    data = json.dumps({"text": message}).encode()
    with req.urlopen(url=request, data=data) as response:
        if response.status != 200:
            raise TeamsWebhookException(response.reason)

if __name__ == "__main__":
    post_message("hey this is my message")
Zev Averbach
  • 1,044
  • 1
  • 11
  • 25
5

Adding a code snippet based on Python's requests library for completeness.

Compared to the other answers this is useful as all major Linux distros provide a python3-requests package but not a python3-msteams package.

#!/usr/bin/env python3

import requests

WEBHOOK_URL = "https://..."

def postTeamsMessage(text):
        jsonData = {
          "text": text
        }
        requests.post(WEBHOOK_URL, json=jsonData)

postTeamsMessage("Hello there")
NrY
  • 141
  • 2
  • 4