fix(msteams): include tenantId and aadObjectId on proactive sends (#58774)#63949
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6858d9ed6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| aadObjectId?: string; | ||
| /** Team ID for channel messages (when available). */ | ||
| teamId?: string; |
There was a problem hiding this comment.
Restore threadId on StoredConversationReference
This change drops threadId from StoredConversationReference, but thread handling still writes and reads it (monitor-handler/message-handler.ts and messenger.ts rely on it for channel thread routing/fallback). That leaves the contract inconsistent and causes type errors where threadId is accessed, while also making it easy for future call sites to lose thread-root metadata and regress threaded replies.
Useful? React with 👍 / 👎.
| ...(tenantId ? { tenantId } : {}), | ||
| ...(aadObjectId ? { aadObjectId } : {}), |
There was a problem hiding this comment.
Preserve tenant and AAD IDs across sparse inbound activities
The new fields are only emitted when truthy (...(tenantId ? ...), ...(aadObjectId ? ...)), but store upserts replace the reference object and only preserve timezone in mergeStoredConversationReference. If a later activity in the same conversation arrives without channelData.tenant.id or from.aadObjectId, this code clears previously captured IDs, so subsequent proactive sends can again omit required tenant/AAD metadata and hit 403.
Useful? React with 👍 / 👎.
Greptile SummaryThis PR fixes HTTP 403 on proactive Teams sends by capturing Confidence Score: 5/5Safe to merge; the fix is well-scoped, backward-compatible, and the remaining finding is a minor hardening suggestion. All findings are P2 or lower. The only concern is that the outbound extensions/msteams/src/sdk.ts — the Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/msteams/src/sdk.ts
Line: 204-206
Comment:
**`recipient` missing `id` field on proactive sends**
When `recipientAadObjectId` is set, the outbound activity's `recipient` only carries `aadObjectId` and omits `id` (the Teams user ID, e.g. `29:…`). Some Bot Framework connector implementations may expect `recipient.id` to be present alongside `aadObjectId` for personal-DM proactive sends. The user ID is already available from `reference.user?.id` in `continueConversation`.
Consider threading `recipientId` through `createSendContext` alongside `recipientAadObjectId` to avoid a potential gap, even if the current connector accepts `aadObjectId` alone.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(msteams): capture and forward tenant..." | Re-trigger Greptile |
| ...(params.recipientAadObjectId | ||
| ? { recipient: { aadObjectId: params.recipientAadObjectId } } | ||
| : {}), |
There was a problem hiding this comment.
recipient missing id field on proactive sends
When recipientAadObjectId is set, the outbound activity's recipient only carries aadObjectId and omits id (the Teams user ID, e.g. 29:…). Some Bot Framework connector implementations may expect recipient.id to be present alongside aadObjectId for personal-DM proactive sends. The user ID is already available from reference.user?.id in continueConversation.
Consider threading recipientId through createSendContext alongside recipientAadObjectId to avoid a potential gap, even if the current connector accepts aadObjectId alone.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/msteams/src/sdk.ts
Line: 204-206
Comment:
**`recipient` missing `id` field on proactive sends**
When `recipientAadObjectId` is set, the outbound activity's `recipient` only carries `aadObjectId` and omits `id` (the Teams user ID, e.g. `29:…`). Some Bot Framework connector implementations may expect `recipient.id` to be present alongside `aadObjectId` for personal-DM proactive sends. The user ID is already available from `reference.user?.id` in `continueConversation`.
Consider threading `recipientId` through `createSendContext` alongside `recipientAadObjectId` to avoid a potential gap, even if the current connector accepts `aadObjectId` alone.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 631134a8c5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...(existing?.aadObjectId && !incoming.aadObjectId | ||
| ? { aadObjectId: existing.aadObjectId } |
There was a problem hiding this comment.
Preserve aadObjectId only when sender identity matches
mergeStoredConversationReference now carries forward the previous top-level aadObjectId whenever the new activity omits it, but it does this without checking whether incoming.user.id changed. In shared conversations, a sparse activity from a different user can produce a mixed reference (user.id from user B with aadObjectId from user A), and createMSTeamsAdapter then forwards both as recipient metadata on proactive sends. That can generate invalid recipient identity tuples and cause proactive sends to fail or route incorrectly; gate this carry-forward on matching user IDs (or keep user and top-level AAD fields synchronized).
Useful? React with 👍 / 👎.
631134a to
ccbd053
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ccbd053439
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| tenantId, | ||
| recipientId, | ||
| recipientAadObjectId, |
There was a problem hiding this comment.
Restrict recipient identity fields to personal conversations
continueConversation now forwards recipientId/recipientAadObjectId for every conversation type, and createSendContext always emits them on outbound activities. In channel/group proactive sends, reference.user is the last sender rather than the conversation target, so this attaches user-specific recipient metadata to channel posts; Teams only supports aadObjectId routing for personal scope, so channel announcements can be rejected or misrouted. Only set recipient identity fields when conversationType is personal.
Useful? React with 👍 / 👎.
…enclaw#58774) (openclaw#63949) * fix(msteams): capture and forward tenantId/aadObjectId on proactive sends (openclaw#58774) * msteams: preserve tenantId/aadObjectId on sparse merges, thread recipientId on proactive sends
…enclaw#58774) (openclaw#63949) * fix(msteams): capture and forward tenantId/aadObjectId on proactive sends (openclaw#58774) * msteams: preserve tenantId/aadObjectId on sparse merges, thread recipientId on proactive sends
…enclaw#58774) (openclaw#63949) * fix(msteams): capture and forward tenantId/aadObjectId on proactive sends (openclaw#58774) * msteams: preserve tenantId/aadObjectId on sparse merges, thread recipientId on proactive sends
Summary
Fixes HTTP 403 on proactive Teams messages by capturing
tenantIdandaadObjectIdfrom inbound activities and forwarding them on outbound proactive sends.Root cause
The Bot Framework's connector requires
tenantIdandaadObjectIdin the conversation reference for proactive (bot-initiated) sends. The msteams plugin was discarding these from inbound activities, so when cron / scheduled messages tried to send proactively, the resulting connector request was rejected with 403.Fix
tenantIdfromactivity.channelData?.tenant?.idat inbound time (channel activities often leaveconversation.tenantIdunset, sochannelData.tenant.idis the canonical source)aadObjectIdfromactivity.from?.aadObjectIdat inbound timeStoredConversationReferencemessenger.tsand on the Bot Framework connector request insdk.ts(viachannelData.tenant.id,conversation.tenantId, andrecipient.aadObjectId)Fixes #58774
Test plan
channelData.tenant.id, plus graceful degradation whenchannelDatais missing)buildConversationReferenceandsendMSTeamsMessages