Repository navigation
feat(channels): carry the sender's display name; keep a LID sender a LID - #50
Conversation
ChannelMessage gains sender_name: Option<String>, the name the platform gives for the sender: the WhatsApp Web push name, the WhatsApp Cloud contacts[].profile.name of the sender's wa_id, Telegram's first and last name (else the username), and Signal's sourceName. Never a saved contact name: no channel exposes one. It is serde-defaulted and skipped when None, so hosts and modules built before it still decode each other's messages; the wire contract version stays 1 (is_compatible is an exact match, so a bump would stop old hosts binding the new module). The envelope maps it to and from SenderRef.name, which both projections used to drop. ChannelMessage now derives Default, so a caller can spread ..Default::default(). WhatsApp Web: a LID-addressed sender was rendered as +<lid>, which looks like a phone number and, as a DM reply target, became a phone JID of the LID's digits. It is now the phone that came with the message (sender_alt) when there is one, else the LID JID itself (<lid>@lid). The allow-list still accepts the old +<lid> form.
Tiny Sweeper reviewTiny Sweeper reviewed this change across 6 lane(s) and found 0 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below. State: Ready for maintainer review Review snapshot
Completeness: Complete What changedThe review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below. FeaturesNone identified with supported citations. TestsNo supported feature-to-test mapping was produced. Test execution is not inferred. FindingsNo active actionable findings. Before mergeNone. How this fits togetherflowchart LR
n0["message<br/>changed"]:::changed
n1["ChannelMessage<br/>changed"]:::changed
n0 -->|uses| n1
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Comment |
There was a problem hiding this comment.
tinysweeper found nothing blocking. Approving.
$0.0663 · 533,034 in / 23,595 out · 73,722 cached (14%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0266 · 243,754 in / 10,461 out · 43,047 cached (18%) · gpt-5.6-luna
security: $0.0393 · 251,457 in / 8,874 out · 30,547 cached (12%) · gpt-5.6-luna
tests: $0.0001 · 12,319 in / 377 out · 64 cached (1%) · glm-5.3-flash
description: $0.0001 · 12,868 in / 281 out · 64 cached (0%) · glm-5.3-flash
Summary
ChannelMessagegainssender_name: Option<String>: the sender's display name as the platform gives it. OpenHuman will store it as the name of the person a channel memory is about.info.push_name).value.contacts[].profile.nameof the contact whosewa_idis the message'sfrom.senderstays the username or id).sourceName.None. No channel exposes the user's saved contact name, so none is synthesised.SenderRef.name; both projections used to drop it.ChannelMessagenow derivesDefault, so callers can spread..Default::default()and keep compiling when an optional field is added.lidserver (WhatsApp's privacy identifier) is now the phone that came with the message (sender_alt), else the LID JID itself (<lid>@lid). It used to be rendered as+<lid>.API Or Behavior Changes
ChannelMessage, plusDefault. Every struct literal ofChannelMessagewithout a..spread must addsender_name: None(or switch to..Default::default()). That's 27 literals in this repo, all updated, and about 44–46 in OpenHuman, to be done in the OpenHuman pin bump.RuntimeChannelMessageis unchanged, so OpenHuman'sRuntimeChannelMessage { message, inbound_envelope }destructuring is unaffected.sender_nameis#[serde(default, skip_serializing_if = "Option::is_none")], andChannelMessagehas nodeny_unknown_fields. A host or module built before this field decodes a newer message (the field is ignored), and a newer one decodes an older message (None). Test:the_sender_name_is_optional_on_the_wire.1).is_compatibleis an exact match (crates/tinychannels-bus/src/version.rs), so a bump would stop every older host binding the new module, for a change that is wire-compatible both ways. Nothing in the module ↔ host binding forces the two to move together:tinychannels-moduleonly importsis_compatible/CONTRACT_VERSION, and OpenHuman's module record pins a release, not a contract range. The source-linked crate and the lazily loaded module can therefore be bumped independently.sender_identityinproviders/whatsapp_web.rs):+<number>.senderand the DM reply target are+<phone>.senderand the DM reply target are<lid>@<server>(e.g.98765432101234@lid), not+<lid>.recipient_to_jid("+<lid>"), i.e.Jid::pn(<lid>), a phone JID made of the LID's digits that isn't this person. It now goes to the LID JID (or the real phone). That misrouting was inferred from the code (compute_reply_target,recipient_to_jid), not observed live.allowed_numbersstill matches the old+<lid>form, plus+<phone>when known, so existing configs keep matching. The outbound gate already normalises a<lid>@lidtarget to+<lid>.redact_recipient, which handles both forms.Tests
Not run locally (team rule: CI runs every check; no local builds).
cargo fmt --allwas run. The CI here runs clippy, build and test both default and--all-features(thewhatsapp-webfeature included). M3gA-Mind fork PRs to this repo do get CI (e.g. #37).New tests:
crates/tinychannels-bus/src/channel/mod_tests.rs:the_sender_name_survives_the_envelope_both_ways,the_sender_name_is_optional_on_the_wire.src/providers/whatsapp_web_tests.rs:a_phone_addressed_sender_is_its_number,a_lid_sender_with_its_phone_is_the_phone,a_lid_sender_alone_stays_a_lid_jid_not_a_phone(the latter asserts the reply target parses to a LID-family JID).src/providers/whatsapp_tests.rs:whatsapp_parse_takes_the_senders_profile_name,whatsapp_parse_without_contacts_has_no_name.src/providers/telegram/channel_tests.rs:telegram_sender_name_is_first_and_last_name,telegram_sender_name_falls_back_to_username_then_none.src/providers/signal_tests.rs:process_envelope_carries_the_profile_name,sse_envelope_reads_source_name.cargo fmt --check(rancargo fmt --all)cargo clippy --all-targets -- -D warnings: CIcargo clippy --all-targets --all-features -- -D warnings: CIcargo build --all-targets: CIcargo build --all-targets --all-features: CIcargo test: CIcargo test --all-features: CIDocumentation
The rustdoc on
ChannelMessage.sender_nameandWhatsAppWebChannel::sender_identitydescribes the fields and the LID rule. No spec underdocs/listsChannelMessagefields, so none needed changing.