openclaw - ✅(Solved) Fix MSTeams: inline pasted images not downloaded (hostedContents contentBytes missing) [2 pull requests, 2 comments, 3 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#50043Fetched 2026-04-08 00:59:55
View on GitHub
Comments
2
Participants
3
Timeline
8
Reactions
0
Author
Timeline (top)
cross-referenced ×4commented ×2closed ×1locked ×1

Root Cause

The hostedContents collection in the activity attachment doesn't include contentBytes directly. The fix is to download the image via the contentUrl using the bot's auth token instead of relying on the inline content bytes.

Fix Action

Fixed

PR fix notes

PR #50044: fix(msteams): fix inline pasted image downloads

Description (problem / solution / changelog)

Summary

Fixes inline pasted image downloads in MSTeams conversations. The Teams API returns hostedContents attachments without contentBytes, so images are never saved.

Changes

  • Download images via contentUrl using the bot's bearer token when contentBytes is missing
  • Handle both hosted content URLs and direct download URLs
  • Properly extract content type from response headers

Testing

  • Verified on v2026.3.13-1 in DM conversations
  • Without fix: images detected but not saved to disk (0 bytes / missing files)
  • With fix: images correctly downloaded and available for processing

Fixes #50043 Supersedes #10902 (closed by stale bot) Related to #5448 (locked)

Changed files

  • extensions/msteams/src/attachments.test.ts (modified, +52/-0)
  • extensions/msteams/src/attachments.ts (modified, +5/-1)
  • extensions/msteams/src/attachments/download.ts (modified, +27/-2)
  • extensions/msteams/src/attachments/graph.ts (modified, +67/-8)
  • extensions/msteams/src/attachments/shared.ts (modified, +5/-1)
  • extensions/msteams/src/monitor-handler/inbound-media.ts (modified, +71/-45)

PR #10902: fix(msteams): fix inline pasted image downloads

Description (problem / solution / changelog)

Fixes #5448

Problem

Inline pasted images in MS Teams (clipboard paste, not drag-and-drop file attachments) were silently dropped, and the gateway never received the image bytes.

Root Cause

Four independent bugs in the MSTeams extension's media download pipeline:

1. Bot Framework attachment URLs return JSON metadata, not binary content

Teams sends pasted images as attachments with Bot Framework URLs like:

https://smba.trafficmanager.net/.../v3/attachments/{id}

Fetching that bare URL returns a JSON metadata envelope. The binary lives at /views/original:

https://smba.trafficmanager.net/.../v3/attachments/{id}/views/original

Fix: Added isBotFrameworkAttachmentUrl() regex helper and /views/original suffix in download.ts. Trailing slashes are stripped before appending.

2. trafficmanager.net missing from auth host allowlist

fetchWithAuthFallback checks DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST before retrying with a Bearer token on 401 responses. trafficmanager.net (used by smba.trafficmanager.net Bot Framework service URLs) was not listed, so auth fallback was silently skipped.

Fix: Added trafficmanager.net to DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST in shared.ts.

3. Inbound media gate required ALL attachments to be text/html

The HTML-attachment gate used every(), requiring all attachments to be text/html before triggering the Graph API fallback (Tier 2). Teams sends mixed types (image/* + text/html) for pasted images, so the condition never matched.

Fix: Changed every()some() and renamed onlyHtmlAttachmentshasHtmlAttachments in inbound-media.ts.

4. Graph API hostedContents collection returns contentBytes: null

downloadGraphHostedContent only read contentBytes from the collection response, which is always null per Microsoft docs:

Note: contentBytes and contentType are always set to null.

The binary is available via the individual $value endpoint:

GET .../hostedContents/{id}/$value → 200 OK, content-type: image/png, <binary body>

Fix: Added $value endpoint fetch with Bearer auth as fallback when contentBytes is null in graph.ts. Kept the contentBytes fast path in case Microsoft starts populating it in the future.

Changes

FileChange
extensions/msteams/src/attachments/download.tsisBotFrameworkAttachmentUrl() + /views/original URL rewriting
extensions/msteams/src/attachments/shared.tstrafficmanager.net added to auth allowlist
extensions/msteams/src/attachments/graph.ts$value endpoint fetch for hosted content
extensions/msteams/src/monitor-handler/inbound-media.tsevery()some() for HTML gate
extensions/msteams/src/attachments.test.ts4 new tests + updated existing tests
CHANGELOG.mdFix entry

Testing

  • Unit tests: 22/22 pass, including 4 new tests:
    • appends /views/original to Bot Framework attachment URLs
    • uses auth fallback for Bot Framework 401 responses
    • downloads hostedContents images via $value endpoint
    • skips hosted content when $value fetch fails
  • Live test: Pasted image in Teams chat → gateway downloaded (2025×1525 PNG), resized, and dispatched to agent successfully
  • Gate: pnpm build && pnpm check && pnpm test all pass
<!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3>
  • Fixes MSTeams inline pasted image handling by rewriting Bot Framework attachment URLs to fetch binary bytes via /views/original.
  • Expands the media auth allowlist to include trafficmanager.net, enabling Bearer-token retry when Bot Framework URLs return 401/403.
  • Adjusts inbound media Tier-2 (Graph) fallback gating to trigger when any text/html attachment is present (mixed attachment types).
  • Updates Graph hosted content download to fetch bytes from hostedContents/{id}/$value when collection contentBytes is null, with accompanying unit tests.
<h3>Confidence Score: 5/5</h3>
  • This PR is safe to merge with minimal risk.
  • Changes are narrowly scoped to MS Teams media download paths, include targeted unit tests for each regression, and preserve existing behavior via fast paths and allowlist checks.
  • No files require special attention
<!-- greptile_other_comments_section -->

<sub>(4/5) You can add custom instructions or style guidelines for the agent here!</sub>

<!-- /greptile_comment -->

Changed files

  • extensions/msteams/src/attachments.test.ts (modified, +99/-18)
  • extensions/msteams/src/attachments/download.ts (modified, +17/-1)
  • extensions/msteams/src/attachments/graph.ts (modified, +32/-7)
  • extensions/msteams/src/attachments/shared.ts (modified, +2/-0)
  • extensions/msteams/src/monitor-handler/inbound-media.ts (modified, +4/-4)
RAW_BUFFERClick to expand / collapse

Bug

Inline pasted images in MSTeams DM and group conversations are not downloaded. The Teams Graph API returns hostedContents without contentBytes, so the current download logic silently fails.

Reproduction

  1. Configure MSTeams provider
  2. Paste an image inline in a DM conversation with the bot
  3. Image attachment is detected but content is empty/not saved

Root cause

The hostedContents collection in the activity attachment doesn't include contentBytes directly. The fix is to download the image via the contentUrl using the bot's auth token instead of relying on the inline content bytes.

Environment

  • OpenClaw v2026.3.13-1
  • @microsoft/[email protected]
  • Confirmed reproducible on current main

Related

  • Supersedes #5448 (locked/closed as NOT_PLANNED, but bug is still present)
  • Previous fix PR #10902 (closed by stale bot)
  • New fix PR incoming

extent analysis

Fix Plan

To resolve the issue of inline pasted images not being downloaded in MSTeams DM and group conversations, we need to modify the download logic to use the contentUrl from the hostedContents collection.

Steps to Fix

  • Update the MSTeams provider configuration to include authentication tokens for downloading content.
  • Modify the image download logic to use the contentUrl instead of relying on contentBytes.
  • Handle authentication tokens in the download request.

Example Code

// Assuming 'activity' is the object containing 'hostedContents'
const hostedContent = activity.hostedContents[0];
const contentUrl = hostedContent.contentUrl;

// Download image using bot's auth token
const authToken = 'YOUR_BOT_AUTH_TOKEN';
const headers = {
  'Authorization': `Bearer ${authToken}`,
  'Content-Type': 'application/octet-stream'
};

fetch(contentUrl, { headers })
  .then(response => response.arrayBuffer())
  .then(arrayBuffer => {
    const blob = new Blob([arrayBuffer], { type: 'image/png' });
    // Save or process the blob as needed
  })
  .catch(error => console.error('Error downloading image:', error));

Verification

To verify the fix, follow these steps:

  • Configure the MSTeams provider with the updated download logic.
  • Paste an image inline in a DM conversation with the bot.
  • Check if the image is downloaded and saved correctly.

Extra Tips

  • Ensure the bot's auth token has the necessary permissions to download content from the contentUrl.
  • Handle errors and exceptions properly to avoid silent failures.
  • Consider adding logging or monitoring to track image download successes and failures.

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

openclaw - ✅(Solved) Fix MSTeams: inline pasted images not downloaded (hostedContents contentBytes missing) [2 pull requests, 2 comments, 3 participants]