Skip to content

Route threaded replies through Bot Framework reply endpoint - #586

Open
Mehak Bindra (MehakBindra) wants to merge 4 commits into
mainfrom
mehakbindra-python-threading-endpoints
Open

Route threaded replies through Bot Framework reply endpoint#586
Mehak Bindra (MehakBindra) wants to merge 4 commits into
mainfrom
mehakbindra-python-threading-endpoints

Conversation

@MehakBindra

Copy link
Copy Markdown
Member

Summary

  • route L2 group-chat and channel placement through POST /v3/conversations/{conversationId}/activities/{rootMessageId} while retaining L1 sends
  • preserve proactive callers by translating valid legacy ;messageid= conversation IDs internally
  • expose typed, read-only inbound channelData.thread.id and apply the reactive personal/group-chat/channel scope matrix
  • deprecate legacy threaded-ID and quote/reply conveniences without changing their runtime behavior; explicit quote metadata remains available through MessageActivityInput.add_quote()
  • update the interacting-with-messages sample and add focused endpoint, routing, metadata, and fallback coverage

Validation

  • uv run poe check
  • uv run pyright
  • affected API/apps tests (236 passed)
  • focused final threading regressions (27 passed)
  • uv build --all-packages
  • echo app startup scenario

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 1, 2026 19:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

App.reply() currently rejects non-numeric thread root IDs, which blocks proactive thread placement for valid non-numeric roots (e.g., IDs coming from inbound channelData.thread.id / activity IDs).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the Teams Python SDK’s outbound message routing so that threaded placement (L2 group-chat and channel threads) uses the Bot Framework reply endpoint (POST /v3/conversations/{conversationId}/activities/{rootMessageId}) while keeping L1 sends on the standard create-activity endpoint. It also preserves compatibility for proactive callers that still pass legacy ;messageid=-suffixed conversation IDs by translating them internally.

Changes:

  • Add thread_root_id routing to the shared send path and route replies via conversations.reply_to_activity(...) when present.
  • Introduce parsing for legacy ;messageid= conversation IDs and use inbound channelData.thread.id (typed as ThreadInfo) to determine reactive thread placement.
  • Update API client reply behavior to use the reply endpoint (path-based root ID) and adjust examples/tests accordingly.
File summaries
File Description
packages/apps/tests/test_app.py Updates app-level tests to assert reply endpoint usage and legacy ID translation behavior.
packages/apps/tests/test_activity_context.py Adds coverage for reactive thread placement matrix (personal vs groupChat vs channel).
packages/apps/src/microsoft_teams/apps/utils/thread.py Adds legacy threaded conversation ID parsing and deprecates to_threaded_conversation_id.
packages/apps/src/microsoft_teams/apps/utils/init.py Keeps exporting deprecated threading helper with pyright suppression.
packages/apps/src/microsoft_teams/apps/routing/activity_context.py Computes thread root from inbound metadata / legacy suffix and threads sends via new routing.
packages/apps/src/microsoft_teams/apps/app.py Translates legacy suffixed IDs for proactive sends and adds explicit thread-root send path.
packages/apps/src/microsoft_teams/apps/activity_send.py Routes non-targeted sends via reply endpoint when thread_root_id is provided.
packages/apps/src/microsoft_teams/apps/init.py Maintains deprecated threading helper export with pyright suppression.
packages/api/tests/unit/test_empty_inbound_objects.py Adds test ensuring inbound channelData.thread.id is typed and read-only.
packages/api/tests/unit/test_conversation_client.py Updates unit tests to validate reply endpoint URL and payload semantics (no replyToId).
packages/api/src/microsoft_teams/api/models/channel_data/thread_info.py Introduces ThreadInfo model for inbound thread metadata.
packages/api/src/microsoft_teams/api/models/channel_data/channel_data.py Adds `ChannelData.thread: ThreadInfo
packages/api/src/microsoft_teams/api/models/channel_data/init.py Exports ThreadInfo.
packages/api/src/microsoft_teams/api/clients/conversation/activity.py Changes activities.reply(...) to POST to /activities/{activity_id} without replyToId in payload.
examples/interacting-with-messages/src/threading_handlers.py Updates sample to use app.reply(...) and inbound thread metadata rather than legacy threaded IDs.
examples/interacting-with-messages/README.md Updates sample documentation to reflect deprecations and new thread-manual behavior.
Review details
  • Files reviewed: 16/16 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/apps/src/microsoft_teams/apps/app.py
@MehakBindra
Mehak Bindra (MehakBindra) marked this pull request as draft September 1, 2026 20:10
@MehakBindra
Mehak Bindra (MehakBindra) marked this pull request as ready for review September 1, 2026 20:25
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a61da459-b09d-412b-9dd1-1310f6dfd42d
return True


def _thread_reference(ctx: ActivityContext[MessageActivity]) -> tuple[str, str]:

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.

should we consider offering this as apart of the SDK? vs having them write a helper fn

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a61da459-b09d-412b-9dd1-1310f6dfd42d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a61da459-b09d-412b-9dd1-1310f6dfd42d
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.

3 participants