From bf4c459538d17cb13ab21e3813a291d8c56685f5 Mon Sep 17 00:00:00 2001 From: Adam Chalkley Date: Wed, 10 Jul 2024 05:34:57 -0500 Subject: [PATCH] Initial support for Power Automate workflow connectors - documentation updates - update `atc0005/go-teams-notify` to `v2.11.0-alpha.1` refs GH-523 --- README.md | 201 +++++++++++--- go.mod | 2 +- go.sum | 8 +- .../atc0005/go-teams-notify/v2/.golangci.yml | 8 - .../atc0005/go-teams-notify/v2/README.md | 252 +++++++++++++++--- .../v2/adaptivecard/adaptivecard.go | 8 +- .../atc0005/go-teams-notify/v2/send.go | 36 ++- vendor/modules.txt | 2 +- 8 files changed, 423 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index d287cf1..e107a4c 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,17 @@ Small CLI tool used to submit messages to Microsoft Teams. - [From source](#from-source) - [Using release binaries](#using-release-binaries) - [Configuration Options](#configuration-options) - - [Webhook URLs](#webhook-urls) - - [Expected format](#expected-format) - - [How to create a webhook URL (Connector)](#how-to-create-a-webhook-url-connector) + - [Setup a connection to Microsoft Teams](#setup-a-connection-to-microsoft-teams) + - [Overview](#overview-1) + - [Workflow connectors](#workflow-connectors) + - [Workflow webhook URL format](#workflow-webhook-url-format) + - [How to create a Workflow connector webhook URL](#how-to-create-a-workflow-connector-webhook-url) + - [Using Teams client Workflows context option](#using-teams-client-workflows-context-option) + - [Using Teams client app](#using-teams-client-app) + - [Using Power Automate web UI](#using-power-automate-web-ui) + - [O365 connectors](#o365-connectors) + - [O365 webhook URL format](#o365-webhook-url-format) + - [How to create an O365 connector webhook URL](#how-to-create-an-o365-connector-webhook-url) - [Command-line](#command-line) - [Limitations](#limitations) - [message size](#message-size) @@ -164,20 +172,130 @@ binaries. ## Configuration Options -### Webhook URLs - -#### Expected format - -Valid webhook URLs for Microsoft Teams use one of several (confirmed) FQDNs -patterns: +### Setup a connection to Microsoft Teams + +#### Overview + +> [!WARNING] +> +> Microsoft announced July 3rd, 2024 that Office 365 (O365) connectors within +Microsoft Teams would be [retired in 3 +months][o365-connector-retirement-announcement] and replaced by Power Automate +workflows (or just "Workflows" for short). + +Quoting from the microsoft365dev blog: + +> We will gradually roll out this change in waves: +> +> - Wave 1 - effective August 15th, 2024: All new Connector creation will be +> blocked within all clouds +> - Wave 2 - effective October 1st, 2024: All connectors within all clouds +> will stop working + +As noted, Existing O365 connector webhook URLs *should* continue to work until +2024-10-01. + +#### Workflow connectors + +##### Workflow webhook URL format + +Valid Power Automate Workflow URLs used to submit messages to Microsoft Teams +use this format: + +- `https://*.logic.azure.com:443/workflows/GUID_HERE/triggers/manual/paths/invoke?api-version=YYYY-MM-DD&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE_HERE` + +Example URL from the LinkedIn [Bring Microsoft Teams incoming webhook security to +the next level with Azure Logic App][linkedin-teams-webhook-security-article] +article: + +- `https://webhook-jenkins.azure-api.net/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=f2QjZY50uoRnX6PIpyPT3xk` + +##### How to create a Workflow connector webhook URL + +> [!TIP] +> +> Use a dedicated "service" account not tied to a specific team member to help +ensure that the Workflow connector is long lived. + +The [initial O365 retirement blog +post][o365-connector-retirement-announcement] provides a list of templates +which guide you through the process of creating a Power Automate Workflow +webhook URL. + +###### Using Teams client Workflows context option + +1. Navigate to a channel or chat +1. Select the ellipsis on the channel or chat +1. Select `Workflows` +1. Type `when a webhook request` +1. Select the appropriate template + - `Post to a channel when a webhook request is received` + - `Post to a chat when a webhook request is received` +1. Verify that `Microsoft Teams` is successfully enabled +1. Select `Next` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create flow` +1. Copy the new workflow URL +1. Select `Done` + +###### Using Teams client app + +1. Open `Workflows` application in teams +1. Select `Create` across the top of the UI +1. Choose `Notifications` at the left +1. Select `Post to a channel when a webhook request is received` +1. Verify that `Microsoft Teams` is successfully enabled +1. Select `Next` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create flow` +1. Copy the new workflow URL +1. Select `Done` + +###### Using Power Automate web UI + +[This][workflow-channel-post-from-webhook-request] template walks you through +the steps of creating a new Workflow using the + web UI: + +1. Select or create a new connection (e.g., ) to Microsoft + Teams +1. Select `Create` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create` +1. If prompted, read the info message (e.g., "Your flow is ready to go") and + dismiss it. +1. Select `Edit` from the menu across the top + - alternatively, select `My flows` from the side menu, then select `Edit` + from the "More commands" ellipsis +1. Select `When a Teams webhook request is received` (e.g., left click) +1. Copy the `HTTP POST URL` value + - this is your *private* custom Workflow connector URL + - by default anyone can `POST` a request to this Workflow connector URL + - while this access setting can be changed it will prevent this library + from being used to submit webhook requests + +#### O365 connectors + +##### O365 webhook URL format + +> [!WARNING] +> +> O365 connector webhook URLs are deprecated and [scheduled to be +retired][o365-connector-retirement-announcement] on 2024-10-01. + +Valid (***deprecated***) O365 webhook URLs for Microsoft Teams use one of several +(confirmed) FQDNs patterns: - `outlook.office.com` - `outlook.office365.com` - `*.webhook.office.com` - e.g., `example.webhook.office.com` -Using a webhook URL with any of these FQDN patterns appears to give identical -results. +Using an O365 webhook URL with any of these FQDN patterns appears to give +identical results. Here are complete, equivalent example webhook URLs from Microsoft's documentation using the FQDNs above: @@ -187,10 +305,16 @@ documentation using the FQDNs above: - - note the `webhookb2` sub-URI specific to this FQDN pattern -All of these patterns should pass the default validation applied to -user-specified webhook URLs. +All of these patterns when provided to this library should pass the default +validation applied. See the example further down for the option of disabling +webhook URL validation entirely. -#### How to create a webhook URL (Connector) +##### How to create an O365 connector webhook URL + +> [!WARNING] +> +> O365 connector webhook URLs are deprecated and [scheduled to be +retired][o365-connector-retirement-announcement] on 2024-10-01. 1. Open Microsoft Teams 1. Navigate to the channel where you wish to receive incoming messages from @@ -217,27 +341,27 @@ shadabacc3934](https://gist.github.com/chusiang/895f6406fbf9285c58ad0a3ace13d025 Currently `send2teams` only supports command-line configuration flags. Requests for other configuration sources will be considered. -| Flag | Required | Default | Possible | Description | -| -------------------------- | -------- | ------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| `h`, `help` | No | N/A | N/A | Display Help; show available flags. | -| `v`, `version` | No | `false` | `true`, `false` | Whether to display application version and then immediately exit application. | -| `channel` | No | `unspecified` | *valid Microsoft Teams channel name* | The target channel where we will send a message. If not specified, defaults to `unspecified`. | -| `color` | No | `NotUsed` | N/A | NOOP; this setting is no longer used. Values specified for this flag are ignored. | -| `message` | Yes | | *valid message string* | The (optionally) Markdown-formatted message to submit. | -| `team` | No | `unspecified` | *valid Microsoft Teams team name* | The name of the Team containing our target channel. If not specified, defaults to `unspecified`. | -| `title` | No | | *valid title string* | The (optional) title for the message to submit. | -| `sender` | No | | *valid application or script name* | The (optional) sending application name or generator of the message this app will attempt to deliver. | -| `url` | Yes | | [*valid Microsoft Office 365 Webhook URL*](#webhook-urls) | The Webhook URL provided by a pre-configured Connector. | -| `target-url` | No | | *valid comma-separated `url`, `description` pair* | The target URL and label (specified as comma separated pair) usually visible as a button towards the bottom of the Microsoft Teams message. | -| `verbose` | No | `false` | `true`, `false` | Whether detailed output should be shown after message submission success or failure | -| `silent` | No | `false` | `true`, `false` | Whether ANY output should be shown after message submission success or failure | -| `convert-eol` | No | `false` | `true`, `false` | Whether messages with Windows, Mac and Linux newlines are updated to use break statements before message submission | -| `disable-url-validation` | No | `false` | `true`, `false` | Whether webhook URL validation should be disabled. Useful when submitting generated JSON payloads to a service like . | -| `disable-branding-trailer` | No | `false` | `true`, `false` | Whether the branding trailer should be omitted from all messages generated by this application. | -| `ignore-invalid-response` | No | `false` | `true`, `false` | Whether an invalid response from remote endpoint should be ignored. This is expected if submitting a message to a non-standard webhook URL. | -| `retries` | No | `2` | *positive whole number* | The number of attempts that this application will make to deliver messages before giving up. | -| `retries-delay` | No | `2` | *positive whole number* | The number of seconds that this application will wait before making another delivery attempt. | -| `user-mention` | No | | *one or more valid comma-separated `name`, `id` pairs* | The DisplayName and ID of the recipient (specified as comma separated pair) for a user mention. May be repeated to create multiple user mentions. | +| Flag | Required | Default | Possible | Description | +| -------------------------- | -------- | ------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `h`, `help` | No | N/A | N/A | Display Help; show available flags. | +| `v`, `version` | No | `false` | `true`, `false` | Whether to display application version and then immediately exit application. | +| `channel` | No | `unspecified` | *valid Microsoft Teams channel name* | The target channel where we will send a message. If not specified, defaults to `unspecified`. | +| `color` | No | `NotUsed` | N/A | NOOP; this setting is no longer used. Values specified for this flag are ignored. | +| `message` | Yes | | *valid message string* | The (optionally) Markdown-formatted message to submit. | +| `team` | No | `unspecified` | *valid Microsoft Teams team name* | The name of the Team containing our target channel. If not specified, defaults to `unspecified`. | +| `title` | No | | *valid title string* | The (optional) title for the message to submit. | +| `sender` | No | | *valid application or script name* | The (optional) sending application name or generator of the message this app will attempt to deliver. | +| `url` | Yes | | [*valid Webhook URL*](#setup-a-connection-to-microsoft-teams) | The Webhook URL provided by a pre-configured Connector. | +| `target-url` | No | | *valid comma-separated `url`, `description` pair* | The target URL and label (specified as comma separated pair) usually visible as a button towards the bottom of the Microsoft Teams message. | +| `verbose` | No | `false` | `true`, `false` | Whether detailed output should be shown after message submission success or failure | +| `silent` | No | `false` | `true`, `false` | Whether ANY output should be shown after message submission success or failure | +| `convert-eol` | No | `false` | `true`, `false` | Whether messages with Windows, Mac and Linux newlines are updated to use break statements before message submission | +| `disable-url-validation` | No | `false` | `true`, `false` | Whether webhook URL validation should be disabled. Useful when submitting generated JSON payloads to a service like . | +| `disable-branding-trailer` | No | `false` | `true`, `false` | Whether the branding trailer should be omitted from all messages generated by this application. | +| `ignore-invalid-response` | No | `false` | `true`, `false` | Whether an invalid response from remote endpoint should be ignored. This is expected if submitting a message to a non-standard webhook URL. | +| `retries` | No | `2` | *positive whole number* | The number of attempts that this application will make to deliver messages before giving up. | +| `retries-delay` | No | `2` | *positive whole number* | The number of seconds that this application will wait before making another delivery attempt. | +| `user-mention` | No | | *one or more valid comma-separated `name`, `id` pairs* | The DisplayName and ID of the recipient (specified as comma separated pair) for a user mention. May be repeated to create multiple user mentions. | ## Limitations @@ -413,6 +537,9 @@ SOFTWARE. - Related projects - + - Webhook / Office 365 - - @@ -438,4 +565,8 @@ SOFTWARE. [go-supported-releases]: "Go Release Policy" +[o365-connector-retirement-announcement]: "Retirement of Office 365 connectors within Microsoft Teams" +[workflow-channel-post-from-webhook-request]: "Post to a channel when a webhook request is received" +[linkedin-teams-webhook-security-article]: "Bring Microsoft Teams incoming webhook security to the next level with Azure Logic App" + diff --git a/go.mod b/go.mod index 04a87be..9ca8a32 100644 --- a/go.mod +++ b/go.mod @@ -13,4 +13,4 @@ go 1.20 // // replace github.com/atc0005/go-teams-notify/v2 => ../go-teams-notify -require github.com/atc0005/go-teams-notify/v2 v2.10.0 +require github.com/atc0005/go-teams-notify/v2 v2.11.0-alpha.1 diff --git a/go.sum b/go.sum index fabc63a..cfa2212 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/atc0005/go-teams-notify/v2 v2.10.0 h1:eQvRIkyESQgBvlUdQ/iPol/lj3QcRyrdEQM3+c/nXhM= -github.com/atc0005/go-teams-notify/v2 v2.10.0/go.mod h1:SIeE1UfCcVRYMqP5b+r1ZteHyA/2UAjzWF5COnZ8q0w= +github.com/atc0005/go-teams-notify/v2 v2.11.0-alpha.1 h1:PHX3wtpybiMyDlajAC2KJe3bhYQGtY9DKx3EYSs0pf4= +github.com/atc0005/go-teams-notify/v2 v2.11.0-alpha.1/go.mod h1:WSv9moolRsBcpZbwEf6gZxj7h0uJlJskJq5zkEWKO8Y= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -8,10 +8,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/vendor/github.com/atc0005/go-teams-notify/v2/.golangci.yml b/vendor/github.com/atc0005/go-teams-notify/v2/.golangci.yml index a6067f5..4bc9eaf 100644 --- a/vendor/github.com/atc0005/go-teams-notify/v2/.golangci.yml +++ b/vendor/github.com/atc0005/go-teams-notify/v2/.golangci.yml @@ -17,10 +17,6 @@ linters: - gofmt - revive - gosec - - # Deprecated linter, but still functional as of golangci-lint v1.39.0. - # See https://github.com/atc0005/go-ci/issues/302 for more information. - - maligned - nakedret - prealloc - exportloopref @@ -41,10 +37,6 @@ linters-settings: # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity: 15 - maligned: - # print struct with more effective memory layout or not, false by default - suggest-new: true - nakedret: # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 max-func-lines: 2 diff --git a/vendor/github.com/atc0005/go-teams-notify/v2/README.md b/vendor/github.com/atc0005/go-teams-notify/v2/README.md index 043ab88..18fe2cb 100644 --- a/vendor/github.com/atc0005/go-teams-notify/v2/README.md +++ b/vendor/github.com/atc0005/go-teams-notify/v2/README.md @@ -21,9 +21,17 @@ A package to send messages to a Microsoft Teams channel. - [Changelog](#changelog) - [Usage](#usage) - [Add this project as a dependency](#add-this-project-as-a-dependency) - - [Webhook URLs](#webhook-urls) - - [Expected format](#expected-format) - - [How to create a webhook URL (Connector)](#how-to-create-a-webhook-url-connector) + - [Setup a connection to Microsoft Teams](#setup-a-connection-to-microsoft-teams) + - [Overview](#overview-1) + - [Workflow connectors](#workflow-connectors) + - [Workflow webhook URL format](#workflow-webhook-url-format) + - [How to create a Workflow connector webhook URL](#how-to-create-a-workflow-connector-webhook-url) + - [Using Teams client Workflows context option](#using-teams-client-workflows-context-option) + - [Using Teams client app](#using-teams-client-app) + - [Using Power Automate web UI](#using-power-automate-web-ui) + - [O365 connectors](#o365-connectors) + - [O365 webhook URL format](#o365-webhook-url-format) + - [How to create an O365 connector webhook URL](#how-to-create-an-o365-connector-webhook-url) - [Examples](#examples) - [Basic](#basic) - [Specify proxy server](#specify-proxy-server) @@ -46,12 +54,14 @@ inclusion into the project. ## Overview The `goteamsnotify` package (aka, `go-teams-notify`) allows sending messages -to a Microsoft Teams channel. These messages can be composed of legacy +to a Microsoft Teams channel. These messages can be composed of +[🚫 deprecated][o365-connector-retirement-announcement] legacy [`MessageCard`][msgcard-ref] or [`Adaptive Card`][adaptivecard-ref] card formats. Simple messages can be created by specifying only a title and a text body. -More complex messages may be composed of multiple sections (`MessageCard`) or +More complex messages may be composed of multiple sections ([🚫 +deprecated][o365-connector-retirement-announcement] `MessageCard`) or containers (`Adaptive Card`), key/value pairs (aka, `Facts`) and externally hosted images. See the [Features](#features) list for more information. @@ -64,12 +74,13 @@ Microsoft Teams. - Submit simple or complex messages to Microsoft Teams - simple messages consist of only a title and a text body (one or more strings) - - complex messages may consist of multiple sections (`MessageCard`), + - complex messages may consist of multiple sections ([🚫 + deprecated][o365-connector-retirement-announcement] `MessageCard`), containers (`Adaptive Card`) key/value pairs (aka, `Facts`) and externally hosted images - Support for Actions, allowing users to take quick actions within Microsoft Teams - - [`MessageCard` `Actions`][msgcard-ref-actions] + - [🚫 deprecated][o365-connector-retirement-announcement] [`MessageCard` `Actions`][msgcard-ref-actions] - [`Adaptive Card` `Actions`][adaptivecard-ref-actions] - Support for [user mentions][adaptivecard-user-mentions] (`Adaptive Card` format) @@ -78,7 +89,8 @@ Microsoft Teams. patterns - option to disable validation entirely - option to use custom validation patterns -- Configurable validation of `MessageCard` type +- Configurable validation of [🚫 + deprecated][o365-connector-retirement-announcement] `MessageCard` type - default assertion that bare-minimum required fields are present - support for providing a custom validation function to override default validation behavior @@ -96,6 +108,7 @@ In short: - The upstream project is no longer being actively developed or maintained. - This fork is now a standalone project, accepting contributions, bug reports and feature requests. + - see [Supported Releases](#supported-releases) for details - Others have also taken an interest in [maintaining their own forks](https://github.com/atc0005/go-teams-notify/network/members) of the original project. See those forks for other ideas/changes that you may find @@ -107,18 +120,41 @@ For more details, see the ## Supported Releases -| Series | Example | Status | -| -------- | ---------------- | ------------------- | -| `v1.x.x` | `v1.3.1` | Not Supported (EOL) | -| `v2.x.x` | `v2.6.0` | Supported | -| `v3.x.x` | `v3.0.0-alpha.1` | TBD | - -The current plan is to continue extending the v2 branch with new functionality -while retaining backwards compatibility. Any breakage in compatibility for the -v2 series is considered a bug (please report it). - -Long-term, the goal is to learn from missteps made in current releases and -correct as many as possible for a future v3 series. +| Series | Example | Status | +| -------- | ---------------- | -------------------------------------------- | +| `v1.x.x` | `v1.3.1` | Not Supported (EOL) | +| `v2.x.x` | `v2.6.0` | Supported (until approximately October 2024) | +| `v3.x.x` | `v3.0.0` | Planning (tentative October 2024) | +| `v4.x.x` | `v4.0.0-alpha.1` | TBD | + +The current plan (now until ~ October 2024): + +- continue supporting the v2 branch with bugfixes and minor changes +- update the v2 branch with support for Power Automate workflow URLs +- refresh documentation to cover O365 connectors and Power Automate workflow + connectors + +Early October 2024: + +- Microsoft [drops support for O365 + connectors][o365-connector-retirement-announcement] on 2024-10-01 +- we release a v3 branch + - drop support for the [🚫 +deprecated][o365-connector-retirement-announcement] O365 connectors + - drop support for the [🚫 +deprecated][o365-connector-retirement-announcement] `MessageCard`) format +- we drop support for the v2 branch + - the focus would be on maintaining the v3 branch with bugfixes and minor + changes + +> [!NOTE] +> +> While the plan for the upcoming v3 series includes dropping support for the +[🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` format +and O365 connectors, the focus would not be on refactoring the overall code +structure; many of the rough edges currently present in the API would remain +in the v3 series and await a more focused cleanup effort made in preparation +for a future v4 series. ## Changelog @@ -134,20 +170,130 @@ official release is also provided for further review. See the [Examples](#examples) section for more details. -### Webhook URLs - -#### Expected format - -Valid webhook URLs for Microsoft Teams use one of several (confirmed) FQDNs -patterns: +### Setup a connection to Microsoft Teams + +#### Overview + +> [!WARNING] +> +> Microsoft announced July 3rd, 2024 that Office 365 (O365) connectors within +Microsoft Teams would be [retired in 3 +months][o365-connector-retirement-announcement] and replaced by Power Automate +workflows (or just "Workflows" for short). + +Quoting from the microsoft365dev blog: + +> We will gradually roll out this change in waves: +> +> - Wave 1 - effective August 15th, 2024: All new Connector creation will be +> blocked within all clouds +> - Wave 2 - effective October 1st, 2024: All connectors within all clouds +> will stop working + +As noted, Existing O365 connector webhook URLs *should* continue to work until +2024-10-01. + +#### Workflow connectors + +##### Workflow webhook URL format + +Valid Power Automate Workflow URLs used to submit messages to Microsoft Teams +use this format: + +- `https://*.logic.azure.com:443/workflows/GUID_HERE/triggers/manual/paths/invoke?api-version=YYYY-MM-DD&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE_HERE` + +Example URL from the LinkedIn [Bring Microsoft Teams incoming webhook security to +the next level with Azure Logic App][linkedin-teams-webhook-security-article] +article: + +- `https://webhook-jenkins.azure-api.net/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=f2QjZY50uoRnX6PIpyPT3xk` + +##### How to create a Workflow connector webhook URL + +> [!TIP] +> +> Use a dedicated "service" account not tied to a specific team member to help +ensure that the Workflow connector is long lived. + +The [initial O365 retirement blog +post][o365-connector-retirement-announcement] provides a list of templates +which guide you through the process of creating a Power Automate Workflow +webhook URL. + +###### Using Teams client Workflows context option + +1. Navigate to a channel or chat +1. Select the ellipsis on the channel or chat +1. Select `Workflows` +1. Type `when a webhook request` +1. Select the appropriate template + - `Post to a channel when a webhook request is received` + - `Post to a chat when a webhook request is received` +1. Verify that `Microsoft Teams` is successfully enabled +1. Select `Next` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create flow` +1. Copy the new workflow URL +1. Select `Done` + +###### Using Teams client app + +1. Open `Workflows` application in teams +1. Select `Create` across the top of the UI +1. Choose `Notifications` at the left +1. Select `Post to a channel when a webhook request is received` +1. Verify that `Microsoft Teams` is successfully enabled +1. Select `Next` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create flow` +1. Copy the new workflow URL +1. Select `Done` + +###### Using Power Automate web UI + +[This][workflow-channel-post-from-webhook-request] template walks you through +the steps of creating a new Workflow using the + web UI: + +1. Select or create a new connection (e.g., ) to Microsoft + Teams +1. Select `Create` +1. Select an appropriate value from the `Microsoft Teams Team` drop-down list. +1. Select an appropriate `Microsoft Teams Channel` drop-down list. +1. Select `Create` +1. If prompted, read the info message (e.g., "Your flow is ready to go") and + dismiss it. +1. Select `Edit` from the menu across the top + - alternatively, select `My flows` from the side menu, then select `Edit` + from the "More commands" ellipsis +1. Select `When a Teams webhook request is received` (e.g., left click) +1. Copy the `HTTP POST URL` value + - this is your *private* custom Workflow connector URL + - by default anyone can `POST` a request to this Workflow connector URL + - while this access setting can be changed it will prevent this library + from being used to submit webhook requests + +#### O365 connectors + +##### O365 webhook URL format + +> [!WARNING] +> +> O365 connector webhook URLs are deprecated and [scheduled to be +retired][o365-connector-retirement-announcement] on 2024-10-01. + +Valid (***deprecated***) O365 webhook URLs for Microsoft Teams use one of several +(confirmed) FQDNs patterns: - `outlook.office.com` - `outlook.office365.com` - `*.webhook.office.com` - e.g., `example.webhook.office.com` -Using a webhook URL with any of these FQDN patterns appears to give identical -results. +Using an O365 webhook URL with any of these FQDN patterns appears to give +identical results. Here are complete, equivalent example webhook URLs from Microsoft's documentation using the FQDNs above: @@ -161,7 +307,12 @@ All of these patterns when provided to this library should pass the default validation applied. See the example further down for the option of disabling webhook URL validation entirely. -#### How to create a webhook URL (Connector) +##### How to create an O365 connector webhook URL + +> [!WARNING] +> +> O365 connector webhook URLs are deprecated and [scheduled to be +retired][o365-connector-retirement-announcement] on 2024-10-01. 1. Open Microsoft Teams 1. Navigate to the channel where you wish to receive incoming messages from @@ -191,7 +342,7 @@ This is an example of a simple client application which uses this library. - `Adaptive Card` - File: [basic](./examples/adaptivecard/basic/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [basic](./examples/messagecard/basic/main.go) #### Specify proxy server @@ -201,13 +352,14 @@ route a generated message through a specified proxy server. - `Adaptive Card` - File: [basic](./examples/adaptivecard/proxy/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [basic](./examples/messagecard/proxy/main.go) #### User Mention These examples illustrates the use of one or more user mentions. This feature -is not available in the legacy `MessageCard` card format. +is not available in the legacy [🚫 +deprecated][o365-connector-retirement-announcement] `MessageCard` card format. - File: [user-mention-single](./examples/adaptivecard/user-mention-single/main.go) - File: [user-mention-multiple](./examples/adaptivecard/user-mention-multiple/main.go) @@ -217,7 +369,8 @@ is not available in the legacy `MessageCard` card format. #### Tables These examples illustrates the use of a [`Table`][adaptivecard-table]. This -feature is not available in the legacy `MessageCard` card format. +feature is not available in the legacy [🚫 +deprecated][o365-connector-retirement-announcement] `MessageCard` card format. - File: [table-manually-created](./examples/adaptivecard/table-manually-created/main.go) - File: [table-unordered-grid](./examples/adaptivecard/table-unordered-grid/main.go) @@ -229,18 +382,19 @@ This example illustrates setting a custom user agent. - `Adaptive Card` - File: [custom-user-agent](./examples/adaptivecard/custom-user-agent/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [custom-user-agent](./examples/messagecard/custom-user-agent/main.go) #### Add an Action -This example illustrates adding an [`OpenUri`][msgcard-ref-actions] -(`MessageCard`) or [`OpenUrl`][adaptivecard-ref-actions] Action. When used, -this action triggers opening a URL in a separate browser or application. +This example illustrates adding an [`OpenUri`][msgcard-ref-actions] ([🚫 +deprecated][o365-connector-retirement-announcement] `MessageCard`) or +[`OpenUrl`][adaptivecard-ref-actions] Action. When used, this action triggers +opening a URL in a separate browser or application. - `Adaptive Card` - File: [actions](./examples/adaptivecard/actions/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [actions](./examples/messagecard/actions/main.go) #### Toggle visibility @@ -262,7 +416,7 @@ testing purposes). - `Adaptive Card` - File: [disable-validation](./examples/adaptivecard/disable-validation/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [disable-validation](./examples/messagecard/disable-validation/main.go) #### Enable custom patterns' validation @@ -272,7 +426,7 @@ URLs. - `Adaptive Card` - File: [custom-validation](./examples/adaptivecard/custom-validation/main.go) -- `MessageCard` +- [🚫 deprecated][o365-connector-retirement-announcement] `MessageCard` - File: [custom-validation](./examples/messagecard/custom-validation/main.go) ## Used by @@ -288,15 +442,27 @@ using either this library or the original project. - [Original project](https://github.com/dasrick/go-teams-notify) - [Forks of original project](https://github.com/atc0005/go-teams-notify/network/members) + - Microsoft Teams - - MS Teams - adaptive cards + - Adaptive Cards ([de-de](https://docs.microsoft.com/de-de/outlook/actionable-messages/adaptive-card), [en-us](https://docs.microsoft.com/en-us/outlook/actionable-messages/adaptive-card)) - - MS Teams - send via connectors + - O365 connectors ([de-de](https://docs.microsoft.com/de-de/outlook/actionable-messages/send-via-connectors), [en-us](https://docs.microsoft.com/en-us/outlook/actionable-messages/send-via-connectors)) - [adaptivecards.io](https://adaptivecards.io/designer) - [Legacy actionable message card reference][msgcard-ref] + - Workflow connectors + - [Creating a workflow from a chat in Teams](https://support.microsoft.com/en-us/office/creating-a-workflow-from-a-channel-in-teams-242eb8f2-f328-45be-b81f-9817b51a5f0e) + - [Creating a workflow from a channel in Teams](https://support.microsoft.com/en-us/office/creating-a-workflow-from-a-chat-in-teams-e3b51c4f-49de-40aa-a6e7-bcff96b99edc) + + + +[o365-connector-retirement-announcement]: "Retirement of Office 365 connectors within Microsoft Teams" +[workflow-channel-post-from-webhook-request]: "Post to a channel when a webhook request is received" +[linkedin-teams-webhook-security-article]: "Bring Microsoft Teams incoming webhook security to the next level with Azure Logic App" [githubtag-image]: https://img.shields.io/github/release/atc0005/go-teams-notify.svg?style=flat [githubtag-url]: https://github.com/atc0005/go-teams-notify @@ -314,3 +480,5 @@ using either this library or the original project. [adaptivecard-ref-actions]: [adaptivecard-user-mentions]: [adaptivecard-table]: + + diff --git a/vendor/github.com/atc0005/go-teams-notify/v2/adaptivecard/adaptivecard.go b/vendor/github.com/atc0005/go-teams-notify/v2/adaptivecard/adaptivecard.go index 92e3cdb..25706ec 100644 --- a/vendor/github.com/atc0005/go-teams-notify/v2/adaptivecard/adaptivecard.go +++ b/vendor/github.com/atc0005/go-teams-notify/v2/adaptivecard/adaptivecard.go @@ -49,7 +49,13 @@ const ( // // https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#support-for-adaptive-cards // https://adaptivecards.io/designer - AdaptiveCardMaxVersion float64 = 1.5 + // + // NOTE: Documented as 1.5 (adaptivecards.io/designer), but in practice > + // 1.4 is rejected for Power Automate workflow connectors. + // + // Setting to 1.4 works both for legacy O365 connectors and Workflow + // connectors. + AdaptiveCardMaxVersion float64 = 1.4 AdaptiveCardMinVersion float64 = 1.0 AdaptiveCardVersionTmpl string = "%0.1f" ) diff --git a/vendor/github.com/atc0005/go-teams-notify/v2/send.go b/vendor/github.com/atc0005/go-teams-notify/v2/send.go index 3348059..83822bd 100644 --- a/vendor/github.com/atc0005/go-teams-notify/v2/send.go +++ b/vendor/github.com/atc0005/go-teams-notify/v2/send.go @@ -34,6 +34,11 @@ const ( WebhookURLOrgWebhookPrefix = "https://example.webhook.office.com" ) +// Known Workflow URL patterns for submitting messages to Microsoft Teams. +const ( + WorkflowURLBaseDomain = "logic.azure.com" +) + // DisableWebhookURLValidation is a special keyword used to indicate to // validation function(s) that webhook URL validation should be disabled. // @@ -380,6 +385,7 @@ func processResponse(response *http.Response) (string, error) { } responseString := string(responseData) + // TODO: Refactor for v3 series once O365 connector support is dropped. switch { // 400 Bad Response is likely an indicator that we failed to provide a // required field in our JSON payload. For example, when leaving out the @@ -393,8 +399,22 @@ func processResponse(response *http.Response) (string, error) { return "", err - // Microsoft Teams developers have indicated that a 200 status code is - // insufficient to confirm that a message was successfully submitted. + case response.StatusCode == 202: + // 202 Accepted response is expected for Workflow connector URL + // submissions. + + logger.Println("202 Accepted response received as expected for workflow connector") + + return responseString, nil + + // DEPRECATED + // + // See https://github.com/atc0005/go-teams-notify/issues/262 + // + // Microsoft Teams developers have indicated that receiving a 200 status + // code when submitting payloads to O365 connectors is insufficient to + // confirm that a message was successfully submitted. + // // Instead, clients should ensure that a specific response string was also // returned along with a 200 status code to confirm that a message was // sent successfully. Because there is a chance that unintentional @@ -402,6 +422,11 @@ func processResponse(response *http.Response) (string, error) { // // See atc0005/go-teams-notify#59 for more information. case responseString != strings.TrimSpace(ExpectedWebhookURLResponseText): + logger.Printf( + "StatusCode: %v, Status: %v\n", response.StatusCode, response.Status, + ) + logger.Printf("ResponseString: %v\n", responseString) + err = fmt.Errorf( "got %q, expected %q: %w", responseString, @@ -432,7 +457,10 @@ func validateWebhook(webhookURL string, skipWebhookValidation bool, patterns []s } if len(patterns) == 0 { - patterns = []string{DefaultWebhookURLValidationPattern} + patterns = []string{ + DefaultWebhookURLValidationPattern, + WorkflowURLBaseDomain, + } } // Indicate passing validation if at least one pattern matches. @@ -442,6 +470,8 @@ func validateWebhook(webhookURL string, skipWebhookValidation bool, patterns []s return err } if matched { + logger.Printf("Pattern %v matched", pat) + return nil } } diff --git a/vendor/modules.txt b/vendor/modules.txt index ca5fffa..09ace08 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/atc0005/go-teams-notify/v2 v2.10.0 +# github.com/atc0005/go-teams-notify/v2 v2.11.0-alpha.1 ## explicit; go 1.14 github.com/atc0005/go-teams-notify/v2 github.com/atc0005/go-teams-notify/v2/adaptivecard