Skip to content

feat: populate contacts from message senders automatically#9

Open
Edouard-m-333 wants to merge 1 commit into
dgrr:mainfrom
Edouard-m-333:feat/auto-populate-contacts-from-senders
Open

feat: populate contacts from message senders automatically#9
Edouard-m-333 wants to merge 1 commit into
dgrr:mainfrom
Edouard-m-333:feat/auto-populate-contacts-from-senders

Conversation

@Edouard-m-333

Copy link
Copy Markdown

Problem

contacts is only populated from the address book (dialog peers and contacts.* lookups). The sender of a message from someone not in your address book — common in groups/supergroups — has no stored name, so message output and SQL analytics fall back to user:<id>. The name can't be recovered later from a bare numeric id, because resolving a user requires its access_hash.

Change

Every fetched message and every real-time update already carries its sender as a Peer, but only the bare id was retained. This upserts the sender into contacts at each point a message is processed — no extra API calls, no schema change, no new dependencies:

  • daemon (src/cmd/daemon.rs): each incoming NewMessage upserts its sender → contacts stay current in real time.
  • sync (src/app/sync.rs): the three message paths (sync, sync_msgs, deep fetch) upsert the senders of messages they pull. Adds a SenderContact field on FetchedMessage and a small sender_contact_from_peer helper.
  • chats members (src/cmd/chats.rs): persists every participant it lists (also covers members who haven't posted).

All four reuse the existing idempotent Store::upsert_contact, whose ON CONFLICT … DO UPDATE uses COALESCE/non-empty guards, so a good value is never overwritten with an empty one. Failures are best-effort (logged in the daemon, ignored elsewhere) so contact population never breaks message storage.

Testing

  • cargo build --release — clean.
  • Ran the daemon, sync / sync msgs, and chats members against a live account: group senders that previously showed as user:<id> now resolve to names in contacts; re-runs are idempotent and don't clobber existing names.

Previously `contacts` was only filled from the address book (dialog peers
and `contacts.*` lookups). The sender of a message from someone not in the
address book — common in groups/supergroups — had no stored name, so
output and analytics fell back to `user:<id>`. The name cannot be recovered
later from a bare numeric id, because resolving a user requires its
access_hash.

Every fetched message and every real-time update already carries its sender
as a `Peer`, but only the bare id was kept. This upserts the sender into
`contacts` wherever a message is processed, at no extra API cost:

- daemon: each incoming message upserts its sender (real-time).
- sync: the three message-sync paths upsert senders of fetched messages.
- chats members: persists every listed participant (incl. silent members).

All reuse the existing idempotent Store::upsert_contact (COALESCE merge),
so a good value is never overwritten with an empty one. No new dependencies
and no schema change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant