Exclude Gmail send-as aliases from received-message participants#2856
Merged
Conversation
…participants A received 1:1 email delivered to a Gmail send-as alias (not the primary account.email) kept the alias as a second participant, so findUnansweredTribeThreads treated it as a group thread and never produced an outreach nudge. Fetch and persist the account's send-as aliases on sync and exclude the whole owner-address set when normalizing received participants. Closes #2831
# Conflicts: # .changelog/NEXT.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a Tribe-outreach gap where a genuinely unanswered 1:1 email delivered to one of the owner's Gmail send-as aliases (rather than the primary
account.email) was never surfaced as an outreach nudge.In
messageActivityCandidates, a received message's participants were computed as[from, ...to, ...cc]filtered to drop onlyaccount.email. When a 1:1 message was delivered to a send-as alias, the alias survived the filter, so the message had two counterparts (sender + owner alias) andfindUnansweredTribeThreadstreated it as a group thread and skipped it. The prior #2796 alias handling only covered the SENT direction (via Gmail'sSENTlabel); the received-to-alias case was unhandled, and the account stored only a singleemailto filter against.Changes
messageGmailSync.jscallsgmail.users.settings.sendAs.liston each sync (best-effort; anullsentinel on failure keeps the stored set rather than clobbering it). Persisted onto the account assendAsAliases(lowercased, deduped) via a newupdateSendAsAliasesinmessageAccounts.js.messageActivityCandidatesnow builds an owner-address set of{ selfEmail, ...sendAsAliases }and excludes all of them from received-message participants. The existingSENT-label direction logic is unchanged.sendAsAliasesdegrades to today's behavior (filter on primary email only); missing/failed alias fetch never crashes and produces no false person records. Additive account field, no migration needed.routes/messages.js) extended with the additivesendAsAliasesarray for parity.Follow-up
ON CONFLICT DO NOTHINGinsert contract leaves already-stored rows with stale participants until they age out of the 14-day window; split out to avoid changing the global dedup semantics). Surfaced by codex review.Test plan
server/services/humanActivity.test.js— new cases: a received 1:1 delivered to an alias stays a single-counterpart 1:1; back-compat (no aliases stored → only primary email filtered).server/services/messageGmailSync.test.js— newfetchSendAsAliasescases: lowercased aliases returned, empty array vsnullsentinel on API failure.humanActivity,messageGmailSync,messageSync,messageAccounts,routes/messages— 149 tests).Closes #2831