From 888b6bc9483518d535f1ff36408da8868c22ea24 Mon Sep 17 00:00:00 2001 From: echoVic Date: Sun, 22 Feb 2026 18:12:40 +0800 Subject: [PATCH] fix(bluebubbles): treat null privateApiStatus as disabled, not enabled Bug: privateApiStatus cache expires after 10 minutes, returning null. The check '!== false' treats null as truthy, causing 500 errors when trying to use Private API features that aren't actually available. Root cause: In JavaScript, null !== false evaluates to true. Fix: Changed all checks from '!== false' to '=== true', so null (cache expired/unknown) is treated as disabled (safe default). Files changed: - extensions/bluebubbles/src/send.ts (line 376) - extensions/bluebubbles/src/monitor-processing.ts (line 423) - extensions/bluebubbles/src/attachments.ts (lines 210, 220) Fixes #23393 --- extensions/bluebubbles/src/attachments.ts | 4 ++-- extensions/bluebubbles/src/monitor-processing.ts | 2 +- extensions/bluebubbles/src/send.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/bluebubbles/src/attachments.ts b/extensions/bluebubbles/src/attachments.ts index 48331f21571..5d5841c8295 100644 --- a/extensions/bluebubbles/src/attachments.ts +++ b/extensions/bluebubbles/src/attachments.ts @@ -207,7 +207,7 @@ export async function sendBlueBubblesAttachment(params: { addField("chatGuid", chatGuid); addField("name", filename); addField("tempGuid", `temp-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`); - if (privateApiStatus !== false) { + if (privateApiStatus === true) { addField("method", "private-api"); } @@ -217,7 +217,7 @@ export async function sendBlueBubblesAttachment(params: { } const trimmedReplyTo = replyToMessageGuid?.trim(); - if (trimmedReplyTo && privateApiStatus !== false) { + if (trimmedReplyTo && privateApiStatus === true) { addField("selectedMessageGuid", trimmedReplyTo); addField("partIndex", typeof replyToPartIndex === "number" ? String(replyToPartIndex) : "0"); } diff --git a/extensions/bluebubbles/src/monitor-processing.ts b/extensions/bluebubbles/src/monitor-processing.ts index 4ae113d935f..8f58c7ab552 100644 --- a/extensions/bluebubbles/src/monitor-processing.ts +++ b/extensions/bluebubbles/src/monitor-processing.ts @@ -420,7 +420,7 @@ export async function processMessage( target: WebhookTarget, ): Promise { const { account, config, runtime, core, statusSink } = target; - const privateApiEnabled = getCachedBlueBubblesPrivateApiStatus(account.accountId) !== false; + const privateApiEnabled = getCachedBlueBubblesPrivateApiStatus(account.accountId) === true; const groupFlag = resolveGroupFlagFromChatGuid(message.chatGuid); const isGroup = typeof groupFlag === "boolean" ? groupFlag : message.isGroup; diff --git a/extensions/bluebubbles/src/send.ts b/extensions/bluebubbles/src/send.ts index c5614062f51..62644ca9d53 100644 --- a/extensions/bluebubbles/src/send.ts +++ b/extensions/bluebubbles/src/send.ts @@ -373,7 +373,7 @@ export async function sendMessageBlueBubbles( const wantsReplyThread = Boolean(opts.replyToMessageGuid?.trim()); const wantsEffect = Boolean(effectId); const needsPrivateApi = wantsReplyThread || wantsEffect; - const canUsePrivateApi = needsPrivateApi && privateApiStatus !== false; + const canUsePrivateApi = needsPrivateApi && privateApiStatus === true; if (wantsEffect && privateApiStatus === false) { throw new Error( "BlueBubbles send failed: reply/effect requires Private API, but it is disabled on the BlueBubbles server.", @@ -395,7 +395,7 @@ export async function sendMessageBlueBubbles( } // Add message effects support - if (effectId) { + if (effectId && canUsePrivateApi) { payload.effectId = effectId; }