Format messages and post to Microsoft Teams.

rveachkc, updated 🕥 2023-01-10 03:23:41

pymsteams

CircleCI PyPI version

Python Wrapper Library to send requests to Microsoft Teams Webhooks. Microsoft refers to these messages as Connector Cards. A message can be sent with only the main Connector Card, or additional sections can be included into the message.

This library uses Webhook Connectors for Microsoft Teams. Please visit the following Microsoft Documentation link for instructions on how to obtain the correct url for your Channel: https://dev.outlook.com/Connectors/GetStarted#creating-messages-through-office-365-connectors-in-microsoft-teams

Please refer to the Microsoft Documentation for the most up to date screenshots. https://dev.outlook.com/connectors/reference

Installation

Install with pip:

bash pip install pymsteams

Install with async capabilities (python 3.6+):

bash pip install pymsteams[async]

Python 2 Installation

At time of writing, the latest release supported by Python 2 is Version 0.1.16

Usage

Creating ConnectorCard Messages

This is the simplest implementation of pymsteams. It will send a message to the teams webhook url with plain text in the message.

```python import pymsteams

You must create the connectorcard object with the Microsoft Webhook URL

myTeamsMessage = pymsteams.connectorcard("")

Add text to the message.

myTeamsMessage.text("this is my text")

send the message.

myTeamsMessage.send() ```

Creating CreatorCard Messages to send via async loop

```python import asyncio import pymsteams

loop = asyncio.get_event_loop()

the async_connectorcard object is used instead of the normal one.

myTeamsMessage = pymsteams.async_connectorcard("")

all formatting for the message should be the same

myTeamsMessage.text("This is my message")

to send the message, pass to the event loop

loop.run_until_complete(myTeamsMessage.send()) ```

Please visit the python asyncio documentation for more info on using asyncio and the event loop: https://docs.python.org/3/library/asyncio-eventloop.html

Optional Formatting Methods for Cards

Add a title

python myTeamsMessage.title("This is my message title")

Add a link button

python myTeamsMessage.addLinkButton("This is the button Text", "https://github.com/rveachkc/pymsteams/")

Change URL

This is useful in the event you need to post the same message to multiple rooms. python myTeamsMessage.newhookurl("<My New URL>")

Set Color Theme

This sets the theme color of the card. The parameter is expected to be a hex color code without the hash or the string red. python myTeamsMessage.color("<Hex Color Code>")

Preview your object

This is a simple print command to view your connector card message object before sending. python myTeamsMessage.printme()

Adding sections to the Connector Card Message

To create a section and add various formatting elements ```python

create the section

myMessageSection = pymsteams.cardsection()

Section Title

myMessageSection.title("Section title")

Activity Elements

myMessageSection.activityTitle("my activity title") myMessageSection.activitySubtitle("my activity subtitle") myMessageSection.activityImage("http://i.imgur.com/c4jt321l.png") myMessageSection.activityText("This is my activity Text")

Facts are key value pairs displayed in a list.

myMessageSection.addFact("this", "is fine") myMessageSection.addFact("this is", "also fine")

Section Text

myMessageSection.text("This is my section text")

Section Images

myMessageSection.addImage("http://i.imgur.com/c4jt321l.png", ititle="This Is Fine")

Add your section to the connector card object before sending

myTeamsMessage.addSection(myMessageSection) You may also add multiple sections to a connector card message as well.python

Create Section 1

Section1 = pymsteams.cardsection() Section1.text("My First Section")

Create Section 2

Section2 = pymsteams.cardsection() Section2.text("My Second Section")

Add both Sections to the main card object

myTeamsMessage.addSection(Section1) myTeamsMessage.addSection(Section2)

Then send the card

myTeamsMessage.send() ```

Adding potential actions to the Connector Card Message

To create a actions on which the user can interect with in MS Teams To find out more information on what actions can be used, please visit https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using#setting-up-a-custom-incoming-webhook

```python myTeamsMessage = pymsteams.connectorcard("")

myTeamsPotentialAction1 = pymsteams.potentialaction(_name = "Add a comment") myTeamsPotentialAction1.addInput("TextInput","comment","Add a comment here",False) myTeamsPotentialAction1.addAction("HttpPost","Add Comment","https://..."")

myTeamsPotentialAction2 = pymsteams.potentialaction(_name = "Set due date") myTeamsPotentialAction2.addInput("DateInput","dueDate","Enter due date") myTeamsPotentialAction2.addAction("HttpPost","save","https://...")

myTeamsPotentialAction3 = pymsteams.potentialaction(_name = "Change Status") myTeamsPotentialAction3.choices.addChoices("In progress","0") myTeamsPotentialAction3.choices.addChoices("Active","1") myTeamsPotentialAction3.addInput("MultichoiceInput","list","Select a status",False) myTeamsPotentialAction3.addAction("HttpPost","Save","https://...")

myTeamsMessage.addPotentialAction(myTeamsPotentialAction1) myTeamsMessage.addPotentialAction(myTeamsPotentialAction2) myTeamsMessage.addPotentialAction(myTeamsPotentialAction3)

myTeamsMessage.summary("Test Message")

myTeamsMessage.send() ```

