mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 09:22:45 +00:00
refactor(bluebubbles): share send helpers
This commit is contained in:
@@ -3,8 +3,8 @@ import crypto from "node:crypto";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||||
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
||||||
|
import { extractBlueBubblesMessageId, resolveBlueBubblesSendTarget } from "./send-helpers.js";
|
||||||
import { resolveChatGuidForTarget } from "./send.js";
|
import { resolveChatGuidForTarget } from "./send.js";
|
||||||
import { parseBlueBubblesTarget, normalizeBlueBubblesHandle } from "./targets.js";
|
|
||||||
import {
|
import {
|
||||||
blueBubblesFetchWithTimeout,
|
blueBubblesFetchWithTimeout,
|
||||||
buildBlueBubblesApiUrl,
|
buildBlueBubblesApiUrl,
|
||||||
@@ -102,52 +102,6 @@ export type SendBlueBubblesAttachmentResult = {
|
|||||||
messageId: string;
|
messageId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function resolveSendTarget(raw: string): BlueBubblesSendTarget {
|
|
||||||
const parsed = parseBlueBubblesTarget(raw);
|
|
||||||
if (parsed.kind === "handle") {
|
|
||||||
return {
|
|
||||||
kind: "handle",
|
|
||||||
address: normalizeBlueBubblesHandle(parsed.to),
|
|
||||||
service: parsed.service,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (parsed.kind === "chat_id") {
|
|
||||||
return { kind: "chat_id", chatId: parsed.chatId };
|
|
||||||
}
|
|
||||||
if (parsed.kind === "chat_guid") {
|
|
||||||
return { kind: "chat_guid", chatGuid: parsed.chatGuid };
|
|
||||||
}
|
|
||||||
return { kind: "chat_identifier", chatIdentifier: parsed.chatIdentifier };
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractMessageId(payload: unknown): string {
|
|
||||||
if (!payload || typeof payload !== "object") {
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
const record = payload as Record<string, unknown>;
|
|
||||||
const data =
|
|
||||||
record.data && typeof record.data === "object"
|
|
||||||
? (record.data as Record<string, unknown>)
|
|
||||||
: null;
|
|
||||||
const candidates = [
|
|
||||||
record.messageId,
|
|
||||||
record.guid,
|
|
||||||
record.id,
|
|
||||||
data?.messageId,
|
|
||||||
data?.guid,
|
|
||||||
data?.id,
|
|
||||||
];
|
|
||||||
for (const candidate of candidates) {
|
|
||||||
if (typeof candidate === "string" && candidate.trim()) {
|
|
||||||
return candidate.trim();
|
|
||||||
}
|
|
||||||
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
|
||||||
return String(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an attachment via BlueBubbles API.
|
* Send an attachment via BlueBubbles API.
|
||||||
* Supports sending media files (images, videos, audio, documents) to a chat.
|
* Supports sending media files (images, videos, audio, documents) to a chat.
|
||||||
@@ -193,7 +147,7 @@ export async function sendBlueBubblesAttachment(params: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = resolveSendTarget(to);
|
const target = resolveBlueBubblesSendTarget(to);
|
||||||
const chatGuid = await resolveChatGuidForTarget({
|
const chatGuid = await resolveChatGuidForTarget({
|
||||||
baseUrl,
|
baseUrl,
|
||||||
password,
|
password,
|
||||||
@@ -299,7 +253,7 @@ export async function sendBlueBubblesAttachment(params: {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(responseBody) as unknown;
|
const parsed = JSON.parse(responseBody) as unknown;
|
||||||
return { messageId: extractMessageId(parsed) };
|
return { messageId: extractBlueBubblesMessageId(parsed) };
|
||||||
} catch {
|
} catch {
|
||||||
return { messageId: "ok" };
|
return { messageId: "ok" };
|
||||||
}
|
}
|
||||||
|
|||||||
53
extensions/bluebubbles/src/send-helpers.ts
Normal file
53
extensions/bluebubbles/src/send-helpers.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import type { BlueBubblesSendTarget } from "./types.js";
|
||||||
|
import { normalizeBlueBubblesHandle, parseBlueBubblesTarget } from "./targets.js";
|
||||||
|
|
||||||
|
export function resolveBlueBubblesSendTarget(raw: string): BlueBubblesSendTarget {
|
||||||
|
const parsed = parseBlueBubblesTarget(raw);
|
||||||
|
if (parsed.kind === "handle") {
|
||||||
|
return {
|
||||||
|
kind: "handle",
|
||||||
|
address: normalizeBlueBubblesHandle(parsed.to),
|
||||||
|
service: parsed.service,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (parsed.kind === "chat_id") {
|
||||||
|
return { kind: "chat_id", chatId: parsed.chatId };
|
||||||
|
}
|
||||||
|
if (parsed.kind === "chat_guid") {
|
||||||
|
return { kind: "chat_guid", chatGuid: parsed.chatGuid };
|
||||||
|
}
|
||||||
|
return { kind: "chat_identifier", chatIdentifier: parsed.chatIdentifier };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractBlueBubblesMessageId(payload: unknown): string {
|
||||||
|
if (!payload || typeof payload !== "object") {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
const record = payload as Record<string, unknown>;
|
||||||
|
const data =
|
||||||
|
record.data && typeof record.data === "object"
|
||||||
|
? (record.data as Record<string, unknown>)
|
||||||
|
: null;
|
||||||
|
const candidates = [
|
||||||
|
record.messageId,
|
||||||
|
record.messageGuid,
|
||||||
|
record.message_guid,
|
||||||
|
record.guid,
|
||||||
|
record.id,
|
||||||
|
data?.messageId,
|
||||||
|
data?.messageGuid,
|
||||||
|
data?.message_guid,
|
||||||
|
data?.message_id,
|
||||||
|
data?.guid,
|
||||||
|
data?.id,
|
||||||
|
];
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
if (typeof candidate === "string" && candidate.trim()) {
|
||||||
|
return candidate.trim();
|
||||||
|
}
|
||||||
|
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
||||||
|
return String(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
@@ -3,11 +3,8 @@ import crypto from "node:crypto";
|
|||||||
import { stripMarkdown } from "openclaw/plugin-sdk";
|
import { stripMarkdown } from "openclaw/plugin-sdk";
|
||||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||||
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
||||||
import {
|
import { extractBlueBubblesMessageId, resolveBlueBubblesSendTarget } from "./send-helpers.js";
|
||||||
extractHandleFromChatGuid,
|
import { extractHandleFromChatGuid, normalizeBlueBubblesHandle } from "./targets.js";
|
||||||
normalizeBlueBubblesHandle,
|
|
||||||
parseBlueBubblesTarget,
|
|
||||||
} from "./targets.js";
|
|
||||||
import {
|
import {
|
||||||
blueBubblesFetchWithTimeout,
|
blueBubblesFetchWithTimeout,
|
||||||
buildBlueBubblesApiUrl,
|
buildBlueBubblesApiUrl,
|
||||||
@@ -74,57 +71,6 @@ function resolveEffectId(raw?: string): string | undefined {
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveSendTarget(raw: string): BlueBubblesSendTarget {
|
|
||||||
const parsed = parseBlueBubblesTarget(raw);
|
|
||||||
if (parsed.kind === "handle") {
|
|
||||||
return {
|
|
||||||
kind: "handle",
|
|
||||||
address: normalizeBlueBubblesHandle(parsed.to),
|
|
||||||
service: parsed.service,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (parsed.kind === "chat_id") {
|
|
||||||
return { kind: "chat_id", chatId: parsed.chatId };
|
|
||||||
}
|
|
||||||
if (parsed.kind === "chat_guid") {
|
|
||||||
return { kind: "chat_guid", chatGuid: parsed.chatGuid };
|
|
||||||
}
|
|
||||||
return { kind: "chat_identifier", chatIdentifier: parsed.chatIdentifier };
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractMessageId(payload: unknown): string {
|
|
||||||
if (!payload || typeof payload !== "object") {
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
const record = payload as Record<string, unknown>;
|
|
||||||
const data =
|
|
||||||
record.data && typeof record.data === "object"
|
|
||||||
? (record.data as Record<string, unknown>)
|
|
||||||
: null;
|
|
||||||
const candidates = [
|
|
||||||
record.messageId,
|
|
||||||
record.messageGuid,
|
|
||||||
record.message_guid,
|
|
||||||
record.guid,
|
|
||||||
record.id,
|
|
||||||
data?.messageId,
|
|
||||||
data?.messageGuid,
|
|
||||||
data?.message_guid,
|
|
||||||
data?.message_id,
|
|
||||||
data?.guid,
|
|
||||||
data?.id,
|
|
||||||
];
|
|
||||||
for (const candidate of candidates) {
|
|
||||||
if (typeof candidate === "string" && candidate.trim()) {
|
|
||||||
return candidate.trim();
|
|
||||||
}
|
|
||||||
if (typeof candidate === "number" && Number.isFinite(candidate)) {
|
|
||||||
return String(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlueBubblesChatRecord = Record<string, unknown>;
|
type BlueBubblesChatRecord = Record<string, unknown>;
|
||||||
|
|
||||||
function extractChatGuid(chat: BlueBubblesChatRecord): string | null {
|
function extractChatGuid(chat: BlueBubblesChatRecord): string | null {
|
||||||
@@ -365,7 +311,7 @@ async function createNewChatWithMessage(params: {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(body) as unknown;
|
const parsed = JSON.parse(body) as unknown;
|
||||||
return { messageId: extractMessageId(parsed) };
|
return { messageId: extractBlueBubblesMessageId(parsed) };
|
||||||
} catch {
|
} catch {
|
||||||
return { messageId: "ok" };
|
return { messageId: "ok" };
|
||||||
}
|
}
|
||||||
@@ -400,7 +346,7 @@ export async function sendMessageBlueBubbles(
|
|||||||
}
|
}
|
||||||
const privateApiStatus = getCachedBlueBubblesPrivateApiStatus(account.accountId);
|
const privateApiStatus = getCachedBlueBubblesPrivateApiStatus(account.accountId);
|
||||||
|
|
||||||
const target = resolveSendTarget(to);
|
const target = resolveBlueBubblesSendTarget(to);
|
||||||
const chatGuid = await resolveChatGuidForTarget({
|
const chatGuid = await resolveChatGuidForTarget({
|
||||||
baseUrl,
|
baseUrl,
|
||||||
password,
|
password,
|
||||||
@@ -477,7 +423,7 @@ export async function sendMessageBlueBubbles(
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(body) as unknown;
|
const parsed = JSON.parse(body) as unknown;
|
||||||
return { messageId: extractMessageId(parsed) };
|
return { messageId: extractBlueBubblesMessageId(parsed) };
|
||||||
} catch {
|
} catch {
|
||||||
return { messageId: "ok" };
|
return { messageId: "ok" };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user