Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Adaptive Card message format support #157

Closed
atc0005 opened this issue Feb 25, 2022 · 16 comments
Closed

Add Adaptive Card message format support #157

atc0005 opened this issue Feb 25, 2022 · 16 comments
Assignees
Labels
card format/adaptivecard Adaptive Card support enhancement New feature or request
Milestone

Comments

@atc0005
Copy link
Owner

atc0005 commented Feb 25, 2022

I've not fully explored it, but as part of the initial work for GH-127 I learned that it appears to support both user mentions and existing functionality provided by the legacy MessageCard format.

Initial support for this format would unify the functionality currently provided (separately) by the messagecard and botapi packages.

@atc0005 atc0005 added the enhancement New feature or request label Feb 25, 2022
@atc0005 atc0005 added this to the Future milestone Feb 25, 2022
@atc0005 atc0005 self-assigned this Feb 25, 2022
@atc0005 atc0005 modified the milestones: Future, v2.7.0 Mar 10, 2022
@atc0005
Copy link
Owner Author

atc0005 commented Mar 10, 2022

Minimum implementation example:

https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#send-adaptive-cards-using-an-incoming-webhook

Maybe not. Attempting to use this results in this error:

Summary or Text is required.

I've seen multiple references to a requirement that the card is wrapped as an "attachment".

This appears to work:

{
    "type": "message",
    "attachments": [
        {
            "contentType": "application/vnd.microsoft.card.adaptive",
            "contentUrl": null,
            "content": {
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "type": "AdaptiveCard",
                "version": "1.2",
                "body": [
                    {
                        "type": "TextBlock",
                        "text": "Hi <at>John Doe</at>"
                    }
                ],
                "msteams": {
                    "entities": [
                        {
                            "type": "mention",
                            "text": "<at>John Doe</at>",
                            "mentioned": {
                                "id": "29:123124124124",
                                "name": "John Doe"
                            }
                        }
                    ]
                }
            }
        }
    ]
}

but places the text within a "box":

image

refs https://stackoverflow.com/questions/50753072/microsoft-teams-webhook-generating-400-for-adaptive-card

@atc0005
Copy link
Owner Author

atc0005 commented Mar 10, 2022

but places the text within a "box":

image

After comparing against earlier test messages, this looks to be normal; I'm likely just not used to seeing a minimal implementation like we're starting with here.

@atc0005
Copy link
Owner Author

atc0005 commented Mar 11, 2022

Looks like version 1.3 of the Adaptive Card format is the highest version supported (at present) by Microsoft Teams for user generated messages.

@atc0005
Copy link
Owner Author

atc0005 commented Mar 30, 2022

Learned that multiple cards in the attachments collection without carousel display option hides cards after the first. Not sure if this is a bug, or if it's intentional.

@atc0005
Copy link
Owner Author

atc0005 commented Mar 30, 2022

Looks like version 1.3 of the Adaptive Card format is the highest version supported (at present) by Microsoft Teams for user generated messages.

Inconclusive. Per https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference, Adaptive Card schema v1.4 or earlier is supported if the card is sent via bot or action based messaging extension.

It's unclear where incoming webhooks fall.

@atc0005
Copy link
Owner Author

atc0005 commented Mar 31, 2022

Looks like version 1.3 of the Adaptive Card format is the highest version supported (at present) by Microsoft Teams for user generated messages.

Inconclusive. Per https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference, Adaptive Card schema v1.4 or earlier is supported if the card is sent via bot or action based messaging extension.

It's unclear where incoming webhooks fall.

Using https://adaptivecards.io/designer and setting host app to Microsoft Teams - Dark with the Target version set to 1.4 or higher results in this warning:

[Warning] The selected Target Version (1.4) is only supported by bot sent card. For user sent cards please use version 1.3

max supported Adaptive Card schema version for Microsoft Teams

Looks like 1.3 might be the max supported version after all.

@atc0005
Copy link
Owner Author

atc0005 commented Mar 31, 2022

Setting Target version to 1.5 confirms explicitly that version 1.5 is not supported:

[Warning] The selected Target Version (1.5) is greater than the version supported by Microsoft Teams - Dark (1.4)

@atc0005
Copy link
Owner Author