Adding HTTP Post to potential actions in the Connector Card Message

```python myTeamsMessage = pymsteams.connectorcard("")

myTeamsPotentialAction1 = pymsteams.potentialaction(_name = "Add a comment")

You can add a TextInput to your potential action like below - Please note the 2nd argment below as the id name

myTeamsPotentialAction1.addInput("TextInput","comment","Add a comment here",False)

we use the 2nd argument above as the id name to parse the values into the body post like below.

myTeamsPotentialAction1.addAction("HttpPost","Add Comment","https://...", "{{comment.value}}") myTeamsMessage.addPotentialAction(myTeamsPotentialAction1)

myTeamsMessage.summary("Test Message")

myTeamsMessage.send()

Notes:

If you post anything via teams, you will get some Javascript encoding happening via the post - For example:

Posting this: {"name":"john", "comment" : "nice"}

Output will be: b'{\u0022name\u0022:\u0022john\u0022, \u0022comment\u0022 : \u0022nice\u0022}'

i solved this issue by decoding unicode escape for a custom rest backend.

```

Please use Github issues to report any bugs or request enhancements.

Troubleshooting HTTP response

This module is really just a nice wrapper pointed at the Microsoft API. To help troubleshoot missing messages, the requests response content is saved to the connectorcard class attribute last_http_response.

To get the last http status code: ```python import pymsteams

myTeamsMessage = pymsteams.connectorcard("") myTeamsMessage.text("this is my text") myTeamsMessage.send()

last_status_code = myTeamsMessage.last_http_response.status_code ```

More info on the Response Content is available in the requests documentation, link.

Exceptions

If the call to the Microsoft Teams webhook service fails, a TeamsWebhookException will be thrown.

Testing

In order to test in your environment with pytest, set the environment variable MS_TEAMS_WEBHOOK to the Microsoft Teams Webhook url you would like to use.

Then, from the root of the repo, install the requirements and run pytest.

bash pip install -r dev-requirements.txt MS_TEAMS_WEBHOOK=MicrosoftWebhookURL export MS_TEAMS_WEBHOOK pytest --cov=./pymsteams --cov-report=term-missing --cov-branch

This will send two MS Teams messages describing how they are formatted. Manually validate that the message comes through as expected.

Certificate Validation

In some situations, a custom CA bundle must be used. This can be set on class initialization, by setting the verify parameter.

```python import pymsteams

set custom ca bundle

msg = pymsteams.connectorcard("", verify="/path/to/file")

disable CA validation

msg = pymsteams.connectorcard("", verify=False) ```

Set to either the path of a custom CA bundle or False to disable.

The requests documentation can be referenced for full details: https://2.python-requests.org/en/master/user/advanced/#ssl-cert-verification

Issues

"==" not sent properly

opened on 2023-02-23 17:00:52 by michalmalus

Describe the bug Sometimes "==" is not sent via the hook.

To Reproduce my_teams_message = pymsteams.connectorcard(...) my_teams_message.text("0==0 1==1") my_teams_message.send()

Expected behavior A message containing "0==0 1==1"

Screenshots

issue

Additional context pymsteams 0.2.2

HTML tables stopped working

opened on 2022-11-21 15:15:04 by talbaumel

Describe the bug I used to send HTML tables on my automatic msg, this feature stopped working (probably teams changed someting)

To Reproduce Just try to post this msg, the table won't appear "<h2>My table:</h2> <table border="1" class="dataframe">\n <thead>\n <tr style="text-align: right;">\n <th></th>\n <th>0</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>1</td>\n </tr>\n <tr>\n <th>1</th>\n <td>2</td>\n </tr>\n <tr>\n <th>2</th>\n <td>3</td>\n </tr>\n </tbody>\n</table> 123"

Expected behavior See the table in the card

Screenshots

Additional context

Adaptive card is not rendered on android phone

opened on 2022-10-25 08:50:17 by tinex81

Dear rveach maintainer,

i would like to submit this issue on android phone that the adaptive card is not rendered well. That is, from android when you click on the buttons (of a potential action) the context menu will appears, such as the calendar or the multi-selection of some values. What does not appear instead is the enter key of the choice you want to make. The pictures perhaps explain better. This is a comparison table, where:

  • the first column represents how potential actions, created through pymsteams, works well on windows 10 with the teams application
  • the second column represents how potential actions, created through pymsteams, doesn't work well on android with the teams application
  • the third column represents how potential actions, created with thirdy party tool, works well on android with the teams application.

For the image see the follow link: https://i.imgur.com/VvAaH5S.png

The code I am using is the following.

