Add support for Shared Channels in app templates#453
Conversation
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
@claude update the schema version to 1.25, add schema property "$schema": "{string}", if it doesn't exist. it should point to this https://developer.microsoft.com/json-schemas/teams/v1.25/MicrosoftTeams.schema.json. Ensure that there are no schema validation errors. |
rajan-chari
left a comment
There was a problem hiding this comment.
The supportsChannelFeatures property requires manifest schema v1.25, but all templates still declare v1.20:
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.20/MicrosoftTeams.schema.json",
"manifestVersion": "1.20",These need to be bumped to v1.25 for the new property to pass schema validation:
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.25/MicrosoftTeams.schema.json",
"manifestVersion": "1.25",Also note there was a Developer Portal bug where supportsChannelFeatures silently disappeared on save — reportedly fixed as of March 19, 2026: https://learn.microsoft.com/en-us/answers/questions/5777774/unable-to-save-supportschannelfeatures-in-teams-ap
Test Results:
|
| # | Trigger | Result |
|---|---|---|
| 1 | Bot added to shared channel | ✅ conversationUpdate with eventType: "channelMemberAdded", channel.type: "shared" |
| 2 | Message in shared channel | ✅ message activity received with channel.type: "shared" and full team/channel context |
| 3 | Bot added to private channel | ✅ conversationUpdate with eventType: "channelMemberAdded", channel.type: "private" |
| 4 | Message in private channel | ✅ message activity received with channel.type: "private" and full team/channel context |
| 5 | Message in standard channel | ✅ Works as expected |
Results: v1.20 manifest WITHOUT supportsChannelFeatures (control)
| # | Trigger | Result |
|---|---|---|
| 1 | Manifest update applied | channelMemberRemoved from private channel — Teams actively evicted the bot |
| 2 | @mention in shared channel | ❌ Bot not available to @mention |
| 3 | @mention in private channel | ❌ Bot not available to @mention (removed from channel) |
| 4 | Message in standard channel | ✅ Still works |
Key Finding
supportsChannelFeatures: "tier1" is required for bots to participate in shared and private channels. Removing the property causes Teams to actively remove the bot from those channels. This confirms Mehak's issue.
Blocker: Schema version must be bumped
As flagged in my earlier review, all 11 templates still reference v1.20:
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.20/MicrosoftTeams.schema.json",
"manifestVersion": "1.20",The v1.20 schema has "additionalProperties": false at the root and does not define supportsChannelFeatures. The v1.25 schema does define it (allowed values: "tier1" or null).
This means the PR as-is produces technically invalid manifests — any schema validator will reject supportsChannelFeatures as an unknown property under v1.20. The fix worked in my testing because Teams is lenient about validation, but:
- Teams Developer Portal may strip the property
- Teams Toolkit validation will flag it
- It's incorrect per the schema contract
Must fix: Bump $schema and manifestVersion from v1.20 to v1.25 in all 11 files.
Tested 2026-03-21 on BAMI1 tenant with @microsoft/teams.apps TypeScript SDK
rajan-chari
left a comment
There was a problem hiding this comment.
Schema version bump to v1.25 confirmed across all 10 manifest templates. Both $schema URL and manifestVersion updated. E2E tested — supportsChannelFeatures tier1 works correctly with v1.25 manifests.
…ndling (microsoft#635) ## Summary Ports two merged **teams.py** PRs to TypeScript: - microsoft/teams.py#453 — streaming error handling for the 2-minute timeout & "content stream not allowed" - microsoft/teams.py#495 — support resetting response streams (reuse after `close()`) ## Streaming error handling (port of microsoft#453) - Add `TerminalStreamError`, `StreamTimedOutError`, and `StreamNotAllowedError` (in `types/streamer.ts`). - `HttpStream.send()` now inspects the `403` response body and maps it to the right error instead of always treating a `403` as canceled: - `exceeded streaming time` → `StreamTimedOutError` (marks `timedOut`) - `cancel` → `StreamCancelledError` - `not allowed` → `StreamNotAllowedError` - anything else / empty body → `TerminalStreamError` - On a 2-minute streaming timeout, the stream finalizes by **updating the original message in place** — it drops the `streaminfo` entity and stream `channelData` so the send routes through *update* (reusing the id) rather than posting a duplicate. - Chunk sends swallow a timeout mid-stream; `close()` then sends the buffered content as a plain final message. - `retry` gains a `nonRetryable` option so terminal stream errors are not retried. ## Reusable streams (port of microsoft#495) - Emitting or updating after `close()` reopens the stream on the **same instance**, starting a new streamed message. - `close()` is idempotent until the next emit/update. - `app.process.ts` close listener switched from `once` → `on` so each reused-stream close fires. ## Example Adds `examples/stream`, mirroring the teams.py example's final state: - default message → single-stream demo with suggested actions - `simple-card` → sends a minimal Adaptive Card outside the streaming flow - `multi-stream` → emits an Adaptive Card as stream 1's final message, `close()`s, then reuses `ctx.stream` for a second streamed response ## Tests - `packages/apps` http-stream spec extended: 403 message→error mapping (parametrized), empty-body 403 → terminal error, final-send timeout updates in place, mid-stream timeout updates in place, and emit-after-close stream reuse. - Full `packages/apps` suite passes (294 tests); `tsc` and eslint clean across the changed library files and the new example. ## Notes - The Python-only `uv.lock` change was not ported. - `examples/stream/.env` is gitignored (no credentials committed). --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Summary
"supportsChannelFeatures": "tier1"to the root of all 10 Teams appmanifest.json.hbstemplate filesskip-test-verification