mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
refactor(bluebubbles): share multipart helpers
This commit is contained in:
@@ -2,11 +2,11 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
||||
import crypto from "node:crypto";
|
||||
import path from "node:path";
|
||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||
import { postMultipartFormData } from "./multipart.js";
|
||||
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
||||
import { extractBlueBubblesMessageId, resolveBlueBubblesSendTarget } from "./send-helpers.js";
|
||||
import { resolveChatGuidForTarget } from "./send.js";
|
||||
import {
|
||||
blueBubblesFetchWithTimeout,
|
||||
buildBlueBubblesApiUrl,
|
||||
type BlueBubblesAttachment,
|
||||
type BlueBubblesSendTarget,
|
||||
@@ -219,26 +219,12 @@ export async function sendBlueBubblesAttachment(params: {
|
||||
// Close the multipart body
|
||||
parts.push(encoder.encode(`--${boundary}--\r\n`));
|
||||
|
||||
// Combine all parts into a single buffer
|
||||
const totalLength = parts.reduce((acc, part) => acc + part.length, 0);
|
||||
const body = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const part of parts) {
|
||||
body.set(part, offset);
|
||||
offset += part.length;
|
||||
}
|
||||
|
||||
const res = await blueBubblesFetchWithTimeout(
|
||||
const res = await postMultipartFormData({
|
||||
url,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
body,
|
||||
},
|
||||
opts.timeoutMs ?? 60_000, // longer timeout for file uploads
|
||||
);
|
||||
boundary,
|
||||
parts,
|
||||
timeoutMs: opts.timeoutMs ?? 60_000, // longer timeout for file uploads
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text();
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
||||
import crypto from "node:crypto";
|
||||
import path from "node:path";
|
||||
import { resolveBlueBubblesAccount } from "./accounts.js";
|
||||
import { postMultipartFormData } from "./multipart.js";
|
||||
import { getCachedBlueBubblesPrivateApiStatus } from "./probe.js";
|
||||
import { blueBubblesFetchWithTimeout, buildBlueBubblesApiUrl } from "./types.js";
|
||||
|
||||
@@ -376,26 +377,12 @@ export async function setGroupIconBlueBubbles(
|
||||
// Close multipart body
|
||||
parts.push(encoder.encode(`--${boundary}--\r\n`));
|
||||
|
||||
// Combine into single buffer
|
||||
const totalLength = parts.reduce((acc, part) => acc + part.length, 0);
|
||||
const body = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const part of parts) {
|
||||
body.set(part, offset);
|
||||
offset += part.length;
|
||||
}
|
||||
|
||||
const res = await blueBubblesFetchWithTimeout(
|
||||
const res = await postMultipartFormData({
|
||||
url,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
body,
|
||||
},
|
||||
opts.timeoutMs ?? 60_000, // longer timeout for file uploads
|
||||
);
|
||||
boundary,
|
||||
parts,
|
||||
timeoutMs: opts.timeoutMs ?? 60_000, // longer timeout for file uploads
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text().catch(() => "");
|
||||
|
||||
32
extensions/bluebubbles/src/multipart.ts
Normal file
32
extensions/bluebubbles/src/multipart.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { blueBubblesFetchWithTimeout } from "./types.js";
|
||||
|
||||
export function concatUint8Arrays(parts: Uint8Array[]): Uint8Array {
|
||||
const totalLength = parts.reduce((acc, part) => acc + part.length, 0);
|
||||
const body = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const part of parts) {
|
||||
body.set(part, offset);
|
||||
offset += part.length;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function postMultipartFormData(params: {
|
||||
url: string;
|
||||
boundary: string;
|
||||
parts: Uint8Array[];
|
||||
timeoutMs: number;
|
||||
}): Promise<Response> {
|
||||
const body = concatUint8Arrays(params.parts);
|
||||
return await blueBubblesFetchWithTimeout(
|
||||
params.url,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": `multipart/form-data; boundary=${params.boundary}`,
|
||||
},
|
||||
body,
|
||||
},
|
||||
params.timeoutMs,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user