```python import pymsteams

You must create the connectorcard object with the Microsoft Webhook URL

myTeamsMessage = pymsteams.connectorcard("MY-CURRENT-WEBHOOK")

Add text to the message.

myTeamsMessage.text("this is my text") myTeamsMessage.title("This is my message title")

create the section

myMessageSection = pymsteams.cardsection()

Potential Action1

myTeamsPotentialAction1 = pymsteams.potentialaction(_name = "Add a comment") myTeamsPotentialAction1.addInput("TextInput","comment","Add a comment here",False) myTeamsPotentialAction1.addAction("HttpPost","Add Comment","https://www.lg.com")

Potential Action2

myTeamsPotentialAction2 = pymsteams.potentialaction(_name = "Set due date") myTeamsPotentialAction2.addInput("DateInput","dueDate","Enter due date") myTeamsPotentialAction2.addAction("HttpPost","save","https://www.virustotal.com")

Potential Action3

myTeamsPotentialAction3 = pymsteams.potentialaction(_name = "Change Status") myTeamsPotentialAction3.choices.addChoices("In progress","0") myTeamsPotentialAction3.choices.addChoices("Active","1") myTeamsPotentialAction3.addInput("MultichoiceInput","list","Select a status",False) myTeamsPotentialAction3.addAction("HttpPost","Save","https://nvd.nist.gov/")

myTeamsMessage.addPotentialAction(myTeamsPotentialAction1) myTeamsMessage.addPotentialAction(myTeamsPotentialAction2) myTeamsMessage.addPotentialAction(myTeamsPotentialAction3)

Summary

myTeamsMessage.summary("Test Message")

Then send the card

myTeamsMessage.send() ```

I can confirm that is probably something with the pymsteams and not related to android, as i have other Teams channel where on android , the button on potential action works as expected. May i can link some info about that

Regards

Update section with adding startGroup

opened on 2022-03-21 18:30:50 by CommonCrisis

Adding the startGroup for a section

HttpPost Basic Auth.

opened on 2021-09-13 10:28:59 by svenrr

Hi, I don't know if it's possible. I could not find anything about this in Microsoft Docs either. It is about "HttpPost". Is there also the possibility for an authentication there, similar to "requests" with basic auth. via "auth=("user", "pw")?

Thanks in advance!

startGroup field in Sections

opened on 2020-04-24 07:24:14 by azs0309

This library uses a the webhook api and connector card format. When requesting new functionality, please reference the API to ensure this is possible.

Can we please have StartGroup field under the section as given in https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference#section-fields

Thanks

Releases

version 0.2.2 - relax response validation 2022-10-09 03:58:11

What's Changed

  • Update how to get the last http status code in README to reflect prior code changes. by @gmi-joelbondurant in https://github.com/rveachkc/pymsteams/pull/126
  • Doc update by @rveachkc in https://github.com/rveachkc/pymsteams/pull/127
  • Dont check if the response text is simply '1' because it's sending a complex JSON payload by @alextadams88 in https://github.com/rveachkc/pymsteams/pull/136

New Contributors

  • @gmi-joelbondurant made their first contribution in https://github.com/rveachkc/pymsteams/pull/126
  • @alextadams88 made their first contribution in https://github.com/rveachkc/pymsteams/pull/136

Full Changelog: https://github.com/rveachkc/pymsteams/compare/0.2.1...0.2.2

0.2.1 2022-01-21 14:49:26

Version 0.2.1 corrects the python setup information, preventing incompatible code from being installed on Python 2.

Full Changelog: https://github.com/rveachkc/pymsteams/compare/0.2.0...0.2.1

0.2.0 2022-01-18 05:49:12

What's Changed

  • Implement async send by @nickolay-github in https://github.com/rveachkc/pymsteams/pull/105
  • add pytest-cov by @nsano-rururu in https://github.com/rveachkc/pymsteams/pull/112

New Contributors

  • @Dritzii made their first contribution in https://github.com/rveachkc/pymsteams/pull/109
  • @aviadlevy made their first contribution in https://github.com/rveachkc/pymsteams/pull/111
  • @nickolay-github made their first contribution in https://github.com/rveachkc/pymsteams/pull/105
  • @nsano-rururu made their first contribution in https://github.com/rveachkc/pymsteams/pull/112

Full Changelog: https://github.com/rveachkc/pymsteams/compare/0.1.16...0.2.0

v0.1.16 2021-10-07 13:27:09

What's Changed

  • Bump urllib3 from 1.25.9 to 1.26.5 by @dependabot in https://github.com/rveachkc/pymsteams/pull/98
  • Upgrade requests to the newest version supporting urllib3 1.26 by @szemek in https://github.com/rveachkc/pymsteams/pull/101
  • optional body arg to POST data to action URL by @calvma in https://github.com/rveachkc/pymsteams/pull/103

New Contributors

  • @szemek made their first contribution in https://github.com/rveachkc/pymsteams/pull/101
  • @calvma made their first contribution in https://github.com/rveachkc/pymsteams/pull/103

Full Changelog: https://github.com/rveachkc/pymsteams/compare/0.1.15...0.1.16

v0.1.15 2021-05-10 13:35:33

95: return self from methods to allow chaining. Thanks @matmunn

v0.1.14 2020-09-01 23:54:35

Resolves #75, connectorcard.send() will now raise a TeamsWebhookException when a sent message is too large for the API to handle. Thanks @stmoody.

rveachkc

Also active on GitLab: https://gitlab.com/rveach

GitHub Repository Homepage