openclaw - ✅(Solved) Fix [Feature]: MS Teams plugin should forward messageBack card actions (Action.Submit) to the agent [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#60952Fetched 2026-04-08 02:45:12
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
labeled ×1

Forward Action.Submit messageBack activities (type="message" with empty text + value object) to the agent instead of dropping them as empty messages.

Root Cause

Forward Action.Submit messageBack activities (type="message" with empty text + value object) to the agent instead of dropping them as empty messages.

Fix Action

Fix / Workaround

Current workaround: We run a sidecar HTTP proxy between the Cloudflare tunnel and OpenClaw that buffers the request body, detects the messageBack pattern, sends HTTP 200 to Teams immediately, rewrites the activity text to include the value payload as [CARD_ACTION] {json}, and forwards it to OpenClaw. This works but adds operational complexity (extra container per gateway).

Affected: All Teams bot users using Adaptive Cards with Action.Submit Severity: High — blocks all interactive card workflows Frequency: Every button click on every Adaptive Card Consequence: Interactive cards are unusable; must fall back to text-based prompts or run a sidecar proxy as workaround

PR fix notes

PR #64503: fix(msteams): forward messageBack card actions (Action.Submit) to agent (#60952)

Description (problem / solution / changelog)

Summary

Forward Action.Submit messageBack activities to the agent instead of dropping them as empty messages. Closes #60952.

When a user clicks an Action.Submit button on an Adaptive Card in Teams, the click is sent as a messageBack activity (type="message" with empty text and a value object). The message handler strips mentions, finds empty text, and drops the message with "skipping empty message after stripping mentions." The value payload is never forwarded to the agent.

This change adds a check for activity.value before the empty-text drop at line 452 of message-handler.ts. If the value payload is a non-empty object, it serializes it as [CARD_ACTION] {json} so the agent receives the button payload. This is consistent with:

  • The adaptiveCard/action invoke handling added in #60431 (which handles Action.Execute)
  • The fileConsent/invoke handling added in #64087

The detection pattern: activity.type === "message" && !text && activity.value && typeof activity.value === "object"

Test plan

  • Send an Adaptive Card with Action.Submit buttons to a Teams DM
  • Click a button — verify the agent receives [CARD_ACTION] {"key":"value"} as the message body
  • Verify normal text messages still work (no regression)
  • Verify empty messages are still dropped (no spurious forwarding)
  • Verify Action.Execute invoke path (#60431) is unaffected

Context

This is the companion fix to #55384/#60431 (Action.Execute). Together they cover both invoke formats Teams uses for Adaptive Card interactions. We've been running a sidecar HTTP proxy workaround for this since March 2026 — this fix eliminates the need for that sidecar for card actions.

🤖 Generated with Claude Code

Changed files

  • extensions/msteams/src/monitor-handler.adaptive-card.test.ts (modified, +140/-0)
  • extensions/msteams/src/monitor-handler/message-handler.ts (modified, +20/-1)

Code Example

const text = stripMSTeamsMentionTags(activity.text || '').trim();
if (!text && activity.value && typeof activity.value === 'object') {
  // This is a messageBack card action — forward to agent with value payload
  // Option A: Serialize value into text: "[CARD_ACTION] {json}"
  // Option B: Forward as-is and let the agent framework access activity.value
}
RAW_BUFFERClick to expand / collapse

Summary

Forward Action.Submit messageBack activities (type="message" with empty text + value object) to the agent instead of dropping them as empty messages.

Problem to solve

When a user clicks an Action.Submit button on an Adaptive Card in Teams, the click is sent as a messageBack activity (type="message" with empty text and a value object containing the button payload). The msteams plugin strips mentions, finds empty text, and drops the message with "skipping empty message after stripping mentions." The value payload is never forwarded to the agent.

This is distinct from the adaptiveCard/action invoke fixed in #60431 — that PR handles Action.Execute (type="invoke"). However, the majority of Adaptive Cards use Action.Submit, which Teams sends as messageBack, not an invoke.

Without this, interactive cards (confirmations, approvals, form submissions, RAG status updates) cannot work. Bots must fall back to conversational text prompts.

Proposed solution

In the message handler, before dropping empty-text messages, check if activity.value is present:

const text = stripMSTeamsMentionTags(activity.text || '').trim();
if (!text && activity.value && typeof activity.value === 'object') {
  // This is a messageBack card action — forward to agent with value payload
  // Option A: Serialize value into text: "[CARD_ACTION] {json}"
  // Option B: Forward as-is and let the agent framework access activity.value
}

The detection pattern is: activity.type === "message" && !activity.text.trim() && activity.value && typeof activity.value === "object"

This should be checked before the "skipping empty message" branch.

Alternatives considered

Current workaround: We run a sidecar HTTP proxy between the Cloudflare tunnel and OpenClaw that buffers the request body, detects the messageBack pattern, sends HTTP 200 to Teams immediately, rewrites the activity text to include the value payload as [CARD_ACTION] {json}, and forwards it to OpenClaw. This works but adds operational complexity (extra container per gateway).

Action.OpenUrl fallback: Using Action.OpenUrl instead of Action.Submit opens a browser — poor UX and not suitable for inline confirmations.

Conversational fallback: Agent displays options as text, user types a number. Works but defeats the purpose of Adaptive Cards.

Impact

Affected: All Teams bot users using Adaptive Cards with Action.Submit Severity: High — blocks all interactive card workflows Frequency: Every button click on every Adaptive Card Consequence: Interactive cards are unusable; must fall back to text-based prompts or run a sidecar proxy as workaround

Evidence/examples

Related: Issue 55384 / PR 60431 fixed adaptiveCard/action invoke (Action.Execute). This issue covers Action.Submit messageBack, a different and more commonly used activity pattern. Environment: OpenClaw latest, msteams stock plugin, Azure Bot Single Tenant, Adaptive Card schema 1.5.

Additional information

The relevant code is in extensions/msteams/src/monitor-handler.ts. The fix should add a value-object check before the empty-text drop logic. This is the companion issue to 55384 — together they cover both invoke formats Teams uses for Adaptive Card interactions.

extent analysis

TL;DR

Check for the presence of activity.value before dropping empty-text messages to forward Action.Submit messages from Adaptive Cards to the agent.

Guidance

  • Modify the message handler to check for activity.value before dropping empty-text messages, using the detection pattern activity.type === "message" && !activity.text.trim() && activity.value && typeof activity.value === "object".
  • Consider serializing the activity.value into the text or forwarding it as-is to let the agent framework access it.
  • Review the monitor-handler.ts file in extensions/msteams/src to implement the fix.
  • Test the modified message handler with Adaptive Cards using Action.Submit to verify that the value payload is correctly forwarded to the agent.

Example

const text = stripMSTeamsMentionTags(activity.text || '').trim();
if (!text && activity.value && typeof activity.value === 'object') {
  // Forward to agent with value payload
  // Option A: Serialize value into text: "[CARD_ACTION] {json}"
  // Option B: Forward as-is and let the agent framework access activity.value
}

Notes

The proposed solution aims to address the issue of dropping empty-text messages from Adaptive Cards with Action.Submit. However, the implementation details may vary depending on the specific requirements of the agent framework and the desired handling of activity.value.

Recommendation

Apply the proposed solution by modifying the message handler to check for activity.value before dropping empty-text messages, as it directly addresses the issue and provides a more seamless experience for users interacting with Adaptive Cards.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING