@openclaw/signal 2026.6.11 → 2026.7.1-beta.2
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-hOCHbEhX.js → accounts-B7Rz3_xV.js} +2 -1
- package/dist/api.js +8 -8
- package/dist/approval-auth-DPVK9A_l.js +151 -0
- package/dist/{approval-handler.runtime-CeJI1wow.js → approval-handler.runtime-BZLgs7EM.js} +28 -8
- package/dist/{send-CBlFUkY_.js → approval-reactions-5x1kmQEq.js} +137 -277
- package/dist/{channel-LmY2UpOt.js → channel-BfWp-F-r.js} +177 -46
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B0-YpkC4.js → channel.runtime-Ks7GIWM1.js} +3 -3
- package/dist/{reaction-runtime-api-C_PQ45D9.js → client-adapter-Dm8-wT2n.js} +9 -130
- package/dist/contract-api.js +1 -1
- package/dist/{install-signal-cli-CXgTF3de.js → install-signal-cli-TwhJ0DGy.js} +7 -5
- package/dist/{message-actions-Bue0g2Kc.js → message-actions-Cs9XckSd.js} +7 -30
- package/dist/{monitor-CUhIKHJo.js → monitor-C9SiyrFt.js} +205 -37
- package/dist/{probe-BQ_Izoya.js → probe-BL2BqTbG.js} +1 -1
- package/dist/reaction-runtime-api-BkAxQPGs.js +115 -0
- package/dist/reaction-runtime-api.js +1 -1
- package/dist/rpc-context-DbFMe7am.js +17 -0
- package/dist/runtime-api.js +8 -7
- package/dist/send-CLzc3RUg.js +187 -0
- package/dist/{send.runtime-CfaZd8X4.js → send.runtime-DgijYwpJ.js} +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +18 -0
- package/package.json +4 -4
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-B6O4k8xg.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
|
|
6
|
-
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
7
|
-
import { kindFromMime, resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
|
|
3
|
+
import { i as resolveSignalTarget, n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-DPVK9A_l.js";
|
|
4
|
+
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
8
5
|
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
9
6
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
7
|
import { buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, resolveApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
11
8
|
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
12
|
-
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
13
9
|
import { matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
10
|
+
import { getExecApprovalReplyMetadata } from "openclaw/plugin-sdk/approval-reply-runtime";
|
|
14
11
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
15
12
|
//#region extensions/signal/src/runtime.ts
|
|
16
13
|
const { setRuntime: setSignalRuntime, getRuntime: getSignalRuntime, tryGetRuntime: getOptionalSignalRuntime, clearRuntime: clearSignalRuntime } = createPluginRuntimeStore({
|
|
@@ -19,10 +16,25 @@ const { setRuntime: setSignalRuntime, getRuntime: getSignalRuntime, tryGetRuntim
|
|
|
19
16
|
});
|
|
20
17
|
//#endregion
|
|
21
18
|
//#region extensions/signal/src/approval-reactions.ts
|
|
22
|
-
|
|
19
|
+
var approval_reactions_exports = /* @__PURE__ */ __exportAll({
|
|
20
|
+
addSignalApprovalReactionHintToStructuredPayload: () => addSignalApprovalReactionHintToStructuredPayload,
|
|
21
|
+
addSignalApprovalReactionHintToText: () => addSignalApprovalReactionHintToText,
|
|
22
|
+
buildSignalApprovalReactionHint: () => buildSignalApprovalReactionHint,
|
|
23
|
+
clearSignalApprovalReactionTargetsForTest: () => clearSignalApprovalReactionTargetsForTest,
|
|
24
|
+
hasSignalApprovalReactionApprovers: () => hasSignalApprovalReactionApprovers,
|
|
25
|
+
listSignalApprovalReactionBindings: () => listSignalApprovalReactionBindings,
|
|
26
|
+
maybeResolveSignalApprovalReaction: () => maybeResolveSignalApprovalReaction,
|
|
27
|
+
registerSignalApprovalReactionTarget: () => registerSignalApprovalReactionTarget,
|
|
28
|
+
registerSignalApprovalReactionTargetForDeliveredPayload: () => registerSignalApprovalReactionTargetForDeliveredPayload,
|
|
29
|
+
resolveSignalApprovalConversationKey: () => resolveSignalApprovalConversationKey,
|
|
30
|
+
resolveSignalApprovalReactionTargetWithPersistence: () => resolveSignalApprovalReactionTargetWithPersistence,
|
|
31
|
+
resolveSignalApprovalTargetAuthorKeys: () => resolveSignalApprovalTargetAuthorKeys,
|
|
32
|
+
unregisterSignalApprovalReactionTarget: () => unregisterSignalApprovalReactionTarget
|
|
33
|
+
});
|
|
34
|
+
const PERSISTENT_NAMESPACE = "signal.approval-reactions.v2";
|
|
23
35
|
const PERSISTENT_MAX_ENTRIES = 1e3;
|
|
24
36
|
const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
|
|
25
|
-
|
|
37
|
+
const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver-BR0MioAA.js"));
|
|
26
38
|
const signalApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
27
39
|
namespace: PERSISTENT_NAMESPACE,
|
|
28
40
|
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
@@ -31,10 +43,7 @@ const signalApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
|
31
43
|
logPersistentError: reportPersistentApprovalReactionError,
|
|
32
44
|
readPersistedTarget
|
|
33
45
|
});
|
|
34
|
-
|
|
35
|
-
resolverRuntimePromise ??= import("./approval-resolver-BR0MioAA.js");
|
|
36
|
-
return resolverRuntimePromise;
|
|
37
|
-
}
|
|
46
|
+
const loadApprovalResolver = resolverRuntimeLoader;
|
|
38
47
|
function resolveApprovalKindFromId(approvalId) {
|
|
39
48
|
return approvalId.startsWith("plugin:") ? "plugin" : "exec";
|
|
40
49
|
}
|
|
@@ -67,10 +76,25 @@ function targetAccountMatches(params) {
|
|
|
67
76
|
const routeAccountId = normalizeOptionalString(params.routeAccountId);
|
|
68
77
|
return Boolean(routeAccountId && normalizeAccountId(routeAccountId) === normalizeAccountId(configuredAccountId));
|
|
69
78
|
}
|
|
79
|
+
function resolveSignalApprovalRouteTarget(params) {
|
|
80
|
+
try {
|
|
81
|
+
return resolveSignalTarget({
|
|
82
|
+
cfg: params.cfg,
|
|
83
|
+
accountId: params.accountId,
|
|
84
|
+
input: params.to
|
|
85
|
+
})?.to ?? normalizeSignalMessagingTarget(params.to) ?? null;
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
70
90
|
function hasMatchingSignalApprovalReactionTarget(params) {
|
|
71
91
|
return (params.config.targets ?? []).some((target) => {
|
|
72
92
|
if (normalizeLowercaseStringOrEmpty(target.channel) !== "signal") return false;
|
|
73
|
-
const configuredTo =
|
|
93
|
+
const configuredTo = resolveSignalApprovalRouteTarget({
|
|
94
|
+
cfg: params.cfg,
|
|
95
|
+
accountId: target.accountId ?? params.route.accountId,
|
|
96
|
+
to: target.to
|
|
97
|
+
});
|
|
74
98
|
if (!configuredTo || configuredTo !== params.route.to) return false;
|
|
75
99
|
return targetAccountMatches({
|
|
76
100
|
routeAccountId: params.route.accountId,
|
|
@@ -89,6 +113,7 @@ function isSignalApprovalReactionRouteStillEnabled(params) {
|
|
|
89
113
|
config,
|
|
90
114
|
route: params.target.route
|
|
91
115
|
}) && hasMatchingSignalApprovalReactionTarget({
|
|
116
|
+
cfg: params.cfg,
|
|
92
117
|
config,
|
|
93
118
|
route: params.target.route
|
|
94
119
|
});
|
|
@@ -101,6 +126,17 @@ function isSignalApprovalReactionRouteStillEnabled(params) {
|
|
|
101
126
|
function resolveSignalApprovalConversationKey(to) {
|
|
102
127
|
return normalizeSignalMessagingTarget(to) ?? null;
|
|
103
128
|
}
|
|
129
|
+
function resolveSignalApprovalConversationKeyForDeliveredTarget(params) {
|
|
130
|
+
try {
|
|
131
|
+
return resolveSignalTarget({
|
|
132
|
+
cfg: params.cfg,
|
|
133
|
+
accountId: params.accountId,
|
|
134
|
+
input: params.to
|
|
135
|
+
})?.to ?? resolveSignalApprovalConversationKey(params.to);
|
|
136
|
+
} catch {
|
|
137
|
+
return resolveSignalApprovalConversationKey(params.to);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
104
140
|
function normalizeSignalApprovalTargetAuthorKey(value) {
|
|
105
141
|
const normalized = normalizeOptionalString(value);
|
|
106
142
|
if (!normalized) return null;
|
|
@@ -173,39 +209,22 @@ function insertSignalApprovalReactionHintNearHeader(params) {
|
|
|
173
209
|
return `${params.hint}\n\n${params.text}`;
|
|
174
210
|
}
|
|
175
211
|
function addSignalApprovalReactionHintToText(params) {
|
|
176
|
-
if (
|
|
212
|
+
if (hasSignalApprovalReactionHintText(params.text)) return params.text;
|
|
177
213
|
const hint = buildSignalApprovalReactionHint(params.allowedDecisions);
|
|
178
214
|
return hint ? insertSignalApprovalReactionHintNearHeader({
|
|
179
215
|
text: params.text,
|
|
180
216
|
hint
|
|
181
217
|
}) : params.text;
|
|
182
218
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
if (normalized === "always") return "allow-always";
|
|
186
|
-
if (normalized === "allow-once" || normalized === "allow-always" || normalized === "deny") return normalized;
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
function extractSignalApprovalPromptBinding(text) {
|
|
190
|
-
const allowedDecisions = [];
|
|
191
|
-
let approvalId = "";
|
|
192
|
-
for (const line of text.split(/\r?\n/)) {
|
|
193
|
-
const match = line.match(/\/approve(?:@[^\s]+)?\s+([A-Za-z0-9][A-Za-z0-9._:-]*)\s+(.+)$/i);
|
|
194
|
-
if (!match) continue;
|
|
195
|
-
if (approvalId && match[1] !== approvalId) continue;
|
|
196
|
-
approvalId ||= match[1];
|
|
197
|
-
for (const decisionText of match[2].split(/[\s|,]+/)) {
|
|
198
|
-
const decision = normalizeApprovalDecision(decisionText);
|
|
199
|
-
if (decision && !allowedDecisions.includes(decision)) allowedDecisions.push(decision);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return approvalId && allowedDecisions.length > 0 ? {
|
|
203
|
-
approvalId,
|
|
204
|
-
allowedDecisions
|
|
205
|
-
} : null;
|
|
219
|
+
function hasSignalApprovalReactionHintText(text) {
|
|
220
|
+
return /(^|\n)React with:\s*(\n|$)/i.test(text ?? "");
|
|
206
221
|
}
|
|
207
222
|
function buildTargetRoute(params) {
|
|
208
|
-
const to =
|
|
223
|
+
const to = resolveSignalApprovalRouteTarget({
|
|
224
|
+
cfg: params.cfg,
|
|
225
|
+
accountId: params.accountId,
|
|
226
|
+
to: params.to
|
|
227
|
+
});
|
|
209
228
|
if (!to) return null;
|
|
210
229
|
const route = {
|
|
211
230
|
deliveryMode: "target",
|
|
@@ -217,39 +236,11 @@ function buildTargetRoute(params) {
|
|
|
217
236
|
return isSignalApprovalReactionRouteStillEnabled({
|
|
218
237
|
cfg: params.cfg,
|
|
219
238
|
target: {
|
|
220
|
-
approvalKind: resolveApprovalKindFromId(params.approvalId),
|
|
239
|
+
approvalKind: params.approvalKind ?? resolveApprovalKindFromId(params.approvalId),
|
|
221
240
|
route
|
|
222
241
|
}
|
|
223
242
|
}) ? route : null;
|
|
224
243
|
}
|
|
225
|
-
function shouldAppendSignalApprovalReactionHintForOutboundMessage(params) {
|
|
226
|
-
const binding = extractSignalApprovalPromptBinding(params.text);
|
|
227
|
-
if (!binding) return false;
|
|
228
|
-
if (resolveSignalApprovalTargetAuthorKeys(params).length === 0) return false;
|
|
229
|
-
if (!hasSignalApprovalReactionApprovers({
|
|
230
|
-
cfg: params.cfg,
|
|
231
|
-
accountId: params.accountId
|
|
232
|
-
})) return false;
|
|
233
|
-
return Boolean(buildTargetRoute({
|
|
234
|
-
cfg: params.cfg,
|
|
235
|
-
accountId: params.accountId,
|
|
236
|
-
to: params.to,
|
|
237
|
-
approvalId: binding.approvalId,
|
|
238
|
-
agentId: params.agentId,
|
|
239
|
-
sessionKey: params.sessionKey
|
|
240
|
-
}));
|
|
241
|
-
}
|
|
242
|
-
function appendSignalApprovalReactionHintForOutboundMessage(params) {
|
|
243
|
-
const binding = extractSignalApprovalPromptBinding(params.text);
|
|
244
|
-
if (!binding || !shouldAppendSignalApprovalReactionHintForOutboundMessage({
|
|
245
|
-
...params,
|
|
246
|
-
text: params.text
|
|
247
|
-
})) return params.text;
|
|
248
|
-
return addSignalApprovalReactionHintToText({
|
|
249
|
-
text: params.text,
|
|
250
|
-
allowedDecisions: binding.allowedDecisions
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
244
|
function hasSignalApprovalReactionApprovers(params) {
|
|
254
245
|
return getSignalApprovalApprovers(params).length > 0;
|
|
255
246
|
}
|
|
@@ -273,7 +264,7 @@ function registerSignalApprovalReactionTarget(params) {
|
|
|
273
264
|
};
|
|
274
265
|
const target = {
|
|
275
266
|
approvalId,
|
|
276
|
-
approvalKind: resolveApprovalKindFromId(approvalId),
|
|
267
|
+
approvalKind: params.approvalKind ?? resolveApprovalKindFromId(approvalId),
|
|
277
268
|
allowedDecisions,
|
|
278
269
|
targetAuthorKeys,
|
|
279
270
|
route
|
|
@@ -281,31 +272,88 @@ function registerSignalApprovalReactionTarget(params) {
|
|
|
281
272
|
signalApprovalReactionTargets.register(key, target, { ttlMs: params.ttlMs });
|
|
282
273
|
return target;
|
|
283
274
|
}
|
|
284
|
-
function
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
287
|
-
|
|
288
|
-
if (!
|
|
289
|
-
|
|
275
|
+
function addSignalApprovalReactionHintToStructuredPayload(params) {
|
|
276
|
+
const metadata = getExecApprovalReplyMetadata(params.payload);
|
|
277
|
+
if (!metadata?.allowedDecisions || metadata.allowedDecisions.length === 0) return null;
|
|
278
|
+
if (resolveSignalApprovalTargetAuthorKeys(params).length === 0) return null;
|
|
279
|
+
if (!hasSignalApprovalReactionApprovers({
|
|
280
|
+
cfg: params.cfg,
|
|
281
|
+
accountId: params.accountId
|
|
282
|
+
})) return null;
|
|
283
|
+
if (!buildTargetRoute({
|
|
290
284
|
cfg: params.cfg,
|
|
291
285
|
accountId: params.accountId,
|
|
292
286
|
to: params.to,
|
|
293
|
-
approvalId:
|
|
294
|
-
|
|
295
|
-
|
|
287
|
+
approvalId: metadata.approvalId,
|
|
288
|
+
approvalKind: metadata.approvalKind,
|
|
289
|
+
agentId: metadata.agentId,
|
|
290
|
+
sessionKey: metadata.sessionKey
|
|
291
|
+
}) || !params.payload.text) return null;
|
|
292
|
+
return {
|
|
293
|
+
...params.payload,
|
|
294
|
+
text: addSignalApprovalReactionHintToText({
|
|
295
|
+
text: params.payload.text,
|
|
296
|
+
allowedDecisions: metadata.allowedDecisions
|
|
297
|
+
})
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function readSignalDeliveryVisibleText(result) {
|
|
301
|
+
const meta = result.meta;
|
|
302
|
+
const visibleText = meta?.signalVisibleText ?? meta?.visibleText;
|
|
303
|
+
return typeof visibleText === "string" ? visibleText : null;
|
|
304
|
+
}
|
|
305
|
+
function listDeliveredSignalMessageIdsWithVisibleHint(params) {
|
|
306
|
+
const signalResults = params.results.filter((result) => !result.channel || normalizeLowercaseStringOrEmpty(result.channel) === "signal");
|
|
307
|
+
const resultsWithVisibleText = signalResults.filter((result) => readSignalDeliveryVisibleText(result) !== null);
|
|
308
|
+
const candidates = resultsWithVisibleText.length > 0 ? resultsWithVisibleText : signalResults;
|
|
309
|
+
if (resultsWithVisibleText.length === 0 && candidates.length !== 1) return [];
|
|
310
|
+
const ids = candidates.filter((result) => resultsWithVisibleText.length > 0 ? hasSignalApprovalReactionHintText(readSignalDeliveryVisibleText(result)) : hasSignalApprovalReactionHintText(params.payload.text)).map((result) => normalizeOptionalString(result.messageId)).filter((messageId) => Boolean(messageId && messageId !== "unknown"));
|
|
311
|
+
return Array.from(new Set(ids));
|
|
312
|
+
}
|
|
313
|
+
function registerSignalApprovalReactionTargetForDeliveredPayload(params) {
|
|
314
|
+
if (normalizeLowercaseStringOrEmpty(params.target.channel) !== "signal") return false;
|
|
315
|
+
const metadata = getExecApprovalReplyMetadata(params.payload);
|
|
316
|
+
if (!metadata?.allowedDecisions || metadata.allowedDecisions.length === 0) return false;
|
|
317
|
+
if (!hasSignalApprovalReactionHintText(params.payload.text)) return false;
|
|
318
|
+
if (!hasSignalApprovalReactionApprovers({
|
|
319
|
+
cfg: params.cfg,
|
|
320
|
+
accountId: params.target.accountId
|
|
321
|
+
})) return false;
|
|
322
|
+
const conversationKey = resolveSignalApprovalConversationKeyForDeliveredTarget({
|
|
323
|
+
cfg: params.cfg,
|
|
324
|
+
accountId: params.target.accountId,
|
|
325
|
+
to: params.target.to
|
|
326
|
+
});
|
|
327
|
+
if (!conversationKey) return false;
|
|
328
|
+
const route = buildTargetRoute({
|
|
329
|
+
cfg: params.cfg,
|
|
330
|
+
accountId: params.target.accountId,
|
|
331
|
+
to: params.target.to,
|
|
332
|
+
approvalId: metadata.approvalId,
|
|
333
|
+
approvalKind: metadata.approvalKind,
|
|
334
|
+
agentId: metadata.agentId,
|
|
335
|
+
sessionKey: metadata.sessionKey
|
|
296
336
|
});
|
|
297
337
|
if (!route) return false;
|
|
298
|
-
|
|
299
|
-
|
|
338
|
+
const targetAuthorKeys = resolveSignalApprovalTargetAuthorKeys(params);
|
|
339
|
+
if (targetAuthorKeys.length === 0) return false;
|
|
340
|
+
let registered = false;
|
|
341
|
+
for (const messageId of listDeliveredSignalMessageIdsWithVisibleHint({
|
|
342
|
+
payload: params.payload,
|
|
343
|
+
results: params.results
|
|
344
|
+
})) registered = Boolean(registerSignalApprovalReactionTarget({
|
|
345
|
+
accountId: normalizeAccountId(params.target.accountId ?? void 0),
|
|
300
346
|
conversationKey,
|
|
301
|
-
messageId
|
|
302
|
-
approvalId:
|
|
303
|
-
|
|
304
|
-
|
|
347
|
+
messageId,
|
|
348
|
+
approvalId: metadata.approvalId,
|
|
349
|
+
approvalKind: metadata.approvalKind,
|
|
350
|
+
allowedDecisions: metadata.allowedDecisions,
|
|
351
|
+
targetAuthorKeys,
|
|
305
352
|
route,
|
|
306
353
|
routeAllowed: true,
|
|
307
354
|
ttlMs: params.ttlMs
|
|
308
|
-
}));
|
|
355
|
+
})) || registered;
|
|
356
|
+
return registered;
|
|
309
357
|
}
|
|
310
358
|
function unregisterSignalApprovalReactionTarget(params) {
|
|
311
359
|
const key = buildReactionTargetKey(params);
|
|
@@ -403,197 +451,9 @@ async function maybeResolveSignalApprovalReaction(params) {
|
|
|
403
451
|
return true;
|
|
404
452
|
}
|
|
405
453
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (opts.baseUrl?.trim() && opts.account?.trim()) return;
|
|
410
|
-
if (!opts.cfg) throw new Error("Signal RPC account resolution requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
|
|
411
|
-
return resolveSignalAccount({
|
|
412
|
-
cfg: requireRuntimeConfig(opts.cfg, "Signal RPC account resolution"),
|
|
413
|
-
accountId: opts.accountId
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
function parseTarget(raw) {
|
|
417
|
-
let value = raw.trim();
|
|
418
|
-
if (!value) throw new Error("Signal recipient is required");
|
|
419
|
-
if (normalizeLowercaseStringOrEmpty(value).startsWith("signal:")) value = value.slice(7).trim();
|
|
420
|
-
const normalized = normalizeLowercaseStringOrEmpty(value);
|
|
421
|
-
if (normalized.startsWith("group:")) return {
|
|
422
|
-
type: "group",
|
|
423
|
-
groupId: value.slice(6).trim()
|
|
424
|
-
};
|
|
425
|
-
if (normalized.startsWith("username:")) return {
|
|
426
|
-
type: "username",
|
|
427
|
-
username: value.slice(9).trim()
|
|
428
|
-
};
|
|
429
|
-
if (normalized.startsWith("u:")) return {
|
|
430
|
-
type: "username",
|
|
431
|
-
username: value.trim()
|
|
432
|
-
};
|
|
433
|
-
return {
|
|
434
|
-
type: "recipient",
|
|
435
|
-
recipient: value
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
function buildTargetParams(target, allow) {
|
|
439
|
-
if (target.type === "recipient") {
|
|
440
|
-
if (!allow.recipient) return null;
|
|
441
|
-
return { recipient: [target.recipient] };
|
|
442
|
-
}
|
|
443
|
-
if (target.type === "group") {
|
|
444
|
-
if (!allow.group) return null;
|
|
445
|
-
return { groupId: target.groupId };
|
|
446
|
-
}
|
|
447
|
-
if (target.type === "username") {
|
|
448
|
-
if (!allow.username) return null;
|
|
449
|
-
return { username: [target.username] };
|
|
450
|
-
}
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
function createSignalSendReceipt(params) {
|
|
454
|
-
const messageId = params.messageId.trim();
|
|
455
|
-
const results = messageId && messageId !== "unknown" ? [{
|
|
456
|
-
channel: "signal",
|
|
457
|
-
messageId,
|
|
458
|
-
meta: { targetType: params.target.type }
|
|
459
|
-
}] : [];
|
|
460
|
-
if (results[0]) {
|
|
461
|
-
if (params.timestamp != null) results[0].timestamp = params.timestamp;
|
|
462
|
-
if (params.target.type === "group") results[0].chatId = params.target.groupId;
|
|
463
|
-
else if (params.target.type === "recipient") results[0].toJid = params.target.recipient;
|
|
464
|
-
else results[0].toJid = params.target.username;
|
|
465
|
-
}
|
|
466
|
-
return createMessageReceiptFromOutboundResults({
|
|
467
|
-
results,
|
|
468
|
-
kind: params.kind
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
async function sendMessageSignal(to, text, opts) {
|
|
472
|
-
const cfg = requireRuntimeConfig(opts.cfg, "Signal send");
|
|
473
|
-
const apiMode = cfg.channels?.signal?.apiMode;
|
|
474
|
-
const accountInfo = resolveSignalAccount({
|
|
475
|
-
cfg,
|
|
476
|
-
accountId: opts.accountId
|
|
477
|
-
});
|
|
478
|
-
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
479
|
-
const target = parseTarget(to);
|
|
480
|
-
const outboundText = appendSignalApprovalReactionHintForOutboundMessage({
|
|
481
|
-
cfg,
|
|
482
|
-
accountId: accountInfo.accountId,
|
|
483
|
-
to,
|
|
484
|
-
text: text ?? "",
|
|
485
|
-
targetAuthor: account
|
|
486
|
-
});
|
|
487
|
-
let message = outboundText;
|
|
488
|
-
let messageFromPlaceholder = false;
|
|
489
|
-
let textStyles = [];
|
|
490
|
-
const textMode = opts.textMode ?? "markdown";
|
|
491
|
-
const maxBytes = (() => {
|
|
492
|
-
if (typeof opts.maxBytes === "number") return opts.maxBytes;
|
|
493
|
-
if (typeof accountInfo.config.mediaMaxMb === "number") return accountInfo.config.mediaMaxMb * 1024 * 1024;
|
|
494
|
-
if (typeof cfg.agents?.defaults?.mediaMaxMb === "number") return cfg.agents.defaults.mediaMaxMb * 1024 * 1024;
|
|
495
|
-
return 8 * 1024 * 1024;
|
|
496
|
-
})();
|
|
497
|
-
let attachments;
|
|
498
|
-
if (opts.mediaUrl?.trim()) {
|
|
499
|
-
const resolved = await resolveOutboundAttachmentFromUrl(opts.mediaUrl.trim(), maxBytes, {
|
|
500
|
-
mediaAccess: opts.mediaAccess,
|
|
501
|
-
localRoots: opts.mediaLocalRoots,
|
|
502
|
-
readFile: opts.mediaReadFile
|
|
503
|
-
});
|
|
504
|
-
attachments = [resolved.path];
|
|
505
|
-
const kind = kindFromMime(resolved.contentType ?? void 0);
|
|
506
|
-
if (!message && kind) {
|
|
507
|
-
message = kind === "image" ? "<media:image>" : `<media:${kind}>`;
|
|
508
|
-
messageFromPlaceholder = true;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
if (message.trim() && !messageFromPlaceholder) if (textMode === "plain") textStyles = opts.textStyles ?? [];
|
|
512
|
-
else {
|
|
513
|
-
const tableMode = resolveMarkdownTableMode({
|
|
514
|
-
cfg,
|
|
515
|
-
channel: "signal",
|
|
516
|
-
accountId: accountInfo.accountId
|
|
517
|
-
});
|
|
518
|
-
const formatted = markdownToSignalText(message, { tableMode });
|
|
519
|
-
message = formatted.text;
|
|
520
|
-
textStyles = formatted.styles;
|
|
521
|
-
}
|
|
522
|
-
if (!message.trim() && (!attachments || attachments.length === 0)) throw new Error("Signal send requires text or media");
|
|
523
|
-
const params = { message };
|
|
524
|
-
if (textStyles.length > 0) params["text-style"] = textStyles.map((style) => `${style.start}:${style.length}:${style.style}`);
|
|
525
|
-
if (account) params.account = account;
|
|
526
|
-
if (attachments && attachments.length > 0) params.attachments = attachments;
|
|
527
|
-
const targetParams = buildTargetParams(target, {
|
|
528
|
-
recipient: true,
|
|
529
|
-
group: true,
|
|
530
|
-
username: true
|
|
531
|
-
});
|
|
532
|
-
if (!targetParams) throw new Error("Signal recipient is required");
|
|
533
|
-
Object.assign(params, targetParams);
|
|
534
|
-
const timestamp = (await signalRpcRequest("send", params, {
|
|
535
|
-
baseUrl,
|
|
536
|
-
timeoutMs: opts.timeoutMs,
|
|
537
|
-
apiMode
|
|
538
|
-
}))?.timestamp;
|
|
539
|
-
const messageId = timestamp ? String(timestamp) : "unknown";
|
|
540
|
-
registerSignalApprovalReactionTargetForOutboundMessage({
|
|
541
|
-
cfg,
|
|
542
|
-
accountId: accountInfo.accountId,
|
|
543
|
-
to,
|
|
544
|
-
messageId,
|
|
545
|
-
text: outboundText,
|
|
546
|
-
targetAuthor: account
|
|
547
|
-
});
|
|
548
|
-
return {
|
|
549
|
-
messageId,
|
|
550
|
-
timestamp,
|
|
551
|
-
receipt: createSignalSendReceipt({
|
|
552
|
-
messageId,
|
|
553
|
-
target,
|
|
554
|
-
kind: attachments && attachments.length > 0 ? "media" : "text",
|
|
555
|
-
...timestamp != null ? { timestamp } : {}
|
|
556
|
-
})
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
async function sendTypingSignal(to, opts) {
|
|
560
|
-
const accountInfo = await resolveSignalRpcAccountInfo(opts);
|
|
561
|
-
const cfg = requireRuntimeConfig(opts.cfg, "Signal typing");
|
|
562
|
-
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
563
|
-
const targetParams = buildTargetParams(parseTarget(to), {
|
|
564
|
-
recipient: true,
|
|
565
|
-
group: true
|
|
566
|
-
});
|
|
567
|
-
if (!targetParams) return false;
|
|
568
|
-
const params = { ...targetParams };
|
|
569
|
-
if (account) params.account = account;
|
|
570
|
-
if (opts.stop) params.stop = true;
|
|
571
|
-
await signalRpcRequest("sendTyping", params, {
|
|
572
|
-
baseUrl,
|
|
573
|
-
timeoutMs: opts.timeoutMs,
|
|
574
|
-
apiMode: cfg.channels?.signal?.apiMode
|
|
575
|
-
});
|
|
576
|
-
return true;
|
|
577
|
-
}
|
|
578
|
-
async function sendReadReceiptSignal(to, targetTimestamp, opts) {
|
|
579
|
-
if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) return false;
|
|
580
|
-
const accountInfo = await resolveSignalRpcAccountInfo(opts);
|
|
581
|
-
const cfg = requireRuntimeConfig(opts.cfg, "Signal read receipt");
|
|
582
|
-
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
583
|
-
const targetParams = buildTargetParams(parseTarget(to), { recipient: true });
|
|
584
|
-
if (!targetParams) return false;
|
|
585
|
-
const params = {
|
|
586
|
-
...targetParams,
|
|
587
|
-
targetTimestamp,
|
|
588
|
-
type: opts.type ?? "read"
|
|
589
|
-
};
|
|
590
|
-
if (account) params.account = account;
|
|
591
|
-
await signalRpcRequest("sendReceipt", params, {
|
|
592
|
-
baseUrl,
|
|
593
|
-
timeoutMs: opts.timeoutMs,
|
|
594
|
-
apiMode: cfg.channels?.signal?.apiMode
|
|
595
|
-
});
|
|
596
|
-
return true;
|
|
454
|
+
function clearSignalApprovalReactionTargetsForTest() {
|
|
455
|
+
signalApprovalReactionTargets.clearForTest();
|
|
456
|
+
resolverRuntimeLoader.clear();
|
|
597
457
|
}
|
|
598
458
|
//#endregion
|
|
599
|
-
export {
|
|
459
|
+
export { registerSignalApprovalReactionTarget as a, resolveSignalApprovalTargetAuthorKeys as c, maybeResolveSignalApprovalReaction as i, unregisterSignalApprovalReactionTarget as l, approval_reactions_exports as n, registerSignalApprovalReactionTargetForDeliveredPayload as o, hasSignalApprovalReactionApprovers as r, resolveSignalApprovalConversationKey as s, addSignalApprovalReactionHintToStructuredPayload as t, setSignalRuntime as u };
|