feat(telemetry): add unified_session telemetry to reduce detection

Implements WhatsApp's unified_session telemetry feature to reduce
detection of unofficial clients. This is an enterprise-grade implementation
inspired by whatsmeow PR #1057 and Baileys PR #2294.

Features:
- UnifiedSessionManager class with circuit breaker protection
- Server time synchronization for accurate session IDs
- Rate limiting to prevent spam (1 minute between sends)
- Prometheus metrics integration (unified_session_sent, errors)
- Structured logging for debugging
- Configurable via SocketConfig.enableUnifiedSession
- Environment variable support (BAILEYS_UNIFIED_SESSION_ENABLED)

Trigger points (matching official WhatsApp Web):
- After successful login (CB:success)
- After successful pairing (CB:iq,,pair-success)
- When sending 'available' presence

Implementation details:
- Session ID algorithm: (now + serverOffset + 3days) % 7days
- Time constants exported from Defaults/index.ts
- Full test coverage (31 tests)

References:
- https://github.com/tulir/whatsmeow/pull/1057
- https://github.com/WhiskeySockets/Baileys/pull/2294
- https://github.com/tulir/whatsmeow/issues/810
This commit is contained in:
Claude
2026-01-24 18:56:08 +00:00
parent a55055e55e
commit 9f17567951
7 changed files with 948 additions and 3 deletions
+9 -1
View File
@@ -68,7 +68,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
getMessage
} = config
const sock = makeSocket(config)
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError } = sock
const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession } = sock
let privacySettings: { [_: string]: string } | undefined
@@ -674,6 +674,14 @@ export const makeChatsSocket = (config: SocketConfig) => {
type
}
})
// Send unified_session telemetry when going online
// This mimics official WhatsApp Web client behavior
if (type === 'available') {
sendUnifiedSession('presence').catch(err => {
logger.debug({ err }, 'Failed to send unified_session on presence available')
})
}
} else {
const { server } = jidDecode(toJid)!
const isLid = server === 'lid'