atc0005 commented Mar 31, 2022

Setting Target version to 1.5 confirms explicitly that version 1.5 is not supported:

FWIW: Setting the version to 1.5 in the JSON payload isn't enough to cause the remote API to reject it. Not something to rely on, but worth noting.

@atc0005
Copy link
Owner Author

atc0005 commented Apr 4, 2022

Some definite drawbacks of using an Adaptive Card vs the legacy MessageCard, formatting in particular:

The following Markdown tags are not supported:

  • Headers
  • Tables
  • Images
  • Preformatted text
  • Blockquotes

The last two I personally relied upon when pushing formatted log messages or error messages from monitoring systems into Teams channels.

Will need to annotate the formatting functionality sufficiently to indicate that it's intended for use with MessageCard text and not text intended for Adaptive Cards.

refs https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format#format-cards-with-markdown

@atc0005
Copy link
Owner Author

atc0005 commented Apr 8, 2022

Beginning initial polish phase.

@atc0005
Copy link
Owner Author

atc0005 commented Apr 9, 2022

Will need to annotate the formatting functionality sufficiently to indicate that it's intended for use with MessageCard text and not text intended for Adaptive Cards.

Ended up "moving" the functionality into the messagecard package, marking the existing functions as deprecated.

atc0005 added a commit that referenced this issue Apr 10, 2022
Add early (and incomplete) implementation of `Adaptive Card` format
(new `adaptivecard` package). This new package is an alternative to
the current implementation of the legacy `MessageCard` format
(`messagecard` package).

Remove `botapi` package. This package was a partial implementation and
intended as a temporary resource until the `adaptivecard` package was
developed sufficiently to replace it. This package could make an
appearance later in a more complete form if there is need for it.

CHANGES

The changes listed here are in comparison to the previous
v2.7.0-alpha.1 release.

