fix(googlechat): keep off-mode replies out of threads#104402
Conversation
Co-authored-by: Jai Govindani <[email protected]> Co-authored-by: Neerav Makwana <[email protected]> Co-authored-by: banddude <[email protected]> Co-authored-by: Novan Adrian <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a7674e7c6
ℹ️ 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".
| - **iOS Share Extension drafts:** preserve legitimate shared text beginning with scaffold-like prefixes, remove only exact legacy scaffold lines, avoid treating scheme-like prose as a URL, and deduplicate host-mirrored content. (#103453) Thanks @lin-hongkuan. | ||
| - **Telegram reasoning previews:** reposition split reasoning previews through deferred deletion so prior preview messages do not remain stale while preserving client scroll position. (#97828) Thanks @ly-wang19. | ||
| - **Feishu native-card threading:** normalize whitespace reply targets once and reuse the shared reply mode for card and media parts so native-card topic replies stay in their thread. (#102804) Thanks @sunlit-deng. | ||
| - **Google Chat reply targeting:** honor default and explicit off modes before creating typing placeholders, replace placeholders when explicit final targets differ, and suppress durable fallback to stale inbound threads. (#89790, #42510) Thanks @jai, @neeravmakwana, @banddude, and @novan. |
There was a problem hiding this comment.
Remove normal-fix changelog entry
For this normal Google Chat fix, adding an Unreleased entry conflicts with the root AGENTS.md changelog rule that CHANGELOG.md is release-only and generated from merged PRs/direct commits. Leaving this in the diff risks duplicate or stale release notes when the release generator rebuilds the changelog; keep the release-note context in the commit/PR text and remove this entry.
Useful? React with 👍 / 👎.
|
Codex review: stale review; fresh review needed. Summary Next step Review history (1 earlier review cycle)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a16f6b70a
ℹ️ 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".
| }); | ||
| typingMessageName = result?.messageName; | ||
| if (result?.messageName) { | ||
| typingMessage = { name: result.messageName, thread: typingMessageThreadName }; |
There was a problem hiding this comment.
Track fallback thread before editing typing message
When Google Chat falls back while creating the typing placeholder, this records the requested thread instead of the thread returned by the API. sendGoogleChatMessage opts into REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD whenever thread is provided and returns threadName from the created message; the official spaces.messages.create docs say that option starts a new thread if replying fails (https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/create). In that fallback case the final payload can still target the original thread, typingMessageThreadName === replyThreadName here, so delivery edits the placeholder that actually lives in the fallback thread instead of deleting it and sending the final reply to the intended thread.
Useful? React with 👍 / 👎.
|
Land-ready proof on exact PR head
The implementation keeps placeholder identity and thread location together, resolves the final thread target once, replaces rather than edits a placeholder when that target changes, and uses the shared explicit-null durable-delivery contract to prevent stale inbound reply metadata from returning. This matches Google Chat's API contract: omitting Live Google Chat service proof is the remaining explicit gap: neither the local profile, the hydrated Testbox, nor repository Actions secrets expose a Google Chat service-account credential or a live Google Chat workflow. No mocked check is represented here as live provider proof. |
|
Merged via squash.
|
* fix(googlechat): align reply and typing targets Co-authored-by: Jai Govindani <[email protected]> Co-authored-by: Neerav Makwana <[email protected]> Co-authored-by: banddude <[email protected]> Co-authored-by: Novan Adrian <[email protected]> * chore(googlechat): leave changelog to release automation * style(googlechat): apply canonical formatting * chore(googlechat): leave changelog to release automation * style(googlechat): keep monitor imports canonical * style(googlechat): keep monitor imports canonical --------- Co-authored-by: Novan Adrian <[email protected]>
Supersedes #89790.
Fixes #42510.
Carries forward focused source work from #74235, #43112, #67055, and #30965.
What Problem This Solves
Fixes an issue where Google Chat users configured with default or explicit
replyToMode: "off"could still see typing placeholders or durable final replies routed into the inbound thread.Why This Change Was Made
The Google Chat monitor now records each typing placeholder together with the thread where it was created, chooses that initial thread from the configured reply mode, and replaces the placeholder when the resolved final target differs. Durable top-level replies pass an explicit null reply target so shared delivery cannot fall back to stale inbound thread metadata.
The single placeholder value replaces the prior parallel optional-name/thread shape, keeping placeholder identity and location consistent through cleanup, edit, and fallback sends.
User Impact
Default and off-mode Google Chat replies remain top-level, while threaded modes and explicit reply directives still target the intended thread. Typing placeholders no longer leave the final answer on a different conversation surface.
Evidence
tbx_01kx8b9hmbtq5nrq4t2snwfc9t.pnpm test extensions/googlechat/src/monitor-durable.test.ts extensions/googlechat/src/monitor.reply-delivery.test.ts extensions/googlechat/src/monitor.test.ts— 3 files, 26 tests passed.pnpm test extensions/googlechat— 20 files, 199 tests passed.pnpm check:changed— extension typechecks, lint, changelog attribution, dependency, import-cycle, and repository guards passed.spaces.messages.createdocumentation: omittingthreadstarts a new thread, while replying to an existing thread requires itsthread.nameplusmessageReplyOption.