fix(bot): stop reconnect loop during fresh pairing — root cause of QR rotation every 5s
The session-manager's auto-reconnect (5 s after a non-logged-out close) was firing during initial pairing. Baileys closes the socket whenever it exhausts its QR refs (or transient handshake errors); the auto-reconnect then opened a brand-new socket → new QR pool → another close 5 s later. The web saw a fresh QR every ~5 s and the user could never link, because WhatsApp invalidates each QR as soon as Baileys cycles to the next. Fix: only auto-reconnect for accounts that have been linked before (`whatsapp_accounts.last_connected_at IS NOT NULL`). For brand-new pairing attempts the pair-handler's 5-minute window is now the single authority; on close we just stop the session and let the operator retry. With auto-reconnect off, Baileys uses its default QR cadence: 60 s for the first QR, 20 s for each subsequent rotation, ~6 refs total (~3 minutes of valid scanning) — plenty of time to scan. Pair-handler now also surfaces ANY close as `session.timeout` to the web (was only emitting on `loggedOut`). Without this the user would be left staring at the last QR after Baileys gives up, with no way to know pairing failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b4f0d0b84
commit
4d10c72551
@ -128,7 +128,12 @@ export async function handleStartPairing(accountId: string): Promise<void> {
|
|||||||
count: synced,
|
count: synced,
|
||||||
});
|
});
|
||||||
off();
|
off();
|
||||||
} else if (event.type === "close" && event.loggedOut) {
|
} else if (event.type === "close") {
|
||||||
|
// During the pairing window, ANY close means the QR window
|
||||||
|
// ended without a successful link — Baileys' default is to
|
||||||
|
// close after exhausting QR refs (~2.5 min). Surface this to
|
||||||
|
// the UI so the user gets a "pairing timed out" screen and a
|
||||||
|
// chance to retry, instead of staring at a stale QR forever.
|
||||||
const t = pairTimeouts.get(id);
|
const t = pairTimeouts.get(id);
|
||||||
if (t) {
|
if (t) {
|
||||||
clearTimeout(t);
|
clearTimeout(t);
|
||||||
|
|||||||
@ -141,14 +141,30 @@ class SessionManager {
|
|||||||
.set({ status: event.loggedOut ? "logged_out" : "disconnected" })
|
.set({ status: event.loggedOut ? "logged_out" : "disconnected" })
|
||||||
.where(eq(whatsappAccounts.id, accountId));
|
.where(eq(whatsappAccounts.id, accountId));
|
||||||
|
|
||||||
if (!event.loggedOut) {
|
if (event.loggedOut) {
|
||||||
const timer = setTimeout(() => {
|
|
||||||
this.reconnectTimers.delete(accountId);
|
|
||||||
void this.stop(accountId).then(() => this.start(accountId));
|
|
||||||
}, 5000);
|
|
||||||
this.reconnectTimers.set(accountId, timer);
|
|
||||||
} else {
|
|
||||||
await this.stop(accountId);
|
await this.stop(accountId);
|
||||||
|
} else {
|
||||||
|
// Only auto-reconnect for accounts that have been linked at least
|
||||||
|
// once — `lastConnectedAt` is set on `open`. During an initial
|
||||||
|
// pairing attempt the close event fires every time Baileys
|
||||||
|
// exhausts QR refs (~every 30s). Reconnecting would restart the
|
||||||
|
// pair dance and rotate the QR every few seconds — pair-handler
|
||||||
|
// already manages the pairing window via its own 5-min timeout.
|
||||||
|
const account = await db.query.whatsappAccounts.findFirst({
|
||||||
|
where: (a, { eq }) => eq(a.id, accountId),
|
||||||
|
columns: { lastConnectedAt: true },
|
||||||
|
});
|
||||||
|
if (account?.lastConnectedAt) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
this.reconnectTimers.delete(accountId);
|
||||||
|
void this.stop(accountId).then(() => this.start(accountId));
|
||||||
|
}, 5000);
|
||||||
|
this.reconnectTimers.set(accountId, timer);
|
||||||
|
} else {
|
||||||
|
// Brand-new account that hasn't authenticated yet — let the
|
||||||
|
// pair-handler clean up via its timeout.
|
||||||
|
await this.stop(accountId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (event.type === "qr") {
|
} else if (event.type === "qr") {
|
||||||
await db
|
await db
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user