-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow sending cards to MS Teams via Webhook URLs (#22)
* [doc] Add TOC and documentation about sending cards resolves #21 * [feat] Rename example and add sending card functionality resolves #21 * [feat] Add MS Teams client for sending cards resolves #21 * [feat] Add sending card functionality to example resolves #21 * [refactor] Auto re-formatting applied * [refactor] Rename module * [ci] Add virtualenv to .gitignore * [doc] Rename chapter * [refactor] Add module level imports to __init__.py * [refactor] Rename webhook url variable * [doc] Add package docstring to __init__ file * [refactor] Trim trailing whitespaces * [ci] Update dependencies and pylint pipeline * [ci] Remove options section from pyproject.toml file * [ci] Add virtual environment to pipeline * [ci] Run pylint with uv * [ci] Source virtualenv before running pylint * [ci] Don't use virtual environment in CI * [doc] Fix line too long issue * [ci] Add .venv as default virtualenv to gitignore * [doc] Extend TeamsClient example Show how webhook url can be updated * [refactor] Use http status codes instead of plain values * [refactor] Re-order import statements
- Loading branch information
Showing
11 changed files
with
216 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
cards | ||
.vscode | ||
<<<<<<< HEAD | ||
__pycache__ | ||
======= | ||
__pycache__ | ||
|
||
>>>>>>> ef5a658... Initial commit | ||
.venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
""" | ||
This package provides small components for building adaptive cards compliant to | ||
the current interface definite with Python. | ||
[Schema Explorer](https://adaptivecards.io/explorer/) | ||
This `__init__.py` file exposes key components of the package for easier access: | ||
By importing the package, the following modulesare directly available: | ||
- [actions, card_types, card, client, containers, elements, inputs, utils, validation] | ||
This module also initializes the package and ensures that any necessary | ||
configuration or setup is performed. | ||
""" | ||
|
||
from adaptive_cards.actions import * | ||
from adaptive_cards.card_types import * | ||
from adaptive_cards.card import * | ||
from adaptive_cards.client import * | ||
from adaptive_cards.containers import * | ||
from adaptive_cards.elements import * | ||
from adaptive_cards.inputs import * | ||
from adaptive_cards.utils import * | ||
from adaptive_cards.validation import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
"""Features to send adaptive cards to MS Teams Channels via web hooks. | ||
## Resources | ||
- [Adaptive Cards for Python](https://github.com/dennis6p/adaptive-cards-py) | ||
- [Creating incoming web hooks with workflows](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498) | ||
""" # pylint: disable=line-too-long | ||
|
||
from typing import Any | ||
from dataclasses import asdict | ||
from http import HTTPStatus | ||
import requests | ||
|
||
from requests import Response | ||
from adaptive_cards.card import AdaptiveCard | ||
|
||
|
||
class TeamsClient: | ||
"""Client class for sending adaptive card objects to MS Teams via webhooks""" | ||
|
||
def __init__(self, webhook_url: str) -> None: | ||
self._webhook_url: str = webhook_url | ||
"""URL the client should communicate with""" | ||
|
||
@staticmethod | ||
def _create_attachment(card: AdaptiveCard) -> dict: | ||
""" | ||
Create an attachment from an AdaptiveCard. | ||
Args: | ||
card (AdaptiveCard): The AdaptiveCard to create an attachment from. | ||
Returns: | ||
dict: A dictionary representing the attachment. | ||
""" | ||
content: dict[str, Any] = asdict(card) | ||
return { | ||
"contentType": "application/vnd.microsoft.card.adaptive", | ||
"contentUrl": None, | ||
"content": content, | ||
} | ||
|
||
def webhook_url(self) -> str: | ||
""" | ||
Returns webhook URL the current client has been initialized with | ||
Returns: | ||
str: _description_ | ||
""" | ||
return self._webhook_url | ||
|
||
def set_webhook_url(self, webhook_url: str) -> None: | ||
""" | ||
Update webhook URL the client should use when sending a card | ||
Args: | ||
webhook_url (str): Webhook URL | ||
""" | ||
self._webhook_url = webhook_url | ||
|
||
def send(self, *cards: AdaptiveCard, timeout: int = 1000) -> Response: | ||
""" | ||
Send the payload of one or multiple cards to a via Microsoft Teams webhook. | ||
Args: | ||
cards (tuple[AdaptiveCard, ...]: Card objecs supposed to be sent | ||
timeout (int): Upper request timeout limit | ||
Returns: | ||
Response: Response object from the webhook request. | ||
Raises: | ||
ValueError: If no webhook URL or no cards are provided. | ||
RuntimeError: If the request to the webhook fails. | ||
""" | ||
if not self._webhook_url: | ||
raise ValueError("No webhook URL provided.") | ||
if not cards: | ||
raise ValueError("No cards provided.") | ||
|
||
headers = {"Content-Type": "application/json"} | ||
attachments = [self._create_attachment(card) for card in cards] | ||
payload = {"attachments": attachments} | ||
response = requests.post( | ||
self._webhook_url, headers=headers, json=payload, timeout=timeout | ||
) | ||
if response.status_code not in (HTTPStatus.OK, HTTPStatus.ACCEPTED): | ||
raise RuntimeError( | ||
f"Failed to send card: {response.status_code}, {response.text}" | ||
) | ||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.