@openclaw/signal 2026.8.1-beta.2 → 2026.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accounts-DrStJjiK.js → accounts-DO4HMqaK.js} +2 -2
- package/dist/api.js +11 -10
- package/dist/{runtime-JPrGlV7h.js → approval-auth-BsYHLTHK.js} +4 -10
- package/dist/{approval-handler.runtime-Bi5yNhnj.js → approval-handler.runtime-PqC23XbY.js} +5 -5
- package/dist/{approval-reactions-BulCzhdB.js → approval-reactions-DB-86mqK.js} +63 -154
- package/dist/{channel-CzDJMDtX.js → channel-C4vwPXz8.js} +28 -23
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-D12iYzJB.js → channel.runtime-CSviXPlC.js} +2 -2
- package/dist/{config-schema-CkMIK7zp.js → config-schema-q_QuhDy2.js} +8 -7
- package/dist/contract-api.js +3 -2
- package/dist/{doctor-contract-api-Dnp5eQQJ.js → doctor-contract-api-C18u1hW0.js} +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{identity-BQ4OzXXk.js → identity-YXPmgFMu.js} +2 -47
- package/dist/{monitor-DiN2hKnG.js → monitor-fR9bCL2p.js} +188 -85
- package/dist/normalize-l_b99hap.js +51 -0
- package/dist/{probe-C_THuQzn.js → probe-D7BV0KJ5.js} +1 -1
- package/dist/{question-reactions-ByjH5qST.js → question-reactions-D04hVKsE.js} +2 -2
- package/dist/{reaction-runtime-api-Cf6QHcE5.js → reaction-runtime-api-Ch0dk2sh.js} +11 -36
- package/dist/reaction-runtime-api.js +1 -1
- package/dist/rpc-context-dXSy4NtF.js +15 -0
- package/dist/runtime-api.js +9 -10
- package/dist/{send-BvGgByMd.js → send-DO3rs413.js} +6 -24
- package/dist/{send.runtime-CtTBBrjL.js → send.runtime-FRY_sREg.js} +1 -1
- package/dist/{transport-detection-BItHawMq.js → transport-detection-BSXAOmuH.js} +19 -42
- package/dist/{transport-detection.runtime-DoiwPcrG.js → transport-detection.runtime-Cnykqcu0.js} +1 -1
- package/node_modules/ws/lib/permessage-deflate.js +3 -1
- package/node_modules/ws/package.json +1 -1
- package/openclaw.plugin.json +0 -6
- package/package.json +5 -5
- package/dist/rpc-context-CZUoE0-A.js +0 -17
|
@@ -1,51 +1,6 @@
|
|
|
1
|
-
import { normalizeLowercaseStringOrEmpty
|
|
1
|
+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
3
3
|
import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
4
|
-
//#region extensions/signal/src/normalize.ts
|
|
5
|
-
function normalizeSignalMessagingTarget(raw) {
|
|
6
|
-
const trimmed = raw.trim();
|
|
7
|
-
if (!trimmed) return;
|
|
8
|
-
let normalized = trimmed;
|
|
9
|
-
if (normalizeLowercaseStringOrEmpty(normalized).startsWith("signal:")) normalized = normalized.slice(7).trim();
|
|
10
|
-
if (!normalized) return;
|
|
11
|
-
const lower = normalizeLowercaseStringOrEmpty(normalized);
|
|
12
|
-
if (lower.startsWith("group:")) {
|
|
13
|
-
const id = normalized.slice(6).trim();
|
|
14
|
-
return id ? `group:${id}` : void 0;
|
|
15
|
-
}
|
|
16
|
-
if (lower.startsWith("username:")) {
|
|
17
|
-
const id = normalized.slice(9).trim();
|
|
18
|
-
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
|
|
19
|
-
}
|
|
20
|
-
if (lower.startsWith("u:")) {
|
|
21
|
-
const id = normalized.slice(2).trim();
|
|
22
|
-
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
|
|
23
|
-
}
|
|
24
|
-
if (lower.startsWith("uuid:")) {
|
|
25
|
-
const id = normalized.slice(5).trim();
|
|
26
|
-
return id ? normalizeLowercaseStringOrEmpty(id) : void 0;
|
|
27
|
-
}
|
|
28
|
-
return normalizeLowercaseStringOrEmpty(normalized);
|
|
29
|
-
}
|
|
30
|
-
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
31
|
-
const UUID_COMPACT_PATTERN = /^[0-9a-f]{32}$/i;
|
|
32
|
-
function looksLikeSignalTargetId(raw, normalized) {
|
|
33
|
-
const candidates = normalizeStringEntries([raw, normalized ?? ""]);
|
|
34
|
-
for (const candidate of candidates) {
|
|
35
|
-
if (/^(signal:)?(group:|username:|u:)/i.test(candidate)) return true;
|
|
36
|
-
if (/^(signal:)?uuid:/i.test(candidate)) {
|
|
37
|
-
const stripped = candidate.replace(/^signal:/i, "").replace(/^uuid:/i, "").trim();
|
|
38
|
-
if (!stripped) continue;
|
|
39
|
-
if (UUID_PATTERN.test(stripped) || UUID_COMPACT_PATTERN.test(stripped)) return true;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
const withoutSignalPrefix = candidate.replace(/^signal:/i, "").trim();
|
|
43
|
-
if (UUID_PATTERN.test(withoutSignalPrefix) || UUID_COMPACT_PATTERN.test(withoutSignalPrefix)) return true;
|
|
44
|
-
if (/^\+?\d{3,}$/.test(withoutSignalPrefix)) return true;
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
4
|
//#region extensions/signal/src/uuid.ts
|
|
50
5
|
const UUID_HYPHENATED_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
51
6
|
const UUID_COMPACT_RE = /^[0-9a-f]{32}$/i;
|
|
@@ -143,4 +98,4 @@ function isSignalSenderAllowed(sender, allowFrom) {
|
|
|
143
98
|
}).allowed;
|
|
144
99
|
}
|
|
145
100
|
//#endregion
|
|
146
|
-
export { normalizeSignalAllowRecipient as a, resolveSignalSender as c,
|
|
101
|
+
export { normalizeSignalAllowRecipient as a, resolveSignalSender as c, isSignalSenderAllowed as i, looksLikeUuid as l, formatSignalSenderDisplay as n, resolveSignalPeerId as o, formatSignalSenderId as r, resolveSignalRecipient as s, formatSignalPairingIdLine as t };
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { i as
|
|
2
|
+
import { l as normalizeSignalTransportHost } from "./transport-policy-DxvSMHp9.js";
|
|
3
|
+
import { i as resolveSignalAccount, o as resolveSignalReplyToMode } from "./accounts-DO4HMqaK.js";
|
|
4
|
+
import { n as normalizeSignalMessagingTarget } from "./normalize-l_b99hap.js";
|
|
5
|
+
import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine } from "./identity-YXPmgFMu.js";
|
|
6
|
+
import { c as resolveSignalReactionLevel, f as isSignalNativeApprovalHandlerConfigured, i as getOptionalSignalRuntime, l as formatSignalMediaText, n as registerSignalReplyContext, o as materializeSignalPresentationFallback } from "./transport-detection-BSXAOmuH.js";
|
|
6
7
|
import { n as signalRpcRequest, r as streamSignalEvents, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
|
|
7
|
-
import { n as sendReactionSignal } from "./reaction-runtime-api-
|
|
8
|
-
import {
|
|
9
|
-
import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-
|
|
10
|
-
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-
|
|
8
|
+
import { n as sendReactionSignal } from "./reaction-runtime-api-Ch0dk2sh.js";
|
|
9
|
+
import { i as maybeResolveSignalApprovalReaction, o as registerSignalApprovalReactionTargetForDeliveredPayload, s as resolveSignalApprovalConversationKey, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-DB-86mqK.js";
|
|
10
|
+
import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-D04hVKsE.js";
|
|
11
|
+
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-DO3rs413.js";
|
|
11
12
|
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
12
13
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
13
|
-
import { canonicalizeBase64, detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
|
|
14
14
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
15
15
|
import { asPositiveSafeInteger, isRecord, normalizeNullableString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
16
16
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
17
17
|
import { normalizeE164, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
18
18
|
import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, logInboundDrop, matchesMentionPatterns, readAgentRunTerminalOutcome, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toHistoryMediaEntries, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
|
|
19
|
+
import { canonicalizeBase64, detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
|
|
19
20
|
import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
20
|
-
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
21
|
+
import { ensurePortAvailable, extractErrorCode, formatErrorMessage as formatErrorMessage$1, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
21
22
|
import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
22
23
|
import path from "node:path";
|
|
23
24
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
@@ -50,6 +51,47 @@ const SIGNAL_DAEMON_STOP_KILL_TIMEOUT_MS = 1500;
|
|
|
50
51
|
function formatSignalDaemonExit(exit) {
|
|
51
52
|
return `signal daemon exited (source=${exit.source} code=${exit.code ?? "null"} signal=${exit.signal ?? "null"})`;
|
|
52
53
|
}
|
|
54
|
+
function formatSignalDaemonEndpoint(httpHost, httpPort) {
|
|
55
|
+
return `${httpHost.includes(":") ? `[${httpHost}]` : httpHost}:${httpPort}`;
|
|
56
|
+
}
|
|
57
|
+
async function assertSignalDaemonEndpointAvailable(params) {
|
|
58
|
+
try {
|
|
59
|
+
await ensurePortAvailable(params.httpPort, params.httpHost, params.abortSignal);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (params.abortSignal?.aborted) throw params.abortSignal.reason;
|
|
62
|
+
if (!(extractErrorCode(error) === "EADDRINUSE" || error instanceof Error && error.name === "PortInUseError")) return;
|
|
63
|
+
const endpoint = formatSignalDaemonEndpoint(params.httpHost, params.httpPort);
|
|
64
|
+
throw new Error(`Signal managed native endpoint ${endpoint} is unavailable: ${formatErrorMessage$1(error)} Stop the conflicting service, configure this Signal account with a different transport.httpPort, or use external-native for an intentionally operator-managed daemon.`, { cause: error });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function waitForSignalDaemonReady(params) {
|
|
68
|
+
await (params.waitForTransportReadyFn ?? waitForTransportReady)({
|
|
69
|
+
label: "signal daemon",
|
|
70
|
+
timeoutMs: Math.max(0, params.startupDeadlineMs - Date.now()),
|
|
71
|
+
logAfterMs: params.logAfterMs,
|
|
72
|
+
logIntervalMs: params.logIntervalMs,
|
|
73
|
+
pollIntervalMs: 150,
|
|
74
|
+
abortSignal: params.abortSignal,
|
|
75
|
+
runtime: params.runtime,
|
|
76
|
+
check: async () => {
|
|
77
|
+
const remainingMs = params.startupDeadlineMs - Date.now();
|
|
78
|
+
if (remainingMs <= 0) return {
|
|
79
|
+
ok: false,
|
|
80
|
+
error: "startup deadline exceeded"
|
|
81
|
+
};
|
|
82
|
+
const res = await signalCheck(params.baseUrl, Math.min(1e3, remainingMs));
|
|
83
|
+
if (Date.now() >= params.startupDeadlineMs) return {
|
|
84
|
+
ok: false,
|
|
85
|
+
error: "startup deadline exceeded"
|
|
86
|
+
};
|
|
87
|
+
if (res.ok) return { ok: true };
|
|
88
|
+
return {
|
|
89
|
+
ok: false,
|
|
90
|
+
error: res.error ?? (res.status ? `HTTP ${res.status}` : "unreachable")
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
53
95
|
function isRecoverableSignalCliReceiveException(line) {
|
|
54
96
|
return /\breceive exception:\s+.*\binvalid PreKey message:\s+decryption failed\b/i.test(line);
|
|
55
97
|
}
|
|
@@ -211,6 +253,68 @@ function createSignalDaemonLifecycle(params) {
|
|
|
211
253
|
};
|
|
212
254
|
}
|
|
213
255
|
//#endregion
|
|
256
|
+
//#region extensions/signal/src/native-reply.ts
|
|
257
|
+
function resolveSignalNativeReplyId(params) {
|
|
258
|
+
if (params.payload.replyToCurrent === false) return;
|
|
259
|
+
const payloadReplyToId = normalizeOptionalString(params.payload.replyToId);
|
|
260
|
+
const isExplicitCurrentReply = params.payload.replyToTag === true || params.payload.replyToCurrent === true;
|
|
261
|
+
if (!payloadReplyToId && !isExplicitCurrentReply && params.replyContext?.allowImplicitCurrentMessage === false) return;
|
|
262
|
+
const contextReplyToId = normalizeOptionalString(params.replyContext?.replyToId);
|
|
263
|
+
if (!contextReplyToId || payloadReplyToId && payloadReplyToId !== contextReplyToId) return;
|
|
264
|
+
return payloadReplyToId ?? contextReplyToId;
|
|
265
|
+
}
|
|
266
|
+
function isSignalStatusNoticePayload(payload) {
|
|
267
|
+
return Boolean(payload.isCompactionNotice || payload.isFallbackNotice || payload.isStatusNotice);
|
|
268
|
+
}
|
|
269
|
+
function createSignalNativeReplyIdPlan(params) {
|
|
270
|
+
const replyToId = resolveSignalNativeReplyId(params);
|
|
271
|
+
if (!replyToId) return {
|
|
272
|
+
peek: () => void 0,
|
|
273
|
+
use: () => void 0,
|
|
274
|
+
markSent: () => void 0
|
|
275
|
+
};
|
|
276
|
+
const isExplicitReply = params.payload.replyToTag === true || params.payload.replyToCurrent === true;
|
|
277
|
+
if (isSignalStatusNoticePayload(params.payload)) {
|
|
278
|
+
const resolve = params.replyToMode === "off" ? () => void 0 : () => replyToId;
|
|
279
|
+
return {
|
|
280
|
+
peek: resolve,
|
|
281
|
+
use: resolve,
|
|
282
|
+
markSent: () => void 0
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (isExplicitReply) {
|
|
286
|
+
const resolve = () => replyToId;
|
|
287
|
+
return {
|
|
288
|
+
peek: resolve,
|
|
289
|
+
use: resolve,
|
|
290
|
+
markSent: () => void 0
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const planner = createReplyReferencePlanner({
|
|
294
|
+
replyToMode: params.replyToMode,
|
|
295
|
+
existingId: replyToId,
|
|
296
|
+
hasReplied: params.replyContext?.state?.hasReplied
|
|
297
|
+
});
|
|
298
|
+
const syncState = () => {
|
|
299
|
+
if (params.replyContext?.state) params.replyContext.state.hasReplied = planner.hasReplied();
|
|
300
|
+
};
|
|
301
|
+
return {
|
|
302
|
+
peek: () => planner.peek(),
|
|
303
|
+
use: () => {
|
|
304
|
+
const nextReplyToId = planner.use();
|
|
305
|
+
syncState();
|
|
306
|
+
return nextReplyToId;
|
|
307
|
+
},
|
|
308
|
+
markSent: () => {
|
|
309
|
+
planner.markSent();
|
|
310
|
+
syncState();
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function createSignalNativeReplyIdResolver(params) {
|
|
315
|
+
return createSignalNativeReplyIdPlan(params).use;
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
214
318
|
//#region extensions/signal/src/monitor/access-policy.ts
|
|
215
319
|
const SIGNAL_UUID_KIND = "plugin:signal-uuid";
|
|
216
320
|
const SIGNAL_GROUP_KIND = "plugin:signal-group";
|
|
@@ -556,8 +660,7 @@ function resolveSignalStatusReactionTimestamp(params) {
|
|
|
556
660
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
557
661
|
}
|
|
558
662
|
function hasSignalStatusReplyDeliveryFailure(result) {
|
|
559
|
-
|
|
560
|
-
return (failedCounts?.tool ?? 0) > 0 || (failedCounts?.block ?? 0) > 0 || (failedCounts?.final ?? 0) > 0;
|
|
663
|
+
return Object.values(result.settledReceipt?.counts ?? {}).some((counts) => counts.failedBeforeSend > 0 || counts.failedAfterSend > 0);
|
|
561
664
|
}
|
|
562
665
|
function resolveSignalStatusReactionEmojis(emojis) {
|
|
563
666
|
if (emojis?.stallHard !== void 0) return emojis;
|
|
@@ -775,6 +878,7 @@ function createSignalEventHandler(deps) {
|
|
|
775
878
|
};
|
|
776
879
|
const dispatcherOptions = {
|
|
777
880
|
...replyPipeline,
|
|
881
|
+
propagateRetryableNoSendFailure: true,
|
|
778
882
|
humanDelay: resolveHumanDelayConfig(deps.cfg, route.agentId),
|
|
779
883
|
typingCallbacks
|
|
780
884
|
};
|
|
@@ -795,6 +899,32 @@ function createSignalEventHandler(deps) {
|
|
|
795
899
|
chatType: entry.isGroup ? "group" : "direct"
|
|
796
900
|
});
|
|
797
901
|
},
|
|
902
|
+
durable: (payload, info) => {
|
|
903
|
+
if (info.kind !== "final") return false;
|
|
904
|
+
const replyPlan = createSignalNativeReplyIdPlan({
|
|
905
|
+
payload,
|
|
906
|
+
replyContext: nativeReplyContext,
|
|
907
|
+
replyToMode
|
|
908
|
+
});
|
|
909
|
+
const send = async (to, text, options) => {
|
|
910
|
+
entry.turnAdoptionLifecycle?.abortSignal.throwIfAborted();
|
|
911
|
+
deps.abortSignal?.throwIfAborted();
|
|
912
|
+
const result = await sendMessageSignal(to, text, {
|
|
913
|
+
...options,
|
|
914
|
+
baseUrl: deps.baseUrl,
|
|
915
|
+
account: deps.account,
|
|
916
|
+
maxBytes: deps.mediaMaxBytes,
|
|
917
|
+
accountId: deps.accountId
|
|
918
|
+
});
|
|
919
|
+
replyPlan.markSent();
|
|
920
|
+
return result;
|
|
921
|
+
};
|
|
922
|
+
return {
|
|
923
|
+
deps: { signal: send },
|
|
924
|
+
replyToId: replyPlan.peek() ?? null,
|
|
925
|
+
replyToMode
|
|
926
|
+
};
|
|
927
|
+
},
|
|
798
928
|
onError: (err, info) => {
|
|
799
929
|
deps.runtime.error?.(danger(`signal ${info.kind} reply failed: ${String(err)}`));
|
|
800
930
|
}
|
|
@@ -823,6 +953,7 @@ function createSignalEventHandler(deps) {
|
|
|
823
953
|
sessionKey: route.sessionKey
|
|
824
954
|
},
|
|
825
955
|
ctxPayload,
|
|
956
|
+
dispatchReplyFromConfig: deps.channelRuntime?.reply?.dispatchReplyFromConfig,
|
|
826
957
|
record: {
|
|
827
958
|
updateLastRoute: !entry.isGroup ? {
|
|
828
959
|
sessionKey: inboundLastRouteSessionKey,
|
|
@@ -994,7 +1125,7 @@ function createSignalEventHandler(deps) {
|
|
|
994
1125
|
if (!isSignalReplySessionInitConflictError(err)) throw err;
|
|
995
1126
|
if (deps.abortSignal?.aborted) return;
|
|
996
1127
|
await retrySignalInboundFlush(entries, admissionLifecycle, settle, err).catch(async (terminalError) => {
|
|
997
|
-
await
|
|
1128
|
+
await lifecycle?.onAbandoned();
|
|
998
1129
|
throw terminalError;
|
|
999
1130
|
});
|
|
1000
1131
|
}
|
|
@@ -1117,10 +1248,10 @@ function createSignalEventHandler(deps) {
|
|
|
1117
1248
|
});
|
|
1118
1249
|
return true;
|
|
1119
1250
|
}
|
|
1120
|
-
return async (event, turnAdoptionLifecycle) => {
|
|
1251
|
+
return async (event, turnAdoptionLifecycle, preparedPayload) => {
|
|
1121
1252
|
if (event.event !== "receive" || !event.data) return;
|
|
1122
|
-
let payload;
|
|
1123
|
-
try {
|
|
1253
|
+
let payload = preparedPayload ?? null;
|
|
1254
|
+
if (!preparedPayload) try {
|
|
1124
1255
|
payload = JSON.parse(event.data);
|
|
1125
1256
|
} catch (err) {
|
|
1126
1257
|
deps.runtime.error?.(`failed to parse event: ${String(err)}`);
|
|
@@ -1444,7 +1575,7 @@ const SignalIngressPermanentError = createChannelIngressError("SignalIngressPerm
|
|
|
1444
1575
|
function normalizeTimestamp(value) {
|
|
1445
1576
|
return asPositiveSafeInteger(value) ?? null;
|
|
1446
1577
|
}
|
|
1447
|
-
function
|
|
1578
|
+
function parseReceivePayload(event) {
|
|
1448
1579
|
if (event.event !== "receive" || !event.data) return null;
|
|
1449
1580
|
let parsed;
|
|
1450
1581
|
try {
|
|
@@ -1453,14 +1584,15 @@ function parseReceiveEnvelope(event) {
|
|
|
1453
1584
|
throw new SignalIngressPermanentError("parse-error", "Signal receive event contains invalid JSON", { cause: error });
|
|
1454
1585
|
}
|
|
1455
1586
|
if (!isRecord(parsed)) throw new SignalIngressPermanentError("parse-error", "Signal receive event must contain a JSON object");
|
|
1456
|
-
return
|
|
1587
|
+
return parsed;
|
|
1457
1588
|
}
|
|
1458
1589
|
function resolveDataMessage(envelope) {
|
|
1459
1590
|
if (isRecord(envelope.dataMessage)) return envelope.dataMessage;
|
|
1460
1591
|
return isRecord(envelope.editMessage?.dataMessage) ? envelope.editMessage.dataMessage : null;
|
|
1461
1592
|
}
|
|
1462
|
-
function inspectSignalIngressEvent(
|
|
1463
|
-
const
|
|
1593
|
+
function inspectSignalIngressEvent(prepared) {
|
|
1594
|
+
const payload = prepared[1] ??= parseReceivePayload(prepared[0]);
|
|
1595
|
+
const envelope = isRecord(payload?.envelope) ? payload.envelope : null;
|
|
1464
1596
|
if (!envelope || "syncMessage" in envelope) return null;
|
|
1465
1597
|
const dataMessage = resolveDataMessage(envelope);
|
|
1466
1598
|
const reactionMessage = isRecord(envelope.reactionMessage) ? envelope.reactionMessage : null;
|
|
@@ -1497,14 +1629,14 @@ async function startSignalIngressMonitor(params) {
|
|
|
1497
1629
|
const ingressQueue = queue;
|
|
1498
1630
|
const monitor = createChannelIngressMonitor({
|
|
1499
1631
|
queue: ingressQueue,
|
|
1500
|
-
inspect: (
|
|
1632
|
+
inspect: (prepared) => inspectSignalIngressEvent(prepared),
|
|
1501
1633
|
payload: {
|
|
1502
1634
|
version: 1,
|
|
1503
|
-
serialize: (event, { receivedAt }) => ({
|
|
1635
|
+
serialize: ([event], { receivedAt }) => ({
|
|
1504
1636
|
receivedAt,
|
|
1505
1637
|
event
|
|
1506
1638
|
}),
|
|
1507
|
-
deserialize: (body) => body.event,
|
|
1639
|
+
deserialize: (body) => [body.event, void 0],
|
|
1508
1640
|
encode: ({ body }) => ({
|
|
1509
1641
|
version: 1,
|
|
1510
1642
|
...body
|
|
@@ -1515,11 +1647,11 @@ async function startSignalIngressMonitor(params) {
|
|
|
1515
1647
|
}),
|
|
1516
1648
|
createClaimError: (_kind, claim) => new SignalIngressPermanentError("unsupported-event", `Signal ingress row ${claim.id} has an invalid payload`)
|
|
1517
1649
|
},
|
|
1518
|
-
deliver: (event, lifecycle) => params.dispatch(event, lifecycle),
|
|
1519
|
-
onDurableAdmission: async (_event, { facts }) => {
|
|
1650
|
+
deliver: ([event, parsedPayload], lifecycle) => parsedPayload ? params.dispatch(event, lifecycle, parsedPayload) : void 0,
|
|
1651
|
+
onDurableAdmission: async (_event, { facts, isNew }) => {
|
|
1520
1652
|
const { numberAliasEventId } = facts;
|
|
1521
1653
|
if (!numberAliasEventId) return;
|
|
1522
|
-
if (!await ingressQueue.complete(numberAliasEventId)) await ingressQueue.complete(facts.eventId);
|
|
1654
|
+
if (!await ingressQueue.complete(numberAliasEventId) && isNew) await ingressQueue.complete(facts.eventId);
|
|
1523
1655
|
},
|
|
1524
1656
|
pollIntervalMs: SIGNAL_INGRESS_DRAIN_INTERVAL_MS,
|
|
1525
1657
|
retention: {
|
|
@@ -1537,7 +1669,7 @@ async function startSignalIngressMonitor(params) {
|
|
|
1537
1669
|
monitor.start();
|
|
1538
1670
|
return {
|
|
1539
1671
|
receive: async (event) => {
|
|
1540
|
-
await monitor.admit(event);
|
|
1672
|
+
await monitor.admit([event, void 0]);
|
|
1541
1673
|
await monitor.waitForPumpIdle();
|
|
1542
1674
|
},
|
|
1543
1675
|
stop: monitor.stop,
|
|
@@ -1684,25 +1816,6 @@ function buildSignalReactionSystemEventText(params) {
|
|
|
1684
1816
|
const withTarget = params.targetLabel ? `${base} from ${params.targetLabel}` : base;
|
|
1685
1817
|
return params.groupLabel ? `${withTarget} in ${params.groupLabel}` : withTarget;
|
|
1686
1818
|
}
|
|
1687
|
-
async function waitForSignalDaemonReady(params) {
|
|
1688
|
-
await (params.waitForTransportReadyFn ?? waitForTransportReady)({
|
|
1689
|
-
label: "signal daemon",
|
|
1690
|
-
timeoutMs: params.timeoutMs,
|
|
1691
|
-
logAfterMs: params.logAfterMs,
|
|
1692
|
-
logIntervalMs: params.logIntervalMs,
|
|
1693
|
-
pollIntervalMs: 150,
|
|
1694
|
-
abortSignal: params.abortSignal,
|
|
1695
|
-
runtime: params.runtime,
|
|
1696
|
-
check: async () => {
|
|
1697
|
-
const res = await signalCheck(params.baseUrl, 1e3);
|
|
1698
|
-
if (res.ok) return { ok: true };
|
|
1699
|
-
return {
|
|
1700
|
-
ok: false,
|
|
1701
|
-
error: res.error ?? (res.status ? `HTTP ${res.status}` : "unreachable")
|
|
1702
|
-
};
|
|
1703
|
-
}
|
|
1704
|
-
});
|
|
1705
|
-
}
|
|
1706
1819
|
const SIGNAL_ATTACHMENT_RPC_RESPONSE_HEADROOM_BYTES = 64 * 1024;
|
|
1707
1820
|
const SIGNAL_BASE64_OVERHEAD_NUMERATOR = 4;
|
|
1708
1821
|
const SIGNAL_BASE64_OVERHEAD_DENOMINATOR = 3;
|
|
@@ -1814,45 +1927,19 @@ async function deliverReplies(params) {
|
|
|
1814
1927
|
}
|
|
1815
1928
|
}
|
|
1816
1929
|
}
|
|
1817
|
-
function resolveSignalNativeReplyOptions(params) {
|
|
1818
|
-
if (params.payload.replyToCurrent === false) return {};
|
|
1819
|
-
const payloadReplyToId = normalizeOptionalString(params.payload.replyToId);
|
|
1820
|
-
const isExplicitCurrentReply = params.payload.replyToTag === true || params.payload.replyToCurrent === true;
|
|
1821
|
-
if (!payloadReplyToId && !isExplicitCurrentReply && params.replyContext?.allowImplicitCurrentMessage === false) return {};
|
|
1822
|
-
const contextReplyToId = normalizeOptionalString(params.replyContext?.replyToId);
|
|
1823
|
-
if (!contextReplyToId || payloadReplyToId && payloadReplyToId !== contextReplyToId) return {};
|
|
1824
|
-
const replyToId = payloadReplyToId ?? contextReplyToId;
|
|
1825
|
-
const replyToAuthor = normalizeOptionalString(params.replyContext?.author);
|
|
1826
|
-
if (!replyToAuthor) return { replyToId };
|
|
1827
|
-
return {
|
|
1828
|
-
replyToId,
|
|
1829
|
-
replyToAuthor,
|
|
1830
|
-
replyToBody: params.replyContext?.body ?? ""
|
|
1831
|
-
};
|
|
1832
|
-
}
|
|
1833
|
-
function isSignalStatusNoticePayload(payload) {
|
|
1834
|
-
return Boolean(payload.isCompactionNotice || payload.isFallbackNotice || payload.isStatusNotice);
|
|
1835
|
-
}
|
|
1836
1930
|
function createSignalNativeReplyResolver(params) {
|
|
1837
|
-
const
|
|
1838
|
-
if (!nativeReply.replyToId) return () => ({});
|
|
1839
|
-
const isExplicitReply = params.payload.replyToTag === true || params.payload.replyToCurrent === true;
|
|
1840
|
-
const isStatusNotice = isSignalStatusNoticePayload(params.payload);
|
|
1841
|
-
if (isStatusNotice && params.replyToMode === "off") return () => ({});
|
|
1842
|
-
if (isExplicitReply) return () => nativeReply;
|
|
1843
|
-
if (isStatusNotice) return () => nativeReply;
|
|
1844
|
-
const planner = createReplyReferencePlanner({
|
|
1845
|
-
replyToMode: params.replyToMode,
|
|
1846
|
-
existingId: nativeReply.replyToId,
|
|
1847
|
-
hasReplied: params.replyContext?.state?.hasReplied
|
|
1848
|
-
});
|
|
1931
|
+
const nextReplyToId = createSignalNativeReplyIdResolver(params);
|
|
1849
1932
|
return () => {
|
|
1850
|
-
const replyToId =
|
|
1851
|
-
if (
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
replyToId
|
|
1855
|
-
|
|
1933
|
+
const replyToId = nextReplyToId();
|
|
1934
|
+
if (!replyToId) return {};
|
|
1935
|
+
const replyToAuthor = normalizeOptionalString(params.replyContext?.author);
|
|
1936
|
+
return {
|
|
1937
|
+
replyToId,
|
|
1938
|
+
...replyToAuthor ? {
|
|
1939
|
+
replyToAuthor,
|
|
1940
|
+
replyToBody: params.replyContext?.body ?? ""
|
|
1941
|
+
} : {}
|
|
1942
|
+
};
|
|
1856
1943
|
};
|
|
1857
1944
|
}
|
|
1858
1945
|
async function monitorSignalProvider(opts = {}) {
|
|
@@ -1898,11 +1985,27 @@ async function monitorSignalProvider(opts = {}) {
|
|
|
1898
1985
|
const monitorTaskRunner = createSignalMonitorTaskRunner(runtime);
|
|
1899
1986
|
let daemonHandle = null;
|
|
1900
1987
|
let ingressMonitor;
|
|
1988
|
+
const startupDeadline = Date.now() + startupTimeoutMs;
|
|
1901
1989
|
if (autoStart) {
|
|
1902
1990
|
const cliPath = opts.cliPath ?? managedTransport?.cliPath ?? "signal-cli";
|
|
1903
1991
|
const configPath = normalizeOptionalString(opts.configPath) ?? normalizeOptionalString(managedTransport?.configPath);
|
|
1904
|
-
const httpHost = opts.httpHost ?? managedTransport?.httpHost ?? "127.0.0.1";
|
|
1992
|
+
const httpHost = normalizeSignalTransportHost(opts.httpHost ?? managedTransport?.httpHost ?? "127.0.0.1");
|
|
1905
1993
|
const httpPort = opts.httpPort ?? managedTransport?.httpPort ?? 8080;
|
|
1994
|
+
const startupTimeoutSignal = AbortSignal.timeout(startupTimeoutMs);
|
|
1995
|
+
const endpointProbeSignal = opts.abortSignal ? AbortSignal.any([opts.abortSignal, startupTimeoutSignal]) : startupTimeoutSignal;
|
|
1996
|
+
try {
|
|
1997
|
+
await assertSignalDaemonEndpointAvailable({
|
|
1998
|
+
httpHost,
|
|
1999
|
+
httpPort,
|
|
2000
|
+
abortSignal: endpointProbeSignal
|
|
2001
|
+
});
|
|
2002
|
+
} catch (error) {
|
|
2003
|
+
if (opts.abortSignal?.aborted) return;
|
|
2004
|
+
if (startupTimeoutSignal.aborted || Date.now() >= startupDeadline) throw new Error(`signal daemon startup timed out after ${startupTimeoutMs}ms while checking its endpoint`, { cause: error });
|
|
2005
|
+
throw error;
|
|
2006
|
+
}
|
|
2007
|
+
if (opts.abortSignal?.aborted) return;
|
|
2008
|
+
if (Date.now() >= startupDeadline) throw new Error(`signal daemon startup timed out after ${startupTimeoutMs}ms before starting`);
|
|
1906
2009
|
daemonHandle = spawnSignalDaemon({
|
|
1907
2010
|
cliPath,
|
|
1908
2011
|
...configPath ? { configPath } : {},
|
|
@@ -1924,7 +2027,7 @@ async function monitorSignalProvider(opts = {}) {
|
|
|
1924
2027
|
await waitForSignalDaemonReady({
|
|
1925
2028
|
baseUrl,
|
|
1926
2029
|
abortSignal: daemonLifecycle.abortSignal,
|
|
1927
|
-
|
|
2030
|
+
startupDeadlineMs: startupDeadline,
|
|
1928
2031
|
logAfterMs: 1e4,
|
|
1929
2032
|
logIntervalMs: 1e4,
|
|
1930
2033
|
runtime,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
//#region extensions/signal/src/normalize.ts
|
|
3
|
+
function normalizeSignalReactionRecipient(raw) {
|
|
4
|
+
const withoutSignal = raw.trim().replace(/^signal:/i, "").trim();
|
|
5
|
+
return /^uuid:/i.test(withoutSignal) ? withoutSignal.slice(5).trim() : withoutSignal;
|
|
6
|
+
}
|
|
7
|
+
function normalizeSignalMessagingTarget(raw) {
|
|
8
|
+
const trimmed = raw.trim();
|
|
9
|
+
if (!trimmed) return;
|
|
10
|
+
let normalized = trimmed;
|
|
11
|
+
if (normalizeLowercaseStringOrEmpty(normalized).startsWith("signal:")) normalized = normalized.slice(7).trim();
|
|
12
|
+
if (!normalized) return;
|
|
13
|
+
const lower = normalizeLowercaseStringOrEmpty(normalized);
|
|
14
|
+
if (lower.startsWith("group:")) {
|
|
15
|
+
const id = normalized.slice(6).trim();
|
|
16
|
+
return id ? `group:${id}` : void 0;
|
|
17
|
+
}
|
|
18
|
+
if (lower.startsWith("username:")) {
|
|
19
|
+
const id = normalized.slice(9).trim();
|
|
20
|
+
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
|
|
21
|
+
}
|
|
22
|
+
if (lower.startsWith("u:")) {
|
|
23
|
+
const id = normalized.slice(2).trim();
|
|
24
|
+
return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
|
|
25
|
+
}
|
|
26
|
+
if (lower.startsWith("uuid:")) {
|
|
27
|
+
const id = normalized.slice(5).trim();
|
|
28
|
+
return id ? normalizeLowercaseStringOrEmpty(id) : void 0;
|
|
29
|
+
}
|
|
30
|
+
return normalizeLowercaseStringOrEmpty(normalized);
|
|
31
|
+
}
|
|
32
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
33
|
+
const UUID_COMPACT_PATTERN = /^[0-9a-f]{32}$/i;
|
|
34
|
+
function looksLikeSignalTargetId(raw, normalized) {
|
|
35
|
+
const candidates = normalizeStringEntries([raw, normalized ?? ""]);
|
|
36
|
+
for (const candidate of candidates) {
|
|
37
|
+
if (/^(signal:)?(group:|username:|u:)/i.test(candidate)) return true;
|
|
38
|
+
if (/^(signal:)?uuid:/i.test(candidate)) {
|
|
39
|
+
const stripped = candidate.replace(/^signal:/i, "").replace(/^uuid:/i, "").trim();
|
|
40
|
+
if (!stripped) continue;
|
|
41
|
+
if (UUID_PATTERN.test(stripped) || UUID_COMPACT_PATTERN.test(stripped)) return true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const withoutSignalPrefix = candidate.replace(/^signal:/i, "").trim();
|
|
45
|
+
if (UUID_PATTERN.test(withoutSignalPrefix) || UUID_COMPACT_PATTERN.test(withoutSignalPrefix)) return true;
|
|
46
|
+
if (/^\+?\d{3,}$/.test(withoutSignalPrefix)) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { normalizeSignalMessagingTarget as n, normalizeSignalReactionRecipient as r, looksLikeSignalTargetId as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { t as detectSignalTransport } from "./transport-detection-
|
|
2
|
+
import { t as detectSignalTransport } from "./transport-detection-BSXAOmuH.js";
|
|
3
3
|
import { n as signalRpcRequest, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
|
|
4
4
|
import { runChannelProbe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
5
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { i as resolveSignalTarget } from "./approval-auth-BsYHLTHK.js";
|
|
3
|
+
import { c as resolveSignalApprovalTargetAuthorKeys, s as resolveSignalApprovalConversationKey } from "./approval-reactions-DB-86mqK.js";
|
|
4
4
|
import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
5
5
|
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
6
6
|
//#region extensions/signal/src/question-reactions.ts
|
|
@@ -1,58 +1,33 @@
|
|
|
1
|
-
import { i as resolveSignalAccount } from "./accounts-
|
|
1
|
+
import { i as resolveSignalAccount } from "./accounts-DO4HMqaK.js";
|
|
2
|
+
import { r as normalizeSignalReactionRecipient } from "./normalize-l_b99hap.js";
|
|
2
3
|
import { n as signalRpcRequest } from "./client-adapter-D9SNPaNx.js";
|
|
3
|
-
import { t as resolveSignalRpcContext } from "./rpc-context-
|
|
4
|
-
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
+
import { t as resolveSignalRpcContext } from "./rpc-context-dXSy4NtF.js";
|
|
5
5
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
6
6
|
//#region extensions/signal/src/send-reactions.ts
|
|
7
|
-
function normalizeSignalId(raw) {
|
|
8
|
-
const trimmed = raw.trim();
|
|
9
|
-
if (!trimmed) return "";
|
|
10
|
-
return trimmed.replace(/^signal:/i, "").trim();
|
|
11
|
-
}
|
|
12
|
-
function normalizeSignalUuid(raw) {
|
|
13
|
-
const trimmed = normalizeSignalId(raw);
|
|
14
|
-
if (!trimmed) return "";
|
|
15
|
-
if (normalizeLowercaseStringOrEmpty(trimmed).startsWith("uuid:")) return trimmed.slice(5).trim();
|
|
16
|
-
return trimmed;
|
|
17
|
-
}
|
|
18
|
-
function resolveTargetAuthorParams(params) {
|
|
19
|
-
const candidates = [
|
|
20
|
-
params.targetAuthor,
|
|
21
|
-
params.targetAuthorUuid,
|
|
22
|
-
params.fallback
|
|
23
|
-
];
|
|
24
|
-
for (const candidate of candidates) {
|
|
25
|
-
const raw = candidate?.trim();
|
|
26
|
-
if (!raw) continue;
|
|
27
|
-
const normalized = normalizeSignalUuid(raw);
|
|
28
|
-
if (normalized) return { targetAuthor: normalized };
|
|
29
|
-
}
|
|
30
|
-
return {};
|
|
31
|
-
}
|
|
32
7
|
async function sendReactionSignalCore(params) {
|
|
33
8
|
const accountInfo = resolveSignalAccount({
|
|
34
9
|
cfg: requireRuntimeConfig(params.opts.cfg, "Signal reactions"),
|
|
35
10
|
accountId: params.opts.accountId
|
|
36
11
|
});
|
|
37
12
|
const { baseUrl, account } = resolveSignalRpcContext(params.opts, accountInfo);
|
|
38
|
-
const normalizedRecipient =
|
|
13
|
+
const normalizedRecipient = normalizeSignalReactionRecipient(params.recipient);
|
|
39
14
|
const groupId = params.opts.groupId?.trim();
|
|
40
15
|
const operation = `Signal reaction${params.remove ? " removal" : ""}`;
|
|
41
16
|
if (!normalizedRecipient && !groupId) throw new Error(`Recipient or groupId is required for ${operation}`);
|
|
42
17
|
if (!Number.isFinite(params.targetTimestamp) || params.targetTimestamp <= 0) throw new Error(`Valid targetTimestamp is required for ${operation}`);
|
|
43
18
|
const normalizedEmoji = params.emoji?.trim();
|
|
44
19
|
if (!normalizedEmoji) throw new Error(`Emoji is required for ${operation}`);
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (groupId && !
|
|
20
|
+
const targetAuthor = [
|
|
21
|
+
params.opts.targetAuthor,
|
|
22
|
+
params.opts.targetAuthorUuid,
|
|
23
|
+
normalizedRecipient
|
|
24
|
+
].map((candidate) => normalizeSignalReactionRecipient(candidate ?? "")).find(Boolean);
|
|
25
|
+
if (groupId && !targetAuthor) throw new Error(`targetAuthor is required for group reaction${params.remove ? " removal" : "s"}`);
|
|
51
26
|
const requestParams = {
|
|
52
27
|
emoji: normalizedEmoji,
|
|
53
28
|
targetTimestamp: params.targetTimestamp,
|
|
54
29
|
...params.remove ? { remove: true } : {},
|
|
55
|
-
...
|
|
30
|
+
...targetAuthor ? { targetAuthor } : {}
|
|
56
31
|
};
|
|
57
32
|
if (normalizedRecipient) requestParams.recipients = [normalizedRecipient];
|
|
58
33
|
if (groupId) requestParams.groupIds = [groupId];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-
|
|
1
|
+
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-Ch0dk2sh.js";
|
|
2
2
|
export { removeReactionSignal, sendReactionSignal };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "./accounts-DO4HMqaK.js";
|
|
2
|
+
//#region extensions/signal/src/rpc-context.ts
|
|
3
|
+
function resolveSignalRpcContext(opts, accountInfo) {
|
|
4
|
+
const baseUrlOverride = opts.baseUrl?.trim();
|
|
5
|
+
const accountOverride = opts.account?.trim();
|
|
6
|
+
if ((!baseUrlOverride || !accountOverride) && !accountInfo) throw new Error("Signal account config is required when baseUrl or account is missing");
|
|
7
|
+
const baseUrl = baseUrlOverride || accountInfo?.baseUrl;
|
|
8
|
+
if (!baseUrl) throw new Error("Signal base URL is required");
|
|
9
|
+
return {
|
|
10
|
+
baseUrl,
|
|
11
|
+
account: accountOverride || accountInfo?.config.account?.trim() || void 0
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { resolveSignalRpcContext as t };
|