Skip to content

Add post: Disabling Adaptive Cards After Submission in Copilot Studio Agents - #336

Open
Monisha Monikantarajan (mmonisha) wants to merge 2 commits into
mainfrom
post/disable-adaptive-cards-after-submission
Open

Add post: Disabling Adaptive Cards After Submission in Copilot Studio Agents#336
Monisha Monikantarajan (mmonisha) wants to merge 2 commits into
mainfrom
post/disable-adaptive-cards-after-submission

Conversation

@mmonisha

Copy link
Copy Markdown

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:

  • WebChat (custom web portals): an attachment middleware that disables the card client-side once it's no longer the latest message.
  • Microsoft Teams: Universal Actions (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 fallback guidance for graceful degradation.

Included

  • _posts/2026-06-11-disable-adaptive-cards-after-submission.md (agent_edition: both)
  • Header image at assets/posts/disable-adaptive-cards-after-submission/header.png
  • New author mmonisha in _data/authors.yml

Validation

  • bundle exec jekyll build passes locally
  • All 3 inline post_url links resolve (adaptive-card-generation, copilot-studio-teams-agent-patterns, webchat-middlewares)
  • References woven inline (no standalone section); 5–8 tags; engagement closing

… 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>
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

Blog preview check passed for 48155ef.

The Jekyll site compiled successfully and generated previews for the newly added post.

  • \_posts/2026\-06\-26\-disable\-adaptive\-cards\-after\-submission\.md -> /mcscatblog/posts/disable\-adaptive\-cards\-after\-submission/

Preview artifacts:

Open the workflow run

… 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 adilei left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. 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.
  2. 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small tag tweaks to strengthen the auto-generated "Further Reading": botframeworkbot-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."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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."

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@adilei adilei Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make a distinction between M365 ESS (the product) and just any self service portal

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@adilei adilei Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same "ESS" issue as the WebChat callout above


```json
{
"type": "ActionSet",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 |

@adilei adilei Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also mention m365, even if no workaround is available

@mmonisha

Copy link
Copy Markdown
Author

Thanks so much, adilei. You're right on both blockers, and I've got a definitive answer on the M365 Copilot question:
The  Action.Execute  + verb refresh flow does not work in the M365 Copilot channel. Per the Copilot Studio Teams/M365 channel docs, "Adaptive Cards with  Action.Execute " is listed under Unsupported node types for Microsoft 365 Copilot. So it's Teams-only.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants