{"id":16101441,"url":"https://github.com/mendhak/airflow-ms-teams-operator","last_synced_at":"2026-02-25T23:02:02.036Z","repository":{"id":45675533,"uuid":"134773601","full_name":"mendhak/Airflow-MS-Teams-Operator","owner":"mendhak","description":"Airflow operator that can send messages to MS Teams","archived":false,"fork":false,"pushed_at":"2024-08-20T18:19:41.000Z","size":366,"stargazers_count":84,"open_issues_count":0,"forks_count":25,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-12T03:31:21.511Z","etag":null,"topics":["airflow","airflow-plugin","ms-teams","python"],"latest_commit_sha":null,"homepage":"https://code.mendhak.com/Airflow-MS-Teams-Operator/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mendhak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-24T22:07:01.000Z","updated_at":"2025-03-27T01:54:46.000Z","dependencies_parsed_at":"2024-10-26T19:31:27.680Z","dependency_job_id":"1fff4d72-dc31-4d05-a47f-dcb09aac8fe7","html_url":"https://github.com/mendhak/Airflow-MS-Teams-Operator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mendhak/Airflow-MS-Teams-Operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2FAirflow-MS-Teams-Operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2FAirflow-MS-Teams-Operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2FAirflow-MS-Teams-Operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2FAirflow-MS-Teams-Operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mendhak","download_url":"https://codeload.github.com/mendhak/Airflow-MS-Teams-Operator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2FAirflow-MS-Teams-Operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29844845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T22:37:40.667Z","status":"ssl_error","status_checked_at":"2026-02-25T22:37:25.960Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["airflow","airflow-plugin","ms-teams","python"],"created_at":"2024-10-09T18:49:56.685Z","updated_at":"2026-02-25T23:02:01.999Z","avatar_url":"https://github.com/mendhak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nThis is an Airflow operator that can send cards to MS Teams via webhooks. There are various options to customize the appearance of the cards. \n\n## Screenshots\n\n\n\n| Header, subtitle, and body                                       | Header, subtitle, body, facts, and a button                                |\n| ---------------------------------------------------------------- | -------------------------------------------------------------------------- |\n| ![Card with a header, subtitle, and body](./screenshots/001.png) | ![Card with a header, subtitle, body, and a button](./screenshots/004.png) |\n\n| Body with coloured text and coloured button                           | Coloured header, body, button, in dark mode                  |\n| --------------------------------------------------------------------- | ------------------------------------------------------------ |\n| ![Body with coloured text and coloured button](./screenshots/002.png) | ![Header, body, button, in dark mode](./screenshots/003.png) |\n\n| Body and empty green header                            | Body and coloured header, without logo                  |\n| ------------------------------------------------------ | ------------------------------------------------------- |\n| ![Body with empty green header](./screenshots/005.png) | ![Body and header, without logo](./screenshots/006.png) |\n\n\n## Setup\n\nCreate a webhook to post to Teams. The Webhook needs to be of the PowerAutomate type, not the deprecated Incoming Webhook type. Currently this is done either through the 'workflows' app in Teams, or via [PowerAutomate](https://powerautomate.com). \n\nOnce that's ready, [create an HTTP Connection](https://airflow.apache.org/docs/apache-airflow/stable/howto/connection.html) in Airflow with the Webhook URL. \n\n* Conn Type: HTTP\n* Host: The URL without the https://\n* Schema: https\n\nCopy the [ms_teams_power_automate_webhook_operator.py](./ms_teams_powerautomate_webhook_operator.py) file into your Airflow dags folder and `import` it in your DAG code.\n\n## Usage\n\nThe usage can be very basic from just a message, to [several parameters](#parameters) including a full card with header, subtitle, body, facts, and a button. There are some style options too.\n\nA very basic message:\n\n```python\n op1 = MSTeamsPowerAutomateWebhookOperator(\n        task_id=\"send_to_teams\",\n        http_conn_id=\"msteams_webhook_url\",\n        body_message=\"DAG **lorem_ipsum** has completed successfully in **localhost**\",\n    )\n```\n\nAdd a button:\n    \n```python\nop1 = MSTeamsPowerAutomateWebhookOperator(\n        task_id=\"send_to_teams\",\n        http_conn_id=\"msteams_webhook_url\",\n        body_message=\"DAG **lorem_ipsum** has completed successfully in **localhost**\",\n        button_text=\"View Logs\",\n        button_url=\"https://example.com\",\n    )\n```\n\nAdd a heading and subtitle:\n\n```python\nop1 = MSTeamsPowerAutomateWebhookOperator(\n        task_id=\"send_to_teams\",\n        http_conn_id=\"msteams_webhook_url\",\n        heading_title=\"DAG **lorem_ipsum** has completed successfully\",\n        heading_subtitle=\"In **localhost**\",\n        body_message=\"DAG **lorem_ipsum** has completed successfully in **localhost**\",\n        button_text=\"View Logs\",\n        button_url=\"https://example.com\",\n    )\n```\n\nAdd some colouring — header bar colour, subtle subtitle, body text colour, button colour:\n\n```python\nop1 = MSTeamsPowerAutomateWebhookOperator(\n        task_id=\"send_to_teams\",\n        http_conn_id=\"msteams_webhook_url\",\n        header_bar_style=\"good\",\n        heading_title=\"DAG **lorem_ipsum** has completed successfully\",\n        heading_subtitle=\"In **localhost**\",\n        heading_subtitle_subtle=False,\n        body_message=\"DAG **lorem_ipsum** has completed successfully in **localhost**\",\n        body_message_color_type=\"good\",\n        button_text=\"View Logs\",\n        button_url=\"https://example.com\",\n        button_style=\"positive\",\n    )\n```\n\nYou can also look at [sample_dag.py](./sample_dag.py) for an example of how to use this operator in a DAG.\n\n\n## Parameters\n\nHere are all the parameters that can be set.\n\n| Parameter               | Values                                                               | Notes                                                                                                   |\n| ----------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |\n| http_conn_id            | The connection ID, eg \"msteams_webhook_url\"                          |                                                                                                         |\n| card_width_full         | True(default) or False                                               | If false, the card will be the MSTeams default.                                                         |\n| header_bar_show         | True(default) or False                                               | If false, heading title, subtitle, logo won't be shown.                                                 |\n| header_bar_style        | `default`, `emphasis`, `good`, `attention`, `warning`, `accent`      | [docs - style](https://adaptivecards.io/explorer/Container.html)                                        |\n| heading_title           |                                                                      | [Limited Markdown support](https://aka.ms/ACTextFeatures), no `monospace`                               |\n| heading_title_size      | `default`, `small`, `medium`, `large`, `extraLarge`                  | [docs - size](https://adaptivecards.io/explorer/TextBlock.html)                                         |\n| heading_subtitle        |                                                                      | Appears just below the title, [Limited Markdown support](https://aka.ms/ACTextFeatures), no `monospace` |\n| heading_subtitle_subtle | True(default) or False                                               | Subtle means toned down to appear less prominent                                                        |\n| heading_show_logo       | True(default) or False                                               |                                                                                                         |\n| body_message            |                                                                      | [Limited Markdown support](https://aka.ms/ACTextFeatures), no `monospace`                               |\n| body_message_color_type | `default`, `dark`, `light`, `accent`, `good`, `warning`, `attention` | [docs - color](https://adaptivecards.io/explorer/TextBlock.html)                                        |\n| body_facts_dict         | Example: {'aaa':'bbb','ccc':'ddd'}                                   | The key value pairs show up as facts in the card                                                        |\n| button_text             | Example: \"View Logs\"                                                 | If not set, button won't be shown                                                                       |\n| button_url              | Example: \"https://example.com\"                                       | For example, the URL to the Airflow log                                                                 |\n| button_style            | `default`, `positive`, `destructive`                                 | [docs - style](https://adaptivecards.io/explorer/Action.OpenUrl.html)                                   |\n| button_show             | True(default) or False                                               |                                                                                                         |\n\n\n\n\n## The old incoming webhooks\n\nThis operator only works with the new PowerAutomate webhooks. The old incoming webhooks were deprecated in this [Teams announcement](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/). It says they'll keep working until December 2025 but I expect much degradation in the service before then.  \n\nThe previous version of this operator, which worked with the old incoming webhooks, is in [the master-old-connectors branch](https://github.com/mendhak/Airflow-MS-Teams-Operator/tree/master-old-connectors). This operator is not a drop-in replacement for the old one, as there are too many differences.\n\n## Contribute\n\nAny simple feature requests, please fork and submit a PR. \n\n## Testing this operator locally for development\n\nI'm using the [Airflow Docker Compose](https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html), with a few changes. Load examples is false and added an extra_hosts.\n\nRun this to prepare the environment:\n\n```\nmkdir -p ./dags ./logs ./plugins ./config\necho -e \"AIRFLOW_UID=$(id -u)\" \u003e .env\ndocker compose up airflow-init\ndocker compose up\n```\n\nThen wait a bit, and open http://localhost:8080 with airflow:airflow. \n\nTo create a connection quickly, use this CLI command, substitute the url bit.\n\n```\ndocker compose exec -it airflow-webserver airflow connections add 'msteams_webhook_url' --conn-json '{\"conn_type\": \"http\", \"description\": \"\", \"host\": \"\u003curl-goes-here-without https://\u003e\", \"schema\": \"https\", \"login\": \"\", \"password\": null, \"port\": null }'\n```\n\nNow run the sample_dag to see the operator in action. \n\n### Echoing requests\n\nTo troubleshoot the requests going out, use the included httpecho container which echoes the request to output.  \nIn Airflow connections, create an HTTP Connection to http://httpecho:8081 \n\n\n```\ndocker compose exec -it airflow-webserver airflow connections add 'msteams_webhook_url' --conn-json '{\"conn_type\": \"http\", \"description\": \"\", \"host\": \"httpecho:8081/a/b/c\", \"schema\": \"http\", \"login\": \"\", \"password\": null, \"port\": null }'\n\ndocker compose logs -f httpecho\n```\n\nNow when you run the sample_dag, you can see the request reflected in the httpecho container.\n\n### Posting a card with curl\n\nTo manually post the sample card to a webhook URL, just for testing, use the included samplecard.json file.\n\n```\ncurl -X POST -H 'Content-Type: application/json' --data-binary @samplecard.json  \"https://prod-11.westus.logic.azure.com:443/workflows/..............\"\n```\n\n\n## License\n\nApache 2.0 (see code file headers) ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendhak%2Fairflow-ms-teams-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmendhak%2Fairflow-ms-teams-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendhak%2Fairflow-ms-teams-operator/lists"}