- add initial implementation of the `adaptivecard` package
- remove partial implementation of `botapi` package
  - incomplete implementation, known issues (atc0005/send2teams#225)
- example code
  - create subdir for new `adaptivecard` examples and populate with
    equivalents
  - create subdir for existing `messagecard` examples
  - refresh doc comments of existing examples
  - attempt to simplify implementation of examples
- documentation refresh
  - cover new features provided by the new `adaptivecard` package
  - make note of plans to extend v2 branch features while retaining
    backwards compatibility with an eye towards a future v3 series
- add `goteamsnotify.InList()` helper func
- simplify `goteamsnotify.messagePreparer` interface
- simplify `MessageCard.Prepare()` implementation
- explicitly mark files containing exclusively deprecated code
- explicitly mark existing formatting functionality as specific to the
  `MessageCard` format

LIMITATIONS

- the `adaptivecard` package is new and its API is subject to change
  before the next stable release
- the `adaptivecard` package is incomplete
  - while the new package contains sufficient functionality to be
    useful and provide a close approximation of functionality to the
    existing `messagecard` package, it is still missing support for
    some (available) features that the older package provides
- there are many TODO items for the new `adaptivecard` package, most
  of which are intended to be removed before the next stable release
- there are active `gocognit` linter warnings for the `Validate()`
  method for multiple types in the new `adaptivecard` package
  - this method is responsible for asserting known requirements for
    multiple field values for its type
  - more "bake time" is needed to determine a simpler approach

REFERENCES

- refs GH-157
- refs atc0005/send2teams#225
@atc0005
Copy link
Owner Author

atc0005 commented Apr 10, 2022

GH-162 adds the first usable implementation of the new package. Unstable/dev release v2.7.0-alpha.2 provides that functionality for general review & feedback.

This should resolve atc0005/send2teams#225 and provide a starting point for GH-127.

@atc0005
Copy link
Owner Author

atc0005 commented Jun 29, 2022

I've closed GH-127 and marked it as resolved (no negative feedback received since I noted the new support two months back).

I plan to focus on linting errors surfaced from recent PRs, then tag a release candidate shortly after.

atc0005 added a commit that referenced this issue Jul 1, 2022
Create internal validation helper and use it to replace existing
validation logic used in methods identified by gocognit. The end
result is that the larger, more complex validation methods are
(hopefully) more concise and readable now.

I began the process of replacing the logic used by other validation
methods with validation helper calls, but have not finished the
conversion work. I plan to return to this with a future PR once
I've reviewed the remaining (unconverted) validation logic further.

Credit to Fabrizio Milo for sharing the original implementation:

- https://stackoverflow.com/a/23960293/903870
- https://github.com/Mistobaan

refs GH-157
@atc0005
Copy link
Owner Author

atc0005 commented Jul 1, 2022

I plan to focus on linting errors surfaced from recent PRs, then tag a release candidate shortly after.

Output from the most recent PR submitted by dependabot:

2022-06-30T07:06:12.4003785Z Running golangci-lint ...
2022-06-30T07:06:13.4179543Z level=warning msg="[runner] The linter 'maligned' is deprecated (since v1.38.0) due to: The repository of the linter has been archived by the owner.  Replaced by govet 'fieldalignment'."
2022-06-30T07:06:18.1993072Z adaptivecard/adaptivecard.go:1089:1: cognitive complexity 46 of func `(Element).Validate` is high (> 10) (gocognit)
2022-06-30T07:06:18.1993890Z func (e Element) Validate() error {
2022-06-30T07:06:18.1994211Z ^
2022-06-30T07:06:18.1994668Z adaptivecard/adaptivecard.go:938:1: cognitive complexity 29 of func `(Card).Validate` is high (> 10) (gocognit)
2022-06-30T07:06:18.1995138Z func (c Card) Validate() error {
2022-06-30T07:06:18.1995857Z ^
2022-06-30T07:06:18.1996429Z adaptivecard/adaptivecard.go:1262:1: cognitive complexity 15 of func `(Column).Validate` is high (> 10) (gocognit)
2022-06-30T07:06:18.1996866Z func (c Column) Validate() error {
2022-06-30T07:06:18.1997349Z ^
2022-06-30T07:06:18.1997759Z adaptivecard/adaptivecard.go:1412:1: cognitive complexity 11 of func `(Action).Validate` is high (> 10) (gocognit)
2022-06-30T07:06:18.1998213Z func (a Action) Validate() error {
2022-06-30T07:06:18.1998515Z ^
2022-06-30T07:06:18.2093458Z make: *** [Makefile:59: linting] Error 1
2022-06-30T07:06:18.2156015Z ##[error]Process completed with exit code 2.

atc0005 added a commit that referenced this issue Jul 1, 2022
Create internal validation helper and use it to replace existing
validation logic used in methods identified by gocognit. The end
result is that the larger, more complex validation methods are
(hopefully) more concise and readable now.

I began the process of replacing the logic used by other validation
methods with validation helper calls, but have not finished the
conversion work. I plan to return to this with a future PR once
I've reviewed the remaining (unconverted) validation logic further.

Credit to Fabrizio Milo for sharing the original implementation:

- https://stackoverflow.com/a/23960293/903870
- https://github.com/Mistobaan

refs GH-157
atc0005 added a commit that referenced this issue Jul 12, 2022
- rename `validation` package back to original name of
  `validator`
  - attempting to follow the guideline of naming a package
    based on what it provides, not what it does
- drop "Must" prefix from validation methods in an effort to make the
  method names sound more natural
- add Validator.NoNilValuesInCollection method
- add validation handling for ColumnItems type alias ([]*Element)
- use Validator methods for validation of Column type

Further refactoring could be beneficial, as would further conversion
of Validate method implementations to use of the validator package.

refs GH-157
atc0005 added a commit that referenced this issue Jul 12, 2022
- rename `validation` package back to original name of
  `validator`
  - attempting to follow the guideline of naming a package
    based on what it provides, not what it does
- drop "Must" prefix from validation methods in an effort to make the
  method names sound more natural
- add Validator.NoNilValuesInCollection method
- add validation handling for ColumnItems type alias ([]*Element)
- use Validator methods for validation of Column type

Further refactoring could be beneficial, as would further conversion
of Validate method implementations to use of the validator package.

refs GH-157
@atc0005
Copy link
Owner Author

atc0005 commented Sep 18, 2022

Initial implementation complete. Further polishing is needed, but will focus on that in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
card format/adaptivecard Adaptive Card support enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant