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

How to add elements: RichTextBlock, CodeBlock? #288

Closed
MichaelUrman opened this issue Aug 5, 2024 · 13 comments · Fixed by #298 or #293
Closed

How to add elements: RichTextBlock, CodeBlock? #288

MichaelUrman opened this issue Aug 5, 2024 · 13 comments · Fixed by #298 or #293
Labels
card format/adaptivecard Adaptive Card support documentation Improvements or additions to documentation enhancement New feature or request validation
Milestone

Comments

@MichaelUrman
Copy link

In migrating message cards to adaptive cards, I've had difficulties replicating some simple things. It seems to me that some, like the title/subtitle/etc. might be handled a few different ways, such as with RichTextBlock elements. Others, like no-longer-supported markdown fenced code blocks, look like they require a MSTeams extension, the CodeBlock element.

Are there good ways to add RichTextBlock or CodeBlock elements outside of go-teams-notify, or is there any interest in adding them or having them added by a PR? If the last, is extending Element the right approach? (I share some concerns I infer from #205 (comment) but it does appear to be the practical path forward.)

@MichaelUrman MichaelUrman changed the title How to add elements: RichtTextBlock, CodeBlock? How to add elements: RichTextBlock, CodeBlock? Aug 5, 2024
@atc0005
Copy link
Owner

atc0005 commented Aug 5, 2024

@MichaelUrman,

Thanks for your interest & for reaching out.

Others, like no-longer-supported markdown fenced code blocks, look like they require a MSTeams extension, the CodeBlock element.

I briefly looked over that and I agree, it looks like that is the current approach to providing fenced code blocks.

Are there good ways to add RichTextBlock or CodeBlock elements outside of go-teams-notify

There are probably alternative packages which provide similar functionality to this one. If that's what you mean.

is there any interest in adding them or having them added by a PR?

Sure. There may be one issue with doing so however.

From #275:

Changes

  • lower AdaptiveCardMaxVersion from 1.5 to 1.4
    • this almost seems like a bug on Teams' end as this limitation is not communicated (from what I could tell) via https://adaptivecards.io/designer/
    • using a value of 1.4 appears to work equally well for O365 and Workflow connectors

This was done to work around what appears to be a bug:

Not sure if that will interfere or if continuing to use a value of 1.4 will work here also.

If the last, is extending Element the right approach? (I share some concerns I infer from #205 (comment) but it does appear to be the practical path forward.)

I still agree with my thoughts there. The approach taken has worked, but has proven limiting.

The workaround thus far (and likely continuing until a future v3 or replacement "subpackage" for the v2 series) has been to:

  • add in the needed fields to Element
  • provide constructors to set the needed fields
  • add validation to help prevent use of unsupported fields for the desired type

I'm open to other ideas.

@MichaelUrman
Copy link
Author

Are there good ways to add RichTextBlock or CodeBlock elements outside of go-teams-notify

There are probably alternative packages which provide similar functionality to this one. If that's what you mean.

I meant ways to mostly use go-teams-notify, extending its element support locally. From what I can tell, the slice of concrete Element requires that Element itself be extended.

Sure. There may be one issue with doing so however.
[...]
Not sure if that will interfere or if continuing to use a value of 1.4 will work here also.

I locally extended a copy of go-teams-notify to add the CodeBlock support, and it displays fine for me with current "new" teams client, targeting both an older connector webhook and a newer workflow webhook. It also failed delivery if I excluded the "codeSnippet" property. I'm unclear what version the teams extensions require, or if all we can rely on is the fuzzy "does it appear to work?"

  • add in the needed fields to Element
  • provide constructors to set the needed fields
  • add validation to help prevent use of unsupported fields for the desired type

I did the first two in my test mentioned above, but merely tweaked the existing validation to allow the CodeBlock. If you're interested, I can submit a PR with what I have so far, or I can attempt to add proper validation first.

I'm open to other ideas.

And I agree with your thoughts as well. The need to extend Element itself results in a lot of potential pitfalls that require run-time verification, or blind hope. Changing the approach will break compatibility.

I have put some thought into leveraging go's type system here to ensure compile-time verification, and I don't have a conclusively better approach. Neither marker interfaces (e.g. type Element interface { isAnElement() }) nor idiomatic verb-er interfaces fully satisfy. (What's the semantic of an adaptive card Element? How does it differ from an ISelectAction? Do either allow for extensions?)

Orthogonally, the interface can be unexported, internal, or exported. Internal allows you to split, say, MSTeams extensions from the primary package while retaining full control (and full responsibility). Fully exported allows custom extension by relinquishing control, including over validation. Is that a problem or a strength? Probably depends on the attitudes of the author and consumer.

@atc0005
Copy link
Owner

atc0005 commented Aug 6, 2024

I'm unclear what version the teams extensions require, or if all we can rely on is the fuzzy "does it appear to work?"

The tricky bit is that their documentation notes 1.5 as the version tables were introduced, but specifying 1.5 results in the payload being rejected by workflow webhooks. So, we specify 1.4 and both webhook connectors (o365 and workflow) accept the payload. Not ideal, but it works (for now).

If you're interested, I can submit a PR with what I have so far, or I can attempt to add proper validation first.

That works with me. You can submit the PR, we can look at it together and if you're open to it I can either offer specific feedback via PR review comments and/or I can push minor tweaks to your branch. You could rebase at the end to drop commits of mine, etc.

Whatever works for you.

My time is limited, so please don't be offended if I go silent for a bit.

@atc0005 atc0005 added enhancement New feature or request card format/adaptivecard Adaptive Card support documentation Improvements or additions to documentation validation labels Aug 8, 2024
@MichaelUrman
Copy link
Author

I've created #293. It functions in my tests, but I won't evaluate it for style and other additional requirements. :)

My time is limited, so please don't be offended if I go silent for a bit.

Totally understood; same here. If it's on my end, feel free to take this to completion as you see fit, whether with my commits or with fresh ones of your own.

@atc0005
Copy link
Owner

atc0005 commented Aug 8, 2024

@MichaelUrman,

I looked over #293 briefly and the worst I could find was a minor typo in a doc comment. :)

CI reports it here (I just approved the jobs to run):

I'll try to give this a more thorough review in the next week.

Thanks for your work on this.

@atc0005 atc0005 added this to the v2.13.0 milestone Aug 8, 2024
@atc0005
Copy link
Owner

atc0005 commented Aug 12, 2024

@MichaelUrman I created a temporary branch, merged yours and saved some WIP scratch work on it:

It's been a while since I've actually used this project, so I'm coming at this with nearly fresh eyes. This includes among other things remembering the API surface and how everything fits together.

It was humbling to try and recall the steps for composing a message using existing examples.

I've still got further tinkering to do, but wanted to share the current progress in case it is useful.

One change I'm not sure about is listing the supported languages for the codeblock.

I like having those details available, both on the factory function and maybe on the field for the Element type (makes for a useful quick reference), but with the supported languages subject to change there is an argument to be made to leave that out and have the library consumer read upstream documentation directly.

EDIT:

I'm guilty of not reading the docs first; it's slowly starting to come back to me (26bff9b). I'll update the example I started crafting accordingly.

@MichaelUrman
Copy link
Author

Thanks for the typo fixes, what sloppiness! 😅 I can push similar fixes if you want, but it looks like your branch is in a better state already.

I agree it's nice to have the details at hand, whether as constants or function commentary. I dodged the question because the fuzziness of the docs on CodeBlock. (Do you specify e.g. "json" or "JSON"? It's currently a trick question: either works. But I don't know what guarantees there are.)

In terms of not remembering the API, I hear you. I had to walk through the code to gather this, as I spent way more focus on laying out the adaptive card, whereas sending just worked so I forgot about it. The general structure my test uses looks loosely like the following, which seems to match your later comment.

cli := goteamsnotify.NewTeamsClient()
# for tests: cli.SetHTTPClient(&http.Client{Transport: MockTransport(...)})

card := adaptivecard.NewCard()
card.SetFullWidth()

head := adaptivecard.NewColumnSet()
# omitted configuration of head's children, culminating in:
# head.Columns = append(head.Columns, image, heading)
card.Body = append(card.Body, head)

# more elements omitted, as well as card.AddAction calls

msg, err := adaptivecard.NewMessageFromCard(card)

cli.Send(hook, msg)

@atc0005
Copy link
Owner

atc0005 commented Aug 16, 2024

@MichaelUrman

Thanks for the typo fixes, what sloppiness! 😅

It happens. If it wasn't for spellcheck I'd be in a mess. :)

I can push similar fixes if you want, but it looks like your branch is in a better state already.

I setup my branch just for illustration purposes (e.g., messy commit messages), but am happy to push fixes to yours if you like.

I hope to pick back up on this early next week.

The additional changes I'm working on could be incorporated into your branch or as a follow-up PR, either way works for me.

@atc0005
Copy link
Owner

atc0005 commented Aug 22, 2024

@MichaelUrman

Do you want to make any further changes to your PR?

I'm happy to push the typo fixes and doc comment tweaks to your branch, or can apply those changes in a follow-up PR. Either way works for me.

@MichaelUrman
Copy link
Author

I'm happy for you to take it from here. I trust your instincts over mine to match the rest of your project. I hope this simple base in 293 was more help than distraction.

Maybe I'll draft some RichTextBlock support sometime... 😉

@atc0005
Copy link
Owner

atc0005 commented Aug 22, 2024

@MichaelUrman

Thanks for confirming and your work on the PR.

I'll plan to merge #293 as-is tomorrow and then follow-up with additional changes as a separate PR.

Further PRs are welcome. :)

atc0005 added a commit that referenced this issue Aug 23, 2024
- add `examples/adaptivecard/codeblock`
- update README file to mention new CodeBlock support
- minor linting fixes
- minor doc comment adjustments to list supported programming
  languages for CodeBlock element

refs GH-288
@atc0005 atc0005 linked a pull request Aug 23, 2024 that will close this issue
@atc0005
Copy link
Owner

atc0005 commented Aug 23, 2024

@MichaelUrman

New pre-release tag:

Will wait about a week for any potential feedback (to allow time to fix anything we've missed) before a stable 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 documentation Improvements or additions to documentation enhancement New feature or request validation
Projects
None yet
2 participants