mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
Adds container REST/WebSocket support for bbernhard/signal-cli-rest-api Signal deployments.
Closes #10240.
Thanks @Hua688.
Verification:
- pnpm exec oxfmt --check --threads=1 docs/channels/signal.md
- pnpm lint:extensions
- pnpm test extensions/signal
- pnpm tsgo:extensions && pnpm tsgo:test:extensions
- pnpm config:docs:check
- git diff --check
- CI checks on PR head 1d0a536ecd
- Crabbox/Testbox live Docker smoke tbx_01kr7h07shhcafxjc0ezfh946w / run 25614453516
98 lines
2.2 KiB
TypeScript
98 lines
2.2 KiB
TypeScript
import {
|
|
computeBackoff,
|
|
logVerbose,
|
|
shouldLogVerbose,
|
|
sleepWithAbort,
|
|
type BackoffPolicy,
|
|
type RuntimeEnv,
|
|
} from "openclaw/plugin-sdk/runtime-env";
|
|
import { type SignalApiMode, type SignalSseEvent, streamSignalEvents } from "./client-adapter.js";
|
|
|
|
const DEFAULT_RECONNECT_POLICY: BackoffPolicy = {
|
|
initialMs: 1_000,
|
|
maxMs: 10_000,
|
|
factor: 2,
|
|
jitter: 0.2,
|
|
};
|
|
|
|
type RunSignalSseLoopParams = {
|
|
baseUrl: string;
|
|
account?: string;
|
|
abortSignal?: AbortSignal;
|
|
runtime: RuntimeEnv;
|
|
onEvent: (event: SignalSseEvent) => void;
|
|
timeoutMs?: number;
|
|
apiMode?: SignalApiMode;
|
|
policy?: Partial<BackoffPolicy>;
|
|
};
|
|
|
|
export async function runSignalSseLoop({
|
|
baseUrl,
|
|
account,
|
|
abortSignal,
|
|
runtime,
|
|
onEvent,
|
|
timeoutMs,
|
|
apiMode,
|
|
policy,
|
|
}: RunSignalSseLoopParams) {
|
|
const reconnectPolicy = {
|
|
...DEFAULT_RECONNECT_POLICY,
|
|
...policy,
|
|
};
|
|
let reconnectAttempts = 0;
|
|
|
|
const logReconnectVerbose = (message: string) => {
|
|
if (!shouldLogVerbose()) {
|
|
return;
|
|
}
|
|
logVerbose(message);
|
|
};
|
|
|
|
for (;;) {
|
|
if (abortSignal?.aborted) {
|
|
break;
|
|
}
|
|
try {
|
|
await streamSignalEvents({
|
|
baseUrl,
|
|
account,
|
|
abortSignal,
|
|
timeoutMs,
|
|
apiMode,
|
|
onEvent: (event: SignalSseEvent) => {
|
|
reconnectAttempts = 0;
|
|
onEvent(event);
|
|
},
|
|
logger: {
|
|
log: runtime.log,
|
|
error: runtime.error,
|
|
},
|
|
});
|
|
if (abortSignal?.aborted) {
|
|
return;
|
|
}
|
|
reconnectAttempts += 1;
|
|
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
|
|
logReconnectVerbose(`Signal stream ended, reconnecting in ${delayMs / 1000}s...`);
|
|
await sleepWithAbort(delayMs, abortSignal);
|
|
} catch (err) {
|
|
if (abortSignal?.aborted) {
|
|
return;
|
|
}
|
|
runtime.error?.(`Signal stream error: ${String(err)}`);
|
|
reconnectAttempts += 1;
|
|
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
|
|
runtime.log?.(`Signal connection lost, reconnecting in ${delayMs / 1000}s...`);
|
|
try {
|
|
await sleepWithAbort(delayMs, abortSignal);
|
|
} catch (sleepErr) {
|
|
if (abortSignal?.aborted) {
|
|
return;
|
|
}
|
|
throw sleepErr;
|
|
}
|
|
}
|
|
}
|
|
}
|