mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-10 10:42:54 +02:00
feat(dm): add delivery confirmation, retry, and receiver-side dedup
- Fix ACK handler bug: read 'code' field instead of 'expected_ack' - Add DM retry (up to 3 attempts) with same timestamp for receiver dedup - Add receiver-side dedup in _on_dm_received() (sender_timestamp or time-window) - Add PATH_UPDATE as backup delivery signal for flood DMs - Track pending acks with dm_id for proper ACK→DM linkage - Return dm_id and expected_ack from POST /dm/messages API - Add find_dm_duplicate() and get_dm_by_id() database helpers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ Synchronous wrapper with WAL mode. Thread-safe via connection-per-call pattern.
|
||||
import sqlite3
|
||||
import shutil
|
||||
import logging
|
||||
import time
|
||||
from pathlib import Path
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime, timedelta
|
||||
@@ -355,6 +356,43 @@ class Database:
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def get_dm_by_id(self, dm_id: int) -> Optional[Dict]:
|
||||
"""Fetch a direct message by its ID."""
|
||||
with self._connect() as conn:
|
||||
row = conn.execute(
|
||||
"SELECT * FROM direct_messages WHERE id = ?", (dm_id,)
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def find_dm_duplicate(self, contact_pubkey: str, content: str,
|
||||
sender_timestamp: int = None,
|
||||
window_seconds: int = 300) -> Optional[Dict]:
|
||||
"""Check for duplicate incoming DM (for receiver-side dedup).
|
||||
|
||||
If sender_timestamp is provided, matches exact (sender, timestamp, text).
|
||||
Otherwise falls back to time-window match (same sender + text within window).
|
||||
"""
|
||||
contact_pubkey = contact_pubkey.lower()
|
||||
with self._connect() as conn:
|
||||
if sender_timestamp is not None:
|
||||
row = conn.execute(
|
||||
"""SELECT id FROM direct_messages
|
||||
WHERE contact_pubkey = ? AND direction = 'in'
|
||||
AND content = ? AND sender_timestamp = ?
|
||||
LIMIT 1""",
|
||||
(contact_pubkey, content, sender_timestamp)
|
||||
).fetchone()
|
||||
else:
|
||||
cutoff = int(time.time()) - window_seconds
|
||||
row = conn.execute(
|
||||
"""SELECT id FROM direct_messages
|
||||
WHERE contact_pubkey = ? AND direction = 'in'
|
||||
AND content = ? AND timestamp > ?
|
||||
LIMIT 1""",
|
||||
(contact_pubkey, content, cutoff)
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
# ================================================================
|
||||
# Echoes
|
||||
# ================================================================
|
||||
|
||||
Reference in New Issue
Block a user