Skip to content

Commit c35ee42

Browse files
committed
fix: register BlueBubbles webhook route before server-info fetch
Previously, monitorBlueBubblesProvider called fetchBlueBubblesServerInfo (up to 5 s timeout) *before* registering the webhook HTTP route. This created a window on every startup and after every crash-loop restart where POST /bluebubbles-webhook returned 404: the plugin HTTP registry had no matching entry yet so the request fell all the way through the gateway's stage pipeline. Fix: move registerBlueBubblesWebhookTarget to the top of the function, before the async server-info fetch, so the route is reachable as soon as the provider (re)starts. Also fix an off-by-one in server-channels restart accounting: when the crash-loop hit MAX_RESTART_ATTEMPTS + 1 it was reporting reconnectAttempts = MAX + 1 instead of MAX, causing the snapshot to show one extra attempt than the configured cap. Fixes #45620
1 parent e84266e commit c35ee42

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

extensions/bluebubbles/src/monitor.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,21 @@ export async function monitorBlueBubblesProvider(
269269
const core = getBlueBubblesRuntime();
270270
const path = options.webhookPath?.trim() || DEFAULT_WEBHOOK_PATH;
271271

272-
// Fetch and cache server info (for macOS version detection in action gating)
272+
// Register the webhook route immediately so that incoming messages are
273+
// accepted as soon as the provider starts (or restarts). Fetching server
274+
// info is async and can take up to 5 s; registering after the fetch would
275+
// leave a window where POST /bluebubbles-webhook returns 404.
276+
const unregister = registerBlueBubblesWebhookTarget({
277+
account,
278+
config,
279+
runtime,
280+
core,
281+
path,
282+
statusSink,
283+
});
284+
285+
// Fetch and cache server info (for macOS version detection in action gating).
286+
// Done after registration so the webhook is already reachable.
273287
const serverInfo = await fetchBlueBubblesServerInfo({
274288
baseUrl: account.baseUrl,
275289
password: account.config.password,
@@ -285,15 +299,6 @@ export async function monitorBlueBubblesProvider(
285299
);
286300
}
287301

288-
const unregister = registerBlueBubblesWebhookTarget({
289-
account,
290-
config,
291-
runtime,
292-
core,
293-
path,
294-
statusSink,
295-
});
296-
297302
return await new Promise((resolve) => {
298303
const stop = () => {
299304
unregister();

src/gateway/server-channels.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
258258
setRuntime(channelId, id, {
259259
accountId: id,
260260
restartPending: false,
261-
reconnectAttempts: attempt,
261+
// Cap at MAX_RESTART_ATTEMPTS so callers see the configured
262+
// limit rather than an internal over-count (attempt is already
263+
// MAX + 1 at this point).
264+
reconnectAttempts: MAX_RESTART_ATTEMPTS,
262265
});
263266
log.error?.(`[${id}] giving up after ${MAX_RESTART_ATTEMPTS} restart attempts`);
264267
return;

0 commit comments

Comments
 (0)