Skip to content

Commit 2c460d4

Browse files
committed
fix: sync own device list at login so DM fan-out includes all companions
WA Web calls syncMyDeviceList() during bootstrap to populate the device registry for the own account. Without this, companion devices added after initial pairing (e.g. WA Web) are missing from the DM fan-out, causing those devices to never receive self-sent messages.
1 parent 78075fc commit 2c460d4

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

‎src/client.rs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,8 +1944,12 @@ impl Client {
19441944
// Don't fail login - PDO will retry via ensure_e2e_sessions fallback
19451945
}
19461946

1947-
// === Passive Tasks (mimics WhatsApp Web's PassiveTaskManager) ===
1948-
// WhatsApp Web executes passive tasks (like PreKey upload) BEFORE sending the active IQ.
1947+
// Sync own device list so DM fan-out includes all companions
1948+
check_generation!();
1949+
if let Err(e) = client_clone.sync_own_device_list().await {
1950+
warn!("Failed to sync own device list: {e:?}");
1951+
}
1952+
19491953
check_generation!();
19501954
if !client_clone.is_connected() {
19511955
debug!("Skipping passive tasks: connection closed");

‎src/usync.rs‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,35 @@ impl Client {
158158

159159
Ok(all_devices)
160160
}
161+
162+
/// Sync own device list from the server, bypassing cache.
163+
/// Matches WA Web's `syncMyDeviceList()` called during bootstrap.
164+
pub(crate) async fn sync_own_device_list(&self) -> Result<(), anyhow::Error> {
165+
let device_snapshot = self.persistence_manager.get_device_snapshot().await;
166+
167+
let mut jids = Vec::with_capacity(2);
168+
if let Some(ref pn) = device_snapshot.pn {
169+
let pn_bare = pn.to_non_ad();
170+
self.invalidate_device_cache(&pn_bare.user).await;
171+
jids.push(pn_bare);
172+
}
173+
if let Some(ref lid) = device_snapshot.lid {
174+
let lid_bare = lid.to_non_ad();
175+
self.invalidate_device_cache(&lid_bare.user).await;
176+
jids.push(lid_bare);
177+
}
178+
179+
if jids.is_empty() {
180+
return Ok(());
181+
}
182+
183+
let devices = self.get_user_devices(&jids).await?;
184+
log::info!(
185+
"Synced own device list from server: {} devices",
186+
devices.len()
187+
);
188+
Ok(())
189+
}
161190
}
162191

163192
#[cfg(test)]

0 commit comments

Comments
 (0)