Add post: Disabling Adaptive Cards After Submission in Copilot Studio Agents - #336
Conversation
… Agents Two patterns to disable or replace Adaptive Cards after submission: WebChat attachment middleware (client-side) and Teams Universal Actions (server-side). Adds header image and mmonisha author. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Blog preview check passed for The Jekyll site compiled successfully and generated previews for the newly added post.
Preview artifacts:
|
… scroll Rename post to 2026-06-26 and update front matter date. Shorten cell text in both comparison tables so they fit the content column without Chirpy's horizontal scroll wrapper kicking in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
adilei
left a comment
There was a problem hiding this comment.
Thanks for this, Monisha Monikantarajan (@mmonisha) — genuinely useful topic, and the implementation holds up. I checked the WebChat middleware against the official BotFramework-WebChat sample and it's faithful (same recentBotMessage logic, same AdaptiveCardContent props, same .card__action--performed CSS), and the Teams Universal Actions flow matches its source too.
I've left inline comments throughout. The two I'd treat as blockers before publishing:
- The "ESS" references are a technical-accuracy problem. Employee Self-Service is a real M365 Copilot agent built on Copilot Studio, and the client-side WebChat pattern can't apply to it. Details inline at the WebChat callout.
- Consider adding a "Microsoft 365 Copilot channel" section. Since the ESS agent and many Copilot Studio agents surface in M365 Copilot, readers will want to know what's possible there for the after-submit moment. The key question to answer definitively: does the
Action.Execute+ verb refresh flow work in the M365 Copilot channel, or is it Teams-only? Happy to help verify from the docs.
The rest are smaller structural / front-matter / sourcing items. Nice work — this is close.
| title: "Disabling Adaptive Cards After Submission in Copilot Studio Agents" | ||
| date: 2026-06-26 | ||
| categories: [copilot-studio, tutorial] | ||
| agent_edition: both |
There was a problem hiding this comment.
agent_edition should be classic here, not both. This is classic-agent authoring (Send a message node, listener topic, invoke schema), and Adaptive Cards are a classic capability.
| date: 2026-06-26 | ||
| categories: [copilot-studio, tutorial] | ||
| agent_edition: both | ||
| tags: [adaptive-cards, teams, webchat, universal-actions, ux, action-execute, botframework] |
There was a problem hiding this comment.
Two small tag tweaks to strengthen the auto-generated "Further Reading": botframework → bot-framework (that's the spelling the WebChat middlewares post you link uses, so the two posts will cross-link), and consider user-experience instead of ux for the same overlap reason.
| author: mmonisha | ||
| image: | ||
| path: /assets/posts/disable-adaptive-cards-after-submission/header.png | ||
| alt: "A glowing blue Adaptive Card form streams into a green 'Response recorded' card sealed with a lock, under the title 'Adaptive Cards: Disable After Submit' with WebChat and Microsoft Teams badges. No more accidental double submits." |
There was a problem hiding this comment.
Heads up: on this blog the header image.alt is also rendered as the visible caption under the image, so this literal description of the artwork reads a little oddly in that spot. House style uses a short, whimsical subtitle about the topic (e.g. "Sometimes even saying hello is too much."). Something like: "You clicked Submit. The card got it, it just forgot to say so."
There was a problem hiding this comment.
Ah, didn't realize the alt renders as the caption. Fixing it now.
|
|
||
| ## Pattern 1: Custom Web Portals (BotFramework-WebChat) | ||
|
|
||
| > This pattern works for agents embedded in custom web portals or Employee Self Service (ESS) pages using the BotFramework-WebChat SDK. |
There was a problem hiding this comment.
We need to make a distinction between M365 ESS (the product) and just any self service portal
There was a problem hiding this comment.
I'll reword this and another callout below to say "custom web portals or self-service pages you build and embed with the BotFramework-WebChat SDK," and explicitly note this is not the Microsoft 365 Employee Self-Service agent, which runs in the M365 Copilot channel where you don't control the client, so this client-side pattern can't apply there.
|
|
||
| ### The core logic | ||
|
|
||
| The middleware intercepts every card render and compares the activity to the latest message in the store: |
There was a problem hiding this comment.
Tiny precision nit: since this excerpt is trimmed to just the adaptive case (the other card types fall through to default), "intercepts every card render" is slightly off — "intercepts adaptive card renders" is truer to the code shown. The full sample does handle all 9 card types identically, so nothing wrong with the logic.
| /> | ||
| ``` | ||
|
|
||
| > This is a **client-side** solution. It prevents resubmission in the UI but doesn't enforce it server-side. For most ESS scenarios, this is sufficient. |
There was a problem hiding this comment.
Same "ESS" issue as the WebChat callout above
|
|
||
| ```json | ||
| { | ||
| "type": "ActionSet", |
There was a problem hiding this comment.
Optional: this Action.Execute block and the replacement-card JSON further down (~L207) both run past ~20 lines. Per the review guide, long JSON reads better tucked into a collapsible <details> — note it needs <pre><code> inside, since markdown fences don't render within <details>.
|
|
||
| ### Step 2: Send with a "Send a message" node | ||
|
|
||
| In Copilot Studio, use a **Send a message** node with the Adaptive Card JSON. Don't use the "Ask with Adaptive Card" node. That node uses `Action.Submit` internally and won't trigger the invoke/refresh flow. |
There was a problem hiding this comment.
Could we link the docs for these two nodes? A Copilot Studio Learn link for the "Send a message" node (and for the "Ask with Adaptive Card" node) would help readers who haven't used them — the review bar asks for MS Docs links on each product feature / config step.
| > Test this in Teams directly, not the Copilot Studio test canvas. The invoke/refresh flow may not work in the test panel. | ||
| {: .prompt-warning } | ||
|
|
||
| The complete walkthrough with screenshots is in [Nghiem Doan's repo](https://github.com/nghiemdoan-msft/AdaptiveCardInCopilotStudio). |
There was a problem hiding this comment.
Rather than point readers to a personal repo for the full walkthrough, let's publish an equivalent sample under microsoft/CopilotStudioSamples (which we own) and link that instead — so the reference doesn't depend on an individual's repo staying put. The WebChat link above is fine, since it points to the Microsoft-owned BotFramework-WebChat repo.
There was a problem hiding this comment.
Makes sense. I'll publish an equivalent walkthrough under CopilotStudioSamples and point the link there instead.
|
|
||
| The complete walkthrough with screenshots is in [Nghiem Doan's repo](https://github.com/nghiemdoan-msft/AdaptiveCardInCopilotStudio). | ||
|
|
||
| ## Comparing the two patterns |
There was a problem hiding this comment.
I'd drop this "Comparing the two patterns" section entirely. The two patterns aren't really alternatives — the channel decides which you use (web → middleware, Teams → Universal Actions), so a feature-by-feature comparison implies a choice the reader doesn't actually have. The "Two patterns, two channels" table up top already maps channel → pattern. Bonus: removing it also clears the ❌/✅ emoji (house style avoids emoji) and the overlap with "Key takeaways" right below.
| | Channel | Pattern | Mechanism | | ||
| |---|---|---| | ||
| | Web portals (WebChat) | Attachment middleware | Disable card client-side | | ||
| | Microsoft Teams | Universal Actions | Replace card server-side | |
There was a problem hiding this comment.
We should also mention m365, even if no workaround is available
|
Thanks so much, adilei. You're right on both blockers, and I've got a definitive answer on the M365 Copilot question: I'm reworking the post to (1) fix the ESS references so they don't imply the WebChat pattern applies to the M365 Employee Self-Service agent, and (2) add a short "Microsoft 365 Copilot channel" section that answers the after-submit question head-on: neither pattern applies there today (no client control, and Action.Execute cards aren't supported), so the practical guidance is to keep cards informational or collect input another way. |
New post: Disabling Adaptive Cards After Submission in Copilot Studio Agents
Adds a tutorial on a common UX gap: Adaptive Card forms stay interactive after a user submits, inviting accidental resubmissions. The post covers two channel-specific patterns:
Action.Execute+ verb + listener topic) that replace the card server-side with a confirmation.It includes a comparison table, a Mermaid sequence diagram, complete code samples, and
fallbackguidance for graceful degradation.Included
_posts/2026-06-11-disable-adaptive-cards-after-submission.md(agent_edition: both)assets/posts/disable-adaptive-cards-after-submission/header.pngmmonishain_data/authors.ymlValidation
bundle exec jekyll buildpasses locallypost_urllinks resolve (adaptive-card-generation, copilot-studio-teams-agent-patterns, webchat-middlewares)