diff --git a/conversations.php b/conversations.php index 392c95b..00b8383 100644 --- a/conversations.php +++ b/conversations.php @@ -1870,19 +1870,31 @@ this.conversations = messages.concat(this.conversations); } - // Dedupe messages by message_id (keep the last occurrence) + // Improved dedupe: use message_id, id, and fallback composite key (direction|type|media|created_sec) try { const seen = new Map(); + const duplicates = []; for (let i = this.conversations.length - 1; i >= 0; i--) { const m = this.conversations[i]; - if (m && m.message_id) { - if (seen.has(m.message_id)) { - this.conversations.splice(i, 1); - } else { - seen.set(m.message_id, true); - } + if (!m) continue; + const mid = m.message_id || m.id || null; + let key = null; + if (mid) key = String(mid); + else { + const partMedia = m.media_url || m.media_url_external || m.local_file || m.local_thumb || m.content || ''; + const ts = m.created_at ? String(Math.floor(new Date(m.created_at).getTime() / 1000)) : ''; + key = `${m.direction||'?'}|${m.message_type||m.media_type||'text'}|${partMedia}|${ts}`; + } + + if (seen.has(key)) { + // remove duplicate occurrence (keep the last one) + duplicates.push({index:i, key}); + this.conversations.splice(i, 1); + } else { + seen.set(key, true); } } + if (duplicates.length) console.debug('Dedupe removed duplicates (indices):', duplicates); } catch (e) { console.warn('Dedupe failed', e); }