Skip to content

Commit e3ed5c0

Browse files
johnsideserfclaude
andcommitted
Fix @mention UUID resolution from message envelopes and group members
@mentions showed truncated UUIDs when the mentioned contact wasn't in the listContacts response. Now uuid_to_name is also populated from incoming message sourceUuid fields and group member data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7ecff66 commit e3ed5c0

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/app.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,6 +3736,12 @@ impl App {
37363736
if let Some(ref name) = msg.source_name {
37373737
self.contact_names.entry(msg.source.clone()).or_insert_with(|| name.clone());
37383738
}
3739+
// Populate UUID->name for @mention resolution
3740+
if let (Some(ref uuid), Some(ref name)) = (&msg.source_uuid, &msg.source_name) {
3741+
if !name.is_empty() {
3742+
self.uuid_to_name.entry(uuid.clone()).or_insert_with(|| name.clone());
3743+
}
3744+
}
37393745
}
37403746

37413747
// Resolve conversation name: prefer message metadata, then contact lookup, then raw ID
@@ -4687,6 +4693,14 @@ impl App {
46874693
for (phone, uuid) in &group.member_uuids {
46884694
self.number_to_uuid.entry(phone.clone()).or_insert_with(|| uuid.clone());
46894695
}
4696+
// Populate UUID->name from group members (phone->uuid + phone->name)
4697+
for (phone, uuid) in &group.member_uuids {
4698+
if let Some(name) = self.contact_names.get(phone) {
4699+
if !name.is_empty() {
4700+
self.uuid_to_name.entry(uuid.clone()).or_insert_with(|| name.clone());
4701+
}
4702+
}
4703+
}
46904704
// Store group for @mention member lookup
46914705
self.groups.insert(group.id.clone(), group.clone());
46924706
// Groups are always "active" (you're a member), so create conversations
@@ -7146,6 +7160,7 @@ mod tests {
71467160
let msg = SignalMessage {
71477161
source: "+15551234567".to_string(),
71487162
source_name: None,
7163+
source_uuid: None,
71497164
timestamp: chrono::Utc::now(),
71507165
body: Some("hey".to_string()),
71517166
attachments: vec![],
@@ -7177,6 +7192,7 @@ mod tests {
71777192
let msg = SignalMessage {
71787193
source: "+1".to_string(),
71797194
source_name: Some("Alice".to_string()),
7195+
source_uuid: None,
71807196
timestamp: chrono::Utc::now(),
71817197
body: Some("hi".to_string()),
71827198
attachments: vec![],
@@ -7216,6 +7232,7 @@ mod tests {
72167232
let msg = SignalMessage {
72177233
source: "+1".to_string(),
72187234
source_name: None,
7235+
source_uuid: None,
72197236
timestamp: chrono::Utc::now(),
72207237
body: Some("hello!".to_string()),
72217238
attachments: vec![],
@@ -7249,6 +7266,7 @@ mod tests {
72497266
let msg = SignalMessage {
72507267
source: "+1".to_string(),
72517268
source_name: Some("Alice".to_string()),
7269+
source_uuid: None,
72527270
timestamp: chrono::Utc::now(),
72537271
body: Some("hey family".to_string()),
72547272
attachments: vec![],
@@ -7283,6 +7301,7 @@ mod tests {
72837301
let msg = SignalMessage {
72847302
source: "+1".to_string(),
72857303
source_name: Some("Alice".to_string()),
7304+
source_uuid: None,
72867305
timestamp: chrono::Utc::now(),
72877306
body: Some("msg".to_string()),
72887307
attachments: vec![],
@@ -8189,6 +8208,7 @@ mod tests {
81898208
let msg = SignalMessage {
81908209
source: "+1".to_string(),
81918210
source_name: Some("Alice".to_string()),
8211+
source_uuid: None,
81928212
timestamp: chrono::Utc::now(),
81938213
body: Some("hello".to_string()),
81948214
attachments: vec![],
@@ -8282,6 +8302,7 @@ mod tests {
82828302
let msg = SignalMessage {
82838303
source: "+1".to_string(),
82848304
source_name: Some("Alice".to_string()),
8305+
source_uuid: None,
82858306
timestamp: chrono::Utc::now(),
82868307
body: Some("hello".to_string()),
82878308
attachments: vec![],
@@ -8322,6 +8343,7 @@ mod tests {
83228343
let msg = SignalMessage {
83238344
source: "+1".to_string(),
83248345
source_name: Some("Alice".to_string()),
8346+
source_uuid: None,
83258347
timestamp: chrono::Utc::now(),
83268348
body: Some("hello".to_string()),
83278349
attachments: vec![],
@@ -8370,6 +8392,7 @@ mod tests {
83708392
let msg = SignalMessage {
83718393
source: "+1".to_string(),
83728394
source_name: Some("Alice".to_string()),
8395+
source_uuid: None,
83738396
timestamp: chrono::Utc::now(),
83748397
body: Some("hello".to_string()),
83758398
attachments: vec![],
@@ -8759,6 +8782,7 @@ mod tests {
87598782
let msg = SignalMessage {
87608783
source: "+1".to_string(),
87618784
source_name: Some("Alice".to_string()),
8785+
source_uuid: None,
87628786
timestamp: chrono::Utc::now(),
87638787
body: Some("\u{FFFC} check this".to_string()),
87648788
attachments: vec![],
@@ -8923,6 +8947,7 @@ mod tests {
89238947
let msg1 = SignalMessage {
89248948
source: "+15551234567".to_string(),
89258949
source_name: Some("Alice".to_string()),
8950+
source_uuid: None,
89268951
timestamp: chrono::Utc::now(),
89278952
body: Some("first".to_string()),
89288953
attachments: vec![],
@@ -8950,6 +8975,7 @@ mod tests {
89508975
let msg2 = SignalMessage {
89518976
source: "+15551234567".to_string(),
89528977
source_name: Some("Alice".to_string()),
8978+
source_uuid: None,
89538979
timestamp: chrono::Utc::now(),
89548980
body: Some("second".to_string()),
89558981
attachments: vec![],
@@ -8979,6 +9005,7 @@ mod tests {
89799005
let msg = |body: &str, ts_ms: i64| SignalMessage {
89809006
source: "+15551234567".to_string(),
89819007
source_name: Some("Alice".to_string()),
9008+
source_uuid: None,
89829009
timestamp: DateTime::from_timestamp_millis(ts_ms).unwrap(),
89839010
body: Some(body.to_string()),
89849011
attachments: vec![],
@@ -9016,6 +9043,7 @@ mod tests {
90169043
let msg = |body: &str, ts_ms: i64| SignalMessage {
90179044
source: "+15551234567".to_string(),
90189045
source_name: Some("Alice".to_string()),
9046+
source_uuid: None,
90199047
timestamp: DateTime::from_timestamp_millis(ts_ms).unwrap(),
90209048
body: Some(body.to_string()),
90219049
attachments: vec![],
@@ -9286,6 +9314,7 @@ mod tests {
92869314
SignalMessage {
92879315
source: source.to_string(),
92889316
source_name: None,
9317+
source_uuid: None,
92899318
timestamp: chrono::Utc::now(),
92909319
body: Some("hello".to_string()),
92919320
attachments: vec![],
@@ -9319,6 +9348,7 @@ mod tests {
93199348
let msg = SignalMessage {
93209349
source: "+10000000000".to_string(),
93219350
source_name: None,
9351+
source_uuid: None,
93229352
timestamp: chrono::Utc::now(),
93239353
body: Some("hey".to_string()),
93249354
attachments: vec![],
@@ -9691,6 +9721,7 @@ mod tests {
96919721
SignalMessage {
96929722
source: source.to_string(),
96939723
source_name: None,
9724+
source_uuid: None,
96949725
timestamp: chrono::Utc::now(),
96959726
body: body.map(|s| s.to_string()),
96969727
attachments: vec![],

src/signal/client.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,11 @@ fn parse_data_message(
15781578
.and_then(|v| v.as_str())
15791579
.map(|s| s.to_string());
15801580

1581+
let source_uuid = envelope
1582+
.get("sourceUuid")
1583+
.and_then(|v| v.as_str())
1584+
.map(|s| s.to_string());
1585+
15811586
let timestamp_ms = data
15821587
.get("timestamp")
15831588
.and_then(|v| v.as_i64())
@@ -1649,6 +1654,7 @@ fn parse_data_message(
16491654
Some(SignalEvent::MessageReceived(SignalMessage {
16501655
source,
16511656
source_name,
1657+
source_uuid,
16521658
timestamp,
16531659
body,
16541660
attachments,
@@ -2010,6 +2016,7 @@ fn parse_sent_sync(
20102016
Some(SignalEvent::MessageReceived(SignalMessage {
20112017
source,
20122018
source_name: None,
2019+
source_uuid: None,
20132020
timestamp,
20142021
body,
20152022
attachments,

src/signal/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub struct PollVote {
106106

107107
/// Events received from signal-cli
108108
#[derive(Debug, Clone)]
109+
#[allow(clippy::large_enum_variant)]
109110
pub enum SignalEvent {
110111
MessageReceived(SignalMessage),
111112
ReceiptReceived {
@@ -290,6 +291,7 @@ impl SignalEvent {
290291
pub struct SignalMessage {
291292
pub source: String,
292293
pub source_name: Option<String>,
294+
pub source_uuid: Option<String>,
293295
pub timestamp: DateTime<Utc>,
294296
pub body: Option<String>,
295297
pub attachments: Vec<Attachment>,

0 commit comments

Comments
 (0)