@openclaw/signal 2026.6.11 → 2026.7.1-beta.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/api.js +7 -7
- package/dist/{approval-handler.runtime-CeJI1wow.js → approval-handler.runtime-C4S7IAvt.js} +3 -1
- package/dist/{send-CBlFUkY_.js → approval-reactions-H-RPGBK7.js} +97 -270
- package/dist/{channel-LmY2UpOt.js → channel-aQhurb0Z.js} +58 -11
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B0-YpkC4.js → channel.runtime-C5skg4Q0.js} +2 -2
- 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-BnugYXjB.js} +3 -3
- package/dist/{monitor-CUhIKHJo.js → monitor-C1gdgT7W.js} +63 -26
- package/dist/{probe-BQ_Izoya.js → probe-BvFJLOBi.js} +1 -1
- package/dist/{reaction-runtime-api-C_PQ45D9.js → reaction-runtime-api-BRJCLiqK.js} +8 -3
- package/dist/reaction-runtime-api.js +1 -1
- package/dist/runtime-api.js +7 -6
- package/dist/send-De6LIOLq.js +186 -0
- package/dist/{send.runtime-CfaZd8X4.js → send.runtime-BnjSh7QP.js} +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-hOCHbEhX.js";
|
|
2
2
|
import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
|
|
3
|
-
import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, r as markdownToSignalText, t as signalMessageActions } from "./message-actions-
|
|
4
|
-
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-
|
|
5
|
-
import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-
|
|
6
|
-
import { a as looksLikeArchive, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli } from "./install-signal-cli-
|
|
7
|
-
import { t as monitorSignalProvider } from "./monitor-
|
|
8
|
-
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-
|
|
9
|
-
import { t as probeSignal } from "./probe-
|
|
3
|
+
import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, r as markdownToSignalText, t as signalMessageActions } from "./message-actions-BnugYXjB.js";
|
|
4
|
+
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
5
|
+
import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-aQhurb0Z.js";
|
|
6
|
+
import { a as looksLikeArchive, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli } from "./install-signal-cli-TwhJ0DGy.js";
|
|
7
|
+
import { t as monitorSignalProvider } from "./monitor-C1gdgT7W.js";
|
|
8
|
+
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
|
|
9
|
+
import { t as probeSignal } from "./probe-BvFJLOBi.js";
|
|
10
10
|
//#region extensions/signal/src/channel.setup.ts
|
|
11
11
|
const signalSetupPlugin = { ...createSignalPluginBase({
|
|
12
12
|
setupWizard: signalSetupWizard,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { d as normalizeSignalMessagingTarget } from "./identity-B6O4k8xg.js";
|
|
2
|
-
import {
|
|
2
|
+
import { a as registerSignalApprovalReactionTarget, c as resolveSignalApprovalTargetAuthorKeys, l as unregisterSignalApprovalReactionTarget, r as hasSignalApprovalReactionApprovers, s as resolveSignalApprovalConversationKey } from "./approval-reactions-H-RPGBK7.js";
|
|
3
|
+
import { r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
|
|
3
4
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
4
5
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
6
|
import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
@@ -124,6 +125,7 @@ const signalApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
|
|
|
124
125
|
conversationKey: entry.conversationKey,
|
|
125
126
|
messageId: entry.messageId,
|
|
126
127
|
approvalId: request.id,
|
|
128
|
+
approvalKind: view.approvalKind,
|
|
127
129
|
allowedDecisions: pendingPayload.reactionPayload.allowedDecisions,
|
|
128
130
|
targetAuthorKeys: entry.targetAuthorKeys,
|
|
129
131
|
route: {
|
|
@@ -1,16 +1,12 @@
|
|
|
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 { c as getSignalApprovalApprovers, l as signalApprovalAuth
|
|
4
|
-
import { a as signalRpcRequest, r as resolveSignalRpcContext } from "./reaction-runtime-api-C_PQ45D9.js";
|
|
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 { c as getSignalApprovalApprovers, l as signalApprovalAuth } from "./message-actions-BnugYXjB.js";
|
|
8
4
|
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
9
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
6
|
import { buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, resolveApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
11
7
|
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
12
|
-
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
13
8
|
import { matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
9
|
+
import { getExecApprovalReplyMetadata } from "openclaw/plugin-sdk/approval-reply-runtime";
|
|
14
10
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
15
11
|
//#region extensions/signal/src/runtime.ts
|
|
16
12
|
const { setRuntime: setSignalRuntime, getRuntime: getSignalRuntime, tryGetRuntime: getOptionalSignalRuntime, clearRuntime: clearSignalRuntime } = createPluginRuntimeStore({
|
|
@@ -19,7 +15,22 @@ const { setRuntime: setSignalRuntime, getRuntime: getSignalRuntime, tryGetRuntim
|
|
|
19
15
|
});
|
|
20
16
|
//#endregion
|
|
21
17
|
//#region extensions/signal/src/approval-reactions.ts
|
|
22
|
-
|
|
18
|
+
var approval_reactions_exports = /* @__PURE__ */ __exportAll({
|
|
19
|
+
addSignalApprovalReactionHintToStructuredPayload: () => addSignalApprovalReactionHintToStructuredPayload,
|
|
20
|
+
addSignalApprovalReactionHintToText: () => addSignalApprovalReactionHintToText,
|
|
21
|
+
buildSignalApprovalReactionHint: () => buildSignalApprovalReactionHint,
|
|
22
|
+
clearSignalApprovalReactionTargetsForTest: () => clearSignalApprovalReactionTargetsForTest,
|
|
23
|
+
hasSignalApprovalReactionApprovers: () => hasSignalApprovalReactionApprovers,
|
|
24
|
+
listSignalApprovalReactionBindings: () => listSignalApprovalReactionBindings,
|
|
25
|
+
maybeResolveSignalApprovalReaction: () => maybeResolveSignalApprovalReaction,
|
|
26
|
+
registerSignalApprovalReactionTarget: () => registerSignalApprovalReactionTarget,
|
|
27
|
+
registerSignalApprovalReactionTargetForDeliveredPayload: () => registerSignalApprovalReactionTargetForDeliveredPayload,
|
|
28
|
+
resolveSignalApprovalConversationKey: () => resolveSignalApprovalConversationKey,
|
|
29
|
+
resolveSignalApprovalReactionTargetWithPersistence: () => resolveSignalApprovalReactionTargetWithPersistence,
|
|
30
|
+
resolveSignalApprovalTargetAuthorKeys: () => resolveSignalApprovalTargetAuthorKeys,
|
|
31
|
+
unregisterSignalApprovalReactionTarget: () => unregisterSignalApprovalReactionTarget
|
|
32
|
+
});
|
|
33
|
+
const PERSISTENT_NAMESPACE = "signal.approval-reactions.v2";
|
|
23
34
|
const PERSISTENT_MAX_ENTRIES = 1e3;
|
|
24
35
|
const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
|
|
25
36
|
let resolverRuntimePromise;
|
|
@@ -173,36 +184,15 @@ function insertSignalApprovalReactionHintNearHeader(params) {
|
|
|
173
184
|
return `${params.hint}\n\n${params.text}`;
|
|
174
185
|
}
|
|
175
186
|
function addSignalApprovalReactionHintToText(params) {
|
|
176
|
-
if (
|
|
187
|
+
if (hasSignalApprovalReactionHintText(params.text)) return params.text;
|
|
177
188
|
const hint = buildSignalApprovalReactionHint(params.allowedDecisions);
|
|
178
189
|
return hint ? insertSignalApprovalReactionHintNearHeader({
|
|
179
190
|
text: params.text,
|
|
180
191
|
hint
|
|
181
192
|
}) : params.text;
|
|
182
193
|
}
|
|
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;
|
|
194
|
+
function hasSignalApprovalReactionHintText(text) {
|
|
195
|
+
return /(^|\n)React with:\s*(\n|$)/i.test(text ?? "");
|
|
206
196
|
}
|
|
207
197
|
function buildTargetRoute(params) {
|
|
208
198
|
const to = normalizeSignalMessagingTarget(params.to);
|
|
@@ -217,39 +207,11 @@ function buildTargetRoute(params) {
|
|
|
217
207
|
return isSignalApprovalReactionRouteStillEnabled({
|
|
218
208
|
cfg: params.cfg,
|
|
219
209
|
target: {
|
|
220
|
-
approvalKind: resolveApprovalKindFromId(params.approvalId),
|
|
210
|
+
approvalKind: params.approvalKind ?? resolveApprovalKindFromId(params.approvalId),
|
|
221
211
|
route
|
|
222
212
|
}
|
|
223
213
|
}) ? route : null;
|
|
224
214
|
}
|
|
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
215
|
function hasSignalApprovalReactionApprovers(params) {
|
|
254
216
|
return getSignalApprovalApprovers(params).length > 0;
|
|
255
217
|
}
|
|
@@ -273,7 +235,7 @@ function registerSignalApprovalReactionTarget(params) {
|
|
|
273
235
|
};
|
|
274
236
|
const target = {
|
|
275
237
|
approvalId,
|
|
276
|
-
approvalKind: resolveApprovalKindFromId(approvalId),
|
|
238
|
+
approvalKind: params.approvalKind ?? resolveApprovalKindFromId(approvalId),
|
|
277
239
|
allowedDecisions,
|
|
278
240
|
targetAuthorKeys,
|
|
279
241
|
route
|
|
@@ -281,31 +243,84 @@ function registerSignalApprovalReactionTarget(params) {
|
|
|
281
243
|
signalApprovalReactionTargets.register(key, target, { ttlMs: params.ttlMs });
|
|
282
244
|
return target;
|
|
283
245
|
}
|
|
284
|
-
function
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
287
|
-
|
|
288
|
-
if (!
|
|
289
|
-
|
|
246
|
+
function addSignalApprovalReactionHintToStructuredPayload(params) {
|
|
247
|
+
const metadata = getExecApprovalReplyMetadata(params.payload);
|
|
248
|
+
if (!metadata?.allowedDecisions || metadata.allowedDecisions.length === 0) return null;
|
|
249
|
+
if (resolveSignalApprovalTargetAuthorKeys(params).length === 0) return null;
|
|
250
|
+
if (!hasSignalApprovalReactionApprovers({
|
|
251
|
+
cfg: params.cfg,
|
|
252
|
+
accountId: params.accountId
|
|
253
|
+
})) return null;
|
|
254
|
+
if (!buildTargetRoute({
|
|
290
255
|
cfg: params.cfg,
|
|
291
256
|
accountId: params.accountId,
|
|
292
257
|
to: params.to,
|
|
293
|
-
approvalId:
|
|
294
|
-
|
|
295
|
-
|
|
258
|
+
approvalId: metadata.approvalId,
|
|
259
|
+
approvalKind: metadata.approvalKind,
|
|
260
|
+
agentId: metadata.agentId,
|
|
261
|
+
sessionKey: metadata.sessionKey
|
|
262
|
+
}) || !params.payload.text) return null;
|
|
263
|
+
return {
|
|
264
|
+
...params.payload,
|
|
265
|
+
text: addSignalApprovalReactionHintToText({
|
|
266
|
+
text: params.payload.text,
|
|
267
|
+
allowedDecisions: metadata.allowedDecisions
|
|
268
|
+
})
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function readSignalDeliveryVisibleText(result) {
|
|
272
|
+
const meta = result.meta;
|
|
273
|
+
const visibleText = meta?.signalVisibleText ?? meta?.visibleText;
|
|
274
|
+
return typeof visibleText === "string" ? visibleText : null;
|
|
275
|
+
}
|
|
276
|
+
function listDeliveredSignalMessageIdsWithVisibleHint(params) {
|
|
277
|
+
const signalResults = params.results.filter((result) => !result.channel || normalizeLowercaseStringOrEmpty(result.channel) === "signal");
|
|
278
|
+
const resultsWithVisibleText = signalResults.filter((result) => readSignalDeliveryVisibleText(result) !== null);
|
|
279
|
+
const candidates = resultsWithVisibleText.length > 0 ? resultsWithVisibleText : signalResults;
|
|
280
|
+
if (resultsWithVisibleText.length === 0 && candidates.length !== 1) return [];
|
|
281
|
+
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"));
|
|
282
|
+
return Array.from(new Set(ids));
|
|
283
|
+
}
|
|
284
|
+
function registerSignalApprovalReactionTargetForDeliveredPayload(params) {
|
|
285
|
+
if (normalizeLowercaseStringOrEmpty(params.target.channel) !== "signal") return false;
|
|
286
|
+
const metadata = getExecApprovalReplyMetadata(params.payload);
|
|
287
|
+
if (!metadata?.allowedDecisions || metadata.allowedDecisions.length === 0) return false;
|
|
288
|
+
if (!hasSignalApprovalReactionHintText(params.payload.text)) return false;
|
|
289
|
+
if (!hasSignalApprovalReactionApprovers({
|
|
290
|
+
cfg: params.cfg,
|
|
291
|
+
accountId: params.target.accountId
|
|
292
|
+
})) return false;
|
|
293
|
+
const conversationKey = resolveSignalApprovalConversationKey(params.target.to);
|
|
294
|
+
if (!conversationKey) return false;
|
|
295
|
+
const route = buildTargetRoute({
|
|
296
|
+
cfg: params.cfg,
|
|
297
|
+
accountId: params.target.accountId,
|
|
298
|
+
to: params.target.to,
|
|
299
|
+
approvalId: metadata.approvalId,
|
|
300
|
+
approvalKind: metadata.approvalKind,
|
|
301
|
+
agentId: metadata.agentId,
|
|
302
|
+
sessionKey: metadata.sessionKey
|
|
296
303
|
});
|
|
297
304
|
if (!route) return false;
|
|
298
|
-
|
|
299
|
-
|
|
305
|
+
const targetAuthorKeys = resolveSignalApprovalTargetAuthorKeys(params);
|
|
306
|
+
if (targetAuthorKeys.length === 0) return false;
|
|
307
|
+
let registered = false;
|
|
308
|
+
for (const messageId of listDeliveredSignalMessageIdsWithVisibleHint({
|
|
309
|
+
payload: params.payload,
|
|
310
|
+
results: params.results
|
|
311
|
+
})) registered = Boolean(registerSignalApprovalReactionTarget({
|
|
312
|
+
accountId: normalizeAccountId(params.target.accountId ?? void 0),
|
|
300
313
|
conversationKey,
|
|
301
|
-
messageId
|
|
302
|
-
approvalId:
|
|
303
|
-
|
|
304
|
-
|
|
314
|
+
messageId,
|
|
315
|
+
approvalId: metadata.approvalId,
|
|
316
|
+
approvalKind: metadata.approvalKind,
|
|
317
|
+
allowedDecisions: metadata.allowedDecisions,
|
|
318
|
+
targetAuthorKeys,
|
|
305
319
|
route,
|
|
306
320
|
routeAllowed: true,
|
|
307
321
|
ttlMs: params.ttlMs
|
|
308
|
-
}));
|
|
322
|
+
})) || registered;
|
|
323
|
+
return registered;
|
|
309
324
|
}
|
|
310
325
|
function unregisterSignalApprovalReactionTarget(params) {
|
|
311
326
|
const key = buildReactionTargetKey(params);
|
|
@@ -403,197 +418,9 @@ async function maybeResolveSignalApprovalReaction(params) {
|
|
|
403
418
|
return true;
|
|
404
419
|
}
|
|
405
420
|
}
|
|
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;
|
|
421
|
+
function clearSignalApprovalReactionTargetsForTest() {
|
|
422
|
+
signalApprovalReactionTargets.clearForTest();
|
|
423
|
+
resolverRuntimePromise = void 0;
|
|
597
424
|
}
|
|
598
425
|
//#endregion
|
|
599
|
-
export {
|
|
426
|
+
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 };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId } from "./accounts-hOCHbEhX.js";
|
|
2
2
|
import { c as resolveSignalSender, d as normalizeSignalMessagingTarget, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
|
|
3
|
-
import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, o as shouldSuppressLocalSignalExecApprovalPrompt, s as signalApprovalCapability, t as signalMessageActions } from "./message-actions-
|
|
3
|
+
import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, o as shouldSuppressLocalSignalExecApprovalPrompt, s as signalApprovalCapability, t as signalMessageActions } from "./message-actions-BnugYXjB.js";
|
|
4
4
|
import { t as SignalChannelConfigSchema } from "./config-schema-BiojLEsX.js";
|
|
5
5
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
6
6
|
import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
|
|
@@ -15,6 +15,7 @@ import { chunkText, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chun
|
|
|
15
15
|
import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
|
|
16
16
|
import { buildBaseChannelStatusSummary, collectStatusIssuesFromLastError, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
17
17
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringifiedEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
18
|
+
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
18
19
|
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
19
20
|
import { createChannelPluginBase, getChatChannelMeta } from "openclaw/plugin-sdk/core";
|
|
20
21
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, createCliPathTextInput, createDelegatedSetupWizardProxy, createDelegatedTextInputShouldPrompt, createPatchedAccountSetupAdapter, createSetupInputPresenceValidator, createSetupTranslator, mergeAllowFromEntries, parseSetupEntriesAllowingWildcard, patchChannelConfigForAccount, promptParsedAllowFromForAccount, setAccountAllowFromForChannel, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
|
|
@@ -176,9 +177,7 @@ function createSignalCliPathTextInput(shouldPrompt) {
|
|
|
176
177
|
accountId,
|
|
177
178
|
credentialValues
|
|
178
179
|
}),
|
|
179
|
-
shouldPrompt
|
|
180
|
-
helpTitle: "Signal",
|
|
181
|
-
helpLines: ["signal-cli not found. Install it, then rerun this step or set channels.signal.cliPath."]
|
|
180
|
+
shouldPrompt
|
|
182
181
|
});
|
|
183
182
|
}
|
|
184
183
|
const signalNumberTextInput = {
|
|
@@ -236,7 +235,7 @@ function createSignalSetupWizardProxy(loadWizard) {
|
|
|
236
235
|
//#region extensions/signal/src/shared.ts
|
|
237
236
|
const SIGNAL_CHANNEL = "signal";
|
|
238
237
|
async function loadSignalChannelRuntime() {
|
|
239
|
-
return await import("./channel.runtime-
|
|
238
|
+
return await import("./channel.runtime-C5skg4Q0.js");
|
|
240
239
|
}
|
|
241
240
|
const signalSetupWizard = createSignalSetupWizardProxy(async () => (await loadSignalChannelRuntime()).signalSetupWizard);
|
|
242
241
|
const signalConfigAdapter = createScopedChannelConfigAdapter({
|
|
@@ -307,18 +306,23 @@ function createSignalPluginBase(params) {
|
|
|
307
306
|
let signalMonitorModulePromise = null;
|
|
308
307
|
let signalProbeModulePromise = null;
|
|
309
308
|
let signalSendRuntimePromise = null;
|
|
309
|
+
let signalApprovalReactionsModulePromise = null;
|
|
310
310
|
async function loadSignalMonitorModule() {
|
|
311
|
-
signalMonitorModulePromise ??= import("./monitor-
|
|
311
|
+
signalMonitorModulePromise ??= import("./monitor-C1gdgT7W.js").then((n) => n.n);
|
|
312
312
|
return await signalMonitorModulePromise;
|
|
313
313
|
}
|
|
314
314
|
async function loadSignalProbeModule() {
|
|
315
|
-
signalProbeModulePromise ??= import("./probe-
|
|
315
|
+
signalProbeModulePromise ??= import("./probe-BvFJLOBi.js").then((n) => n.n);
|
|
316
316
|
return await signalProbeModulePromise;
|
|
317
317
|
}
|
|
318
318
|
async function loadSignalSendRuntime() {
|
|
319
|
-
signalSendRuntimePromise ??= import("./send.runtime-
|
|
319
|
+
signalSendRuntimePromise ??= import("./send.runtime-BnjSh7QP.js");
|
|
320
320
|
return await signalSendRuntimePromise;
|
|
321
321
|
}
|
|
322
|
+
async function loadSignalApprovalReactionsModule() {
|
|
323
|
+
signalApprovalReactionsModulePromise ??= import("./approval-reactions-H-RPGBK7.js").then((n) => n.n);
|
|
324
|
+
return await signalApprovalReactionsModulePromise;
|
|
325
|
+
}
|
|
322
326
|
async function resolveSignalSendContext(params) {
|
|
323
327
|
return {
|
|
324
328
|
send: resolveOutboundSendDep(params.deps, "signal") ?? (await loadSignalSendRuntime()).sendMessageSignal,
|
|
@@ -340,6 +344,16 @@ async function sendSignalOutbound(params) {
|
|
|
340
344
|
accountId: params.accountId ?? void 0
|
|
341
345
|
});
|
|
342
346
|
}
|
|
347
|
+
function attachSignalVisibleText(result, visibleText) {
|
|
348
|
+
const meta = "meta" in result && result.meta && typeof result.meta === "object" ? result.meta : {};
|
|
349
|
+
return {
|
|
350
|
+
...result,
|
|
351
|
+
meta: {
|
|
352
|
+
...meta,
|
|
353
|
+
signalVisibleText: visibleText
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
343
357
|
const signalMessageAdapter = defineChannelMessageAdapter({
|
|
344
358
|
id: "signal",
|
|
345
359
|
durableFinal: { capabilities: {
|
|
@@ -424,7 +438,7 @@ async function sendFormattedSignalText(ctx) {
|
|
|
424
438
|
textMode: "plain",
|
|
425
439
|
textStyles: chunk.styles
|
|
426
440
|
});
|
|
427
|
-
results.push(result);
|
|
441
|
+
results.push(attachSignalVisibleText(result, chunk.text));
|
|
428
442
|
}
|
|
429
443
|
return attachChannelToResults("signal", results);
|
|
430
444
|
}
|
|
@@ -444,7 +458,7 @@ async function sendFormattedSignalMedia(ctx) {
|
|
|
444
458
|
text: ctx.text,
|
|
445
459
|
styles: []
|
|
446
460
|
};
|
|
447
|
-
return attachChannelToResult("signal", await send(ctx.to, formatted.text, {
|
|
461
|
+
return attachChannelToResult("signal", attachSignalVisibleText(await send(ctx.to, formatted.text, {
|
|
448
462
|
cfg: ctx.cfg,
|
|
449
463
|
mediaUrl: ctx.mediaUrl,
|
|
450
464
|
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
@@ -453,7 +467,37 @@ async function sendFormattedSignalMedia(ctx) {
|
|
|
453
467
|
accountId: ctx.accountId ?? void 0,
|
|
454
468
|
textMode: "plain",
|
|
455
469
|
textStyles: formatted.styles
|
|
456
|
-
}));
|
|
470
|
+
}), formatted.text));
|
|
471
|
+
}
|
|
472
|
+
async function registerDeliveredSignalApprovalPayloadForReactions(params) {
|
|
473
|
+
const account = resolveSignalAccount({
|
|
474
|
+
cfg: params.cfg,
|
|
475
|
+
accountId: params.target.accountId ?? void 0
|
|
476
|
+
});
|
|
477
|
+
if (!account.config.account) return;
|
|
478
|
+
const { registerSignalApprovalReactionTargetForDeliveredPayload } = await loadSignalApprovalReactionsModule();
|
|
479
|
+
registerSignalApprovalReactionTargetForDeliveredPayload({
|
|
480
|
+
cfg: params.cfg,
|
|
481
|
+
target: params.target,
|
|
482
|
+
payload: params.payload,
|
|
483
|
+
results: params.results,
|
|
484
|
+
targetAuthor: account.config.account
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
async function renderSignalApprovalPayloadForReactions(params) {
|
|
488
|
+
const account = resolveSignalAccount({
|
|
489
|
+
cfg: params.ctx.cfg,
|
|
490
|
+
accountId: params.ctx.accountId ?? void 0
|
|
491
|
+
});
|
|
492
|
+
if (!account.config.account) return null;
|
|
493
|
+
const { addSignalApprovalReactionHintToStructuredPayload } = await loadSignalApprovalReactionsModule();
|
|
494
|
+
return addSignalApprovalReactionHintToStructuredPayload({
|
|
495
|
+
cfg: params.ctx.cfg,
|
|
496
|
+
accountId: params.ctx.accountId ?? void 0,
|
|
497
|
+
to: params.ctx.to,
|
|
498
|
+
payload: params.payload,
|
|
499
|
+
targetAuthor: account.config.account
|
|
500
|
+
});
|
|
457
501
|
}
|
|
458
502
|
const signalPlugin = createChatChannelPlugin({
|
|
459
503
|
base: {
|
|
@@ -567,12 +611,15 @@ const signalPlugin = createChatChannelPlugin({
|
|
|
567
611
|
chunker: chunkText,
|
|
568
612
|
chunkerMode: "text",
|
|
569
613
|
textChunkLimit: 4e3,
|
|
614
|
+
sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text),
|
|
570
615
|
shouldSuppressLocalPayloadPrompt: ({ cfg, accountId, payload, hint }) => shouldSuppressLocalSignalExecApprovalPrompt({
|
|
571
616
|
cfg,
|
|
572
617
|
accountId,
|
|
573
618
|
payload,
|
|
574
619
|
hint
|
|
575
620
|
}),
|
|
621
|
+
afterDeliverPayload: async (params) => await registerDeliveredSignalApprovalPayloadForReactions(params),
|
|
622
|
+
renderPresentation: async (params) => await renderSignalApprovalPayloadForReactions(params),
|
|
576
623
|
sendFormattedText: async ({ cfg, to, text, accountId, deps, abortSignal }) => await sendFormattedSignalText({
|
|
577
624
|
cfg,
|
|
578
625
|
to,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as signalPlugin } from "./channel-
|
|
1
|
+
import { t as signalPlugin } from "./channel-aQhurb0Z.js";
|
|
2
2
|
export { signalPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as resolveSignalAccount, n as listSignalAccountIds } from "./accounts-hOCHbEhX.js";
|
|
2
|
-
import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-
|
|
3
|
-
import { r as installSignalCli } from "./install-signal-cli-
|
|
2
|
+
import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-aQhurb0Z.js";
|
|
3
|
+
import { r as installSignalCli } from "./install-signal-cli-TwhJ0DGy.js";
|
|
4
4
|
import { detectBinary } from "openclaw/plugin-sdk/setup-tools";
|
|
5
5
|
import { createDetectedBinaryStatus, createSetupTranslator, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
6
6
|
//#region extensions/signal/src/setup-surface.ts
|
package/dist/contract-api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
|
|
2
|
-
import { a as looksLikeArchive, i as installSignalCliFromRelease, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli, t as downloadToFile } from "./install-signal-cli-
|
|
2
|
+
import { a as looksLikeArchive, i as installSignalCliFromRelease, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli, t as downloadToFile } from "./install-signal-cli-TwhJ0DGy.js";
|
|
3
3
|
export { downloadToFile, extractSignalCliArchive, installSignalCli, installSignalCliFromRelease, isSignalSenderAllowed, looksLikeArchive, looksLikeSignalTargetId, normalizeSignalMessagingTarget, pickAsset };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
2
3
|
import fs from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
5
|
+
import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
|
4
6
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
7
|
import { CONFIG_DIR, extractArchive, resolveBrewExecutable } from "openclaw/plugin-sdk/setup-tools";
|
|
6
8
|
import { createWriteStream } from "node:fs";
|
|
@@ -50,7 +52,7 @@ function pickAsset(assets, platform, arch) {
|
|
|
50
52
|
if (arch === "x64") return byName(/linux-native/) || byName(/linux/) || archives[0];
|
|
51
53
|
return;
|
|
52
54
|
}
|
|
53
|
-
if (platform === "darwin") return byName(/macos|osx|darwin/)
|
|
55
|
+
if (platform === "darwin") return byName(/macos|osx|darwin/);
|
|
54
56
|
if (platform === "win32") return byName(/windows|win/) || archives[0];
|
|
55
57
|
return archives[0];
|
|
56
58
|
}
|
|
@@ -130,7 +132,7 @@ async function installSignalCliViaBrew(runtime) {
|
|
|
130
132
|
const brewExe = resolveBrewExecutable();
|
|
131
133
|
if (!brewExe) return {
|
|
132
134
|
ok: false,
|
|
133
|
-
error: `No native signal-cli build is available for ${process.arch}. Install Homebrew (https://brew.sh) and try again, or install signal-cli manually.`
|
|
135
|
+
error: `No native signal-cli build is available for ${process.platform}/${process.arch}. Install Homebrew (https://brew.sh) and try again, or install signal-cli manually.`
|
|
134
136
|
};
|
|
135
137
|
runtime.log(`Installing signal-cli via Homebrew (${brewExe})…`);
|
|
136
138
|
const result = await runPluginCommandWithTimeout({
|
|
@@ -143,7 +145,7 @@ async function installSignalCliViaBrew(runtime) {
|
|
|
143
145
|
});
|
|
144
146
|
if (result.code !== 0) return {
|
|
145
147
|
ok: false,
|
|
146
|
-
error: `brew install signal-cli failed (exit ${result.code}): ${result.stderr.trim()
|
|
148
|
+
error: `brew install signal-cli failed (exit ${result.code}): ${truncateUtf16Safe(result.stderr.trim(), 200)}`
|
|
147
149
|
};
|
|
148
150
|
const cliPath = await resolveBrewSignalCliPath(brewExe);
|
|
149
151
|
if (!cliPath) return {
|
|
@@ -184,7 +186,7 @@ async function installSignalCliFromRelease(runtime) {
|
|
|
184
186
|
error: `Failed to fetch release info (${response.status})`
|
|
185
187
|
};
|
|
186
188
|
try {
|
|
187
|
-
payload = await response.
|
|
189
|
+
payload = await readProviderJsonResponse(response, "signal.release-info");
|
|
188
190
|
} catch {
|
|
189
191
|
return {
|
|
190
192
|
ok: false,
|
|
@@ -236,7 +238,7 @@ async function installSignalCli(runtime) {
|
|
|
236
238
|
ok: false,
|
|
237
239
|
error: "Signal CLI auto-install is not supported on Windows yet."
|
|
238
240
|
};
|
|
239
|
-
if (process.platform
|
|
241
|
+
if (process.platform === "linux" && process.arch === "x64") return installSignalCliFromRelease(runtime);
|
|
240
242
|
return installSignalCliViaBrew(runtime);
|
|
241
243
|
}
|
|
242
244
|
//#endregion
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-hOCHbEhX.js";
|
|
2
2
|
import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-B6O4k8xg.js";
|
|
3
|
-
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-
|
|
3
|
+
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
4
4
|
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
5
5
|
import { resolveReactionLevel } from "openclaw/plugin-sdk/status-helpers";
|
|
6
6
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { markdownToIR, renderMarkdownIRChunksWithinLimit } from "openclaw/plugin-sdk/text-chunking";
|
|
7
8
|
import { createChannelApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
|
|
8
9
|
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
9
10
|
import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver, createNativeApprovalChannelRouteGates, createNativeApprovalForwardingFallbackSuppressor, shouldSuppressLocalNativeExecApprovalPrompt } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
10
11
|
import { buildApprovalReactionPendingContentForRequest } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
11
12
|
import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
12
13
|
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
13
|
-
import { markdownToIR, renderMarkdownIRChunksWithinLimit } from "openclaw/plugin-sdk/text-chunking";
|
|
14
14
|
import { createActionGate, jsonResult, readStringParam, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
|
|
15
15
|
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
16
16
|
//#region extensions/signal/src/approval-auth.ts
|
|
@@ -233,7 +233,7 @@ const signalApprovalCapability = createChannelApprovalCapability({
|
|
|
233
233
|
accountId,
|
|
234
234
|
request
|
|
235
235
|
}),
|
|
236
|
-
load: async () => (await import("./approval-handler.runtime-
|
|
236
|
+
load: async () => (await import("./approval-handler.runtime-C4S7IAvt.js")).signalApprovalNativeRuntime
|
|
237
237
|
})
|
|
238
238
|
});
|
|
239
239
|
//#endregion
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { i as resolveSignalAccount } from "./accounts-hOCHbEhX.js";
|
|
3
3
|
import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine } from "./identity-B6O4k8xg.js";
|
|
4
|
-
import { a as isSignalNativeApprovalHandlerConfigured } from "./message-actions-
|
|
5
|
-
import { a as signalRpcRequest, i as signalCheck, o as streamSignalEvents } from "./reaction-runtime-api-
|
|
6
|
-
import {
|
|
4
|
+
import { a as isSignalNativeApprovalHandlerConfigured } from "./message-actions-BnugYXjB.js";
|
|
5
|
+
import { a as signalRpcRequest, i as signalCheck, o as streamSignalEvents } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
6
|
+
import { i as maybeResolveSignalApprovalReaction, o as registerSignalApprovalReactionTargetForDeliveredPayload, s as resolveSignalApprovalConversationKey, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-H-RPGBK7.js";
|
|
7
|
+
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
|
|
7
8
|
import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-outbound";
|
|
8
9
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
9
10
|
import { detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
|
|
10
11
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
11
12
|
import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
13
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
13
|
-
import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
14
|
+
import { normalizeE164, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
14
15
|
import path from "node:path";
|
|
15
16
|
import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
16
17
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
@@ -473,7 +474,7 @@ function createSignalEventHandler(deps) {
|
|
|
473
474
|
extra: { GroupSubject: entry.isGroup ? entry.groupName ?? void 0 : void 0 }
|
|
474
475
|
});
|
|
475
476
|
if (shouldLogVerbose()) {
|
|
476
|
-
const preview = body
|
|
477
|
+
const preview = truncateUtf16Safe(body, 200).replace(/\\n/g, "\\\\n");
|
|
477
478
|
logVerbose(`signal inbound: from=${ctxPayload.From} len=${body.length} preview="${preview}"`);
|
|
478
479
|
}
|
|
479
480
|
const { onModelSelected, typingCallbacks, ...replyPipeline } = createChannelMessageReplyPipeline({
|
|
@@ -1026,7 +1027,10 @@ async function runSignalSseLoop({ baseUrl, account, abortSignal, runtime, onEven
|
|
|
1026
1027
|
}
|
|
1027
1028
|
//#endregion
|
|
1028
1029
|
//#region extensions/signal/src/monitor.ts
|
|
1029
|
-
var monitor_exports = /* @__PURE__ */ __exportAll({
|
|
1030
|
+
var monitor_exports = /* @__PURE__ */ __exportAll({
|
|
1031
|
+
deliverReplies: () => deliverReplies,
|
|
1032
|
+
monitorSignalProvider: () => monitorSignalProvider
|
|
1033
|
+
});
|
|
1030
1034
|
function resolveRuntime(opts) {
|
|
1031
1035
|
return opts.runtime ?? createNonExitingRuntime();
|
|
1032
1036
|
}
|
|
@@ -1220,30 +1224,63 @@ async function fetchAttachment(params) {
|
|
|
1220
1224
|
}
|
|
1221
1225
|
async function deliverReplies(params) {
|
|
1222
1226
|
const { replies, target, baseUrl, account, accountId, runtime, maxBytes, textLimit, chunkMode } = params;
|
|
1223
|
-
for (const payload of replies)
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1227
|
+
for (const payload of replies) {
|
|
1228
|
+
const deliveryResults = [];
|
|
1229
|
+
const deliveredPayload = addSignalApprovalReactionHintToStructuredPayload({
|
|
1230
|
+
cfg: params.cfg,
|
|
1231
|
+
accountId,
|
|
1232
|
+
to: target,
|
|
1233
|
+
payload,
|
|
1234
|
+
targetAuthor: account
|
|
1235
|
+
}) ?? payload;
|
|
1236
|
+
const reply = resolveSendableOutboundReplyParts(deliveredPayload);
|
|
1237
|
+
const recordDeliveryResult = (result, visibleText) => {
|
|
1238
|
+
const messageId = typeof result?.messageId === "string" && result.messageId.trim() ? result.messageId.trim() : null;
|
|
1239
|
+
if (messageId) deliveryResults.push({
|
|
1240
|
+
channel: "signal",
|
|
1241
|
+
messageId,
|
|
1242
|
+
meta: { signalVisibleText: visibleText }
|
|
1234
1243
|
});
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1244
|
+
};
|
|
1245
|
+
if (await deliverTextOrMediaReply({
|
|
1246
|
+
payload: deliveredPayload,
|
|
1247
|
+
text: reply.text,
|
|
1248
|
+
chunkText: (value) => chunkTextWithMode(value, textLimit, chunkMode),
|
|
1249
|
+
sendText: async (chunk) => {
|
|
1250
|
+
recordDeliveryResult(await sendMessageSignal(target, chunk, {
|
|
1251
|
+
cfg: params.cfg,
|
|
1252
|
+
baseUrl,
|
|
1253
|
+
account,
|
|
1254
|
+
maxBytes,
|
|
1255
|
+
accountId
|
|
1256
|
+
}), chunk);
|
|
1257
|
+
},
|
|
1258
|
+
sendMedia: async ({ mediaUrl, caption }) => {
|
|
1259
|
+
const visibleText = caption ?? "";
|
|
1260
|
+
recordDeliveryResult(await sendMessageSignal(target, visibleText, {
|
|
1261
|
+
cfg: params.cfg,
|
|
1262
|
+
baseUrl,
|
|
1263
|
+
account,
|
|
1264
|
+
mediaUrl,
|
|
1265
|
+
maxBytes,
|
|
1266
|
+
accountId
|
|
1267
|
+
}), visibleText);
|
|
1268
|
+
}
|
|
1269
|
+
}) !== "empty") {
|
|
1270
|
+
registerSignalApprovalReactionTargetForDeliveredPayload({
|
|
1238
1271
|
cfg: params.cfg,
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1272
|
+
target: {
|
|
1273
|
+
channel: "signal",
|
|
1274
|
+
to: target,
|
|
1275
|
+
accountId
|
|
1276
|
+
},
|
|
1277
|
+
payload: deliveredPayload,
|
|
1278
|
+
results: deliveryResults,
|
|
1279
|
+
targetAuthor: account
|
|
1244
1280
|
});
|
|
1281
|
+
runtime.log?.(`delivered reply to ${target}`);
|
|
1245
1282
|
}
|
|
1246
|
-
}
|
|
1283
|
+
}
|
|
1247
1284
|
}
|
|
1248
1285
|
async function monitorSignalProvider(opts = {}) {
|
|
1249
1286
|
const runtime = resolveRuntime(opts);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { a as signalRpcRequest, i as signalCheck } from "./reaction-runtime-api-
|
|
2
|
+
import { a as signalRpcRequest, i as signalCheck } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
3
3
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
4
4
|
//#region extensions/signal/src/probe.ts
|
|
5
5
|
var probe_exports = /* @__PURE__ */ __exportAll({ probeSignal: () => probeSignal });
|
|
@@ -6,6 +6,7 @@ import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime"
|
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
|
|
9
|
+
import { readProviderTextResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
9
10
|
import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
|
|
10
11
|
import WebSocket from "ws";
|
|
11
12
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
@@ -176,12 +177,16 @@ async function containerRestRequest(endpoint, opts, method = "GET", body) {
|
|
|
176
177
|
const res = await fetchWithTimeout(url, init, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS$2);
|
|
177
178
|
if (res.status === 204) return;
|
|
178
179
|
if (!res.ok) {
|
|
179
|
-
const errorText = await res
|
|
180
|
+
const errorText = await readResponseTextLimited(res).catch(() => "");
|
|
180
181
|
throw new Error(`Signal REST ${res.status}: ${errorText || res.statusText}`);
|
|
181
182
|
}
|
|
182
|
-
const text = await res
|
|
183
|
+
const text = await readProviderTextResponse(res, "Signal REST");
|
|
183
184
|
if (!text) return;
|
|
184
|
-
|
|
185
|
+
try {
|
|
186
|
+
return JSON.parse(text);
|
|
187
|
+
} catch {
|
|
188
|
+
throw new Error("Signal REST returned malformed JSON");
|
|
189
|
+
}
|
|
185
190
|
}
|
|
186
191
|
/**
|
|
187
192
|
* Fetch attachment binary from bbernhard container.
|
|
@@ -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-BRJCLiqK.js";
|
|
2
2
|
export { removeReactionSignal, sendReactionSignal };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-hOCHbEhX.js";
|
|
2
2
|
import { d as normalizeSignalMessagingTarget, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
|
|
3
|
-
import { n as resolveSignalReactionLevel, t as signalMessageActions } from "./message-actions-
|
|
4
|
-
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-
|
|
3
|
+
import { n as resolveSignalReactionLevel, t as signalMessageActions } from "./message-actions-BnugYXjB.js";
|
|
4
|
+
import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
5
5
|
import { n as buildChannelConfigSchema, t as SignalConfigSchema } from "./config-api-KS-qhQvD.js";
|
|
6
|
-
import { r as installSignalCli } from "./install-signal-cli-
|
|
7
|
-
import {
|
|
8
|
-
import { t as
|
|
9
|
-
import { t as
|
|
6
|
+
import { r as installSignalCli } from "./install-signal-cli-TwhJ0DGy.js";
|
|
7
|
+
import { u as setSignalRuntime } from "./approval-reactions-H-RPGBK7.js";
|
|
8
|
+
import { t as monitorSignalProvider } from "./monitor-C1gdgT7W.js";
|
|
9
|
+
import { t as sendMessageSignal } from "./send-De6LIOLq.js";
|
|
10
|
+
import { t as probeSignal } from "./probe-BvFJLOBi.js";
|
|
10
11
|
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
11
12
|
import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
|
|
12
13
|
import { buildBaseAccountStatusSnapshot, buildBaseChannelStatusSummary, collectStatusIssuesFromLastError, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { i as resolveSignalAccount } from "./accounts-hOCHbEhX.js";
|
|
2
|
+
import { r as markdownToSignalText } from "./message-actions-BnugYXjB.js";
|
|
3
|
+
import { a as signalRpcRequest, r as resolveSignalRpcContext } from "./reaction-runtime-api-BRJCLiqK.js";
|
|
4
|
+
import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
|
|
5
|
+
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
6
|
+
import { kindFromMime, resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
|
|
7
|
+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
|
+
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
9
|
+
//#region extensions/signal/src/send.ts
|
|
10
|
+
async function resolveSignalRpcAccountInfo(opts) {
|
|
11
|
+
if (opts.baseUrl?.trim() && opts.account?.trim()) return;
|
|
12
|
+
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.");
|
|
13
|
+
return resolveSignalAccount({
|
|
14
|
+
cfg: requireRuntimeConfig(opts.cfg, "Signal RPC account resolution"),
|
|
15
|
+
accountId: opts.accountId
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function parseTarget(raw) {
|
|
19
|
+
let value = raw.trim();
|
|
20
|
+
if (!value) throw new Error("Signal recipient is required");
|
|
21
|
+
if (normalizeLowercaseStringOrEmpty(value).startsWith("signal:")) value = value.slice(7).trim();
|
|
22
|
+
const normalized = normalizeLowercaseStringOrEmpty(value);
|
|
23
|
+
if (normalized.startsWith("group:")) return {
|
|
24
|
+
type: "group",
|
|
25
|
+
groupId: value.slice(6).trim()
|
|
26
|
+
};
|
|
27
|
+
if (normalized.startsWith("username:")) return {
|
|
28
|
+
type: "username",
|
|
29
|
+
username: value.slice(9).trim()
|
|
30
|
+
};
|
|
31
|
+
if (normalized.startsWith("u:")) return {
|
|
32
|
+
type: "username",
|
|
33
|
+
username: value.trim()
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
type: "recipient",
|
|
37
|
+
recipient: value
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function buildTargetParams(target, allow) {
|
|
41
|
+
if (target.type === "recipient") {
|
|
42
|
+
if (!allow.recipient) return null;
|
|
43
|
+
return { recipient: [target.recipient] };
|
|
44
|
+
}
|
|
45
|
+
if (target.type === "group") {
|
|
46
|
+
if (!allow.group) return null;
|
|
47
|
+
return { groupId: target.groupId };
|
|
48
|
+
}
|
|
49
|
+
if (target.type === "username") {
|
|
50
|
+
if (!allow.username) return null;
|
|
51
|
+
return { username: [target.username] };
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function createSignalSendReceipt(params) {
|
|
56
|
+
const messageId = params.messageId.trim();
|
|
57
|
+
const results = messageId && messageId !== "unknown" ? [{
|
|
58
|
+
channel: "signal",
|
|
59
|
+
messageId,
|
|
60
|
+
meta: { targetType: params.target.type }
|
|
61
|
+
}] : [];
|
|
62
|
+
if (results[0]) {
|
|
63
|
+
if (params.timestamp != null) results[0].timestamp = params.timestamp;
|
|
64
|
+
if (params.target.type === "group") results[0].chatId = params.target.groupId;
|
|
65
|
+
else if (params.target.type === "recipient") results[0].toJid = params.target.recipient;
|
|
66
|
+
else results[0].toJid = params.target.username;
|
|
67
|
+
}
|
|
68
|
+
return createMessageReceiptFromOutboundResults({
|
|
69
|
+
results,
|
|
70
|
+
kind: params.kind
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function sendMessageSignal(to, text, opts) {
|
|
74
|
+
const cfg = requireRuntimeConfig(opts.cfg, "Signal send");
|
|
75
|
+
const apiMode = cfg.channels?.signal?.apiMode;
|
|
76
|
+
const accountInfo = resolveSignalAccount({
|
|
77
|
+
cfg,
|
|
78
|
+
accountId: opts.accountId
|
|
79
|
+
});
|
|
80
|
+
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
81
|
+
const target = parseTarget(to);
|
|
82
|
+
let message = text ?? "";
|
|
83
|
+
let messageFromPlaceholder = false;
|
|
84
|
+
let textStyles = [];
|
|
85
|
+
const textMode = opts.textMode ?? "markdown";
|
|
86
|
+
const maxBytes = (() => {
|
|
87
|
+
if (typeof opts.maxBytes === "number") return opts.maxBytes;
|
|
88
|
+
if (typeof accountInfo.config.mediaMaxMb === "number") return accountInfo.config.mediaMaxMb * 1024 * 1024;
|
|
89
|
+
if (typeof cfg.agents?.defaults?.mediaMaxMb === "number") return cfg.agents.defaults.mediaMaxMb * 1024 * 1024;
|
|
90
|
+
return 8 * 1024 * 1024;
|
|
91
|
+
})();
|
|
92
|
+
let attachments;
|
|
93
|
+
if (opts.mediaUrl?.trim()) {
|
|
94
|
+
const resolved = await resolveOutboundAttachmentFromUrl(opts.mediaUrl.trim(), maxBytes, {
|
|
95
|
+
mediaAccess: opts.mediaAccess,
|
|
96
|
+
localRoots: opts.mediaLocalRoots,
|
|
97
|
+
readFile: opts.mediaReadFile
|
|
98
|
+
});
|
|
99
|
+
attachments = [resolved.path];
|
|
100
|
+
const kind = kindFromMime(resolved.contentType ?? void 0);
|
|
101
|
+
if (!message && kind) {
|
|
102
|
+
message = kind === "image" ? "<media:image>" : `<media:${kind}>`;
|
|
103
|
+
messageFromPlaceholder = true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (message.trim() && !messageFromPlaceholder) if (textMode === "plain") textStyles = opts.textStyles ?? [];
|
|
107
|
+
else {
|
|
108
|
+
const tableMode = resolveMarkdownTableMode({
|
|
109
|
+
cfg,
|
|
110
|
+
channel: "signal",
|
|
111
|
+
accountId: accountInfo.accountId
|
|
112
|
+
});
|
|
113
|
+
const formatted = markdownToSignalText(message, { tableMode });
|
|
114
|
+
message = formatted.text;
|
|
115
|
+
textStyles = formatted.styles;
|
|
116
|
+
}
|
|
117
|
+
if (!message.trim() && (!attachments || attachments.length === 0)) throw new Error("Signal send requires text or media");
|
|
118
|
+
const params = { message };
|
|
119
|
+
if (textStyles.length > 0) params["text-style"] = textStyles.map((style) => `${style.start}:${style.length}:${style.style}`);
|
|
120
|
+
if (account) params.account = account;
|
|
121
|
+
if (attachments && attachments.length > 0) params.attachments = attachments;
|
|
122
|
+
const targetParams = buildTargetParams(target, {
|
|
123
|
+
recipient: true,
|
|
124
|
+
group: true,
|
|
125
|
+
username: true
|
|
126
|
+
});
|
|
127
|
+
if (!targetParams) throw new Error("Signal recipient is required");
|
|
128
|
+
Object.assign(params, targetParams);
|
|
129
|
+
const timestamp = (await signalRpcRequest("send", params, {
|
|
130
|
+
baseUrl,
|
|
131
|
+
timeoutMs: opts.timeoutMs,
|
|
132
|
+
apiMode
|
|
133
|
+
}))?.timestamp;
|
|
134
|
+
const messageId = timestamp ? String(timestamp) : "unknown";
|
|
135
|
+
return {
|
|
136
|
+
messageId,
|
|
137
|
+
timestamp,
|
|
138
|
+
receipt: createSignalSendReceipt({
|
|
139
|
+
messageId,
|
|
140
|
+
target,
|
|
141
|
+
kind: attachments && attachments.length > 0 ? "media" : "text",
|
|
142
|
+
...timestamp != null ? { timestamp } : {}
|
|
143
|
+
})
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async function sendTypingSignal(to, opts) {
|
|
147
|
+
const accountInfo = await resolveSignalRpcAccountInfo(opts);
|
|
148
|
+
const cfg = requireRuntimeConfig(opts.cfg, "Signal typing");
|
|
149
|
+
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
150
|
+
const targetParams = buildTargetParams(parseTarget(to), {
|
|
151
|
+
recipient: true,
|
|
152
|
+
group: true
|
|
153
|
+
});
|
|
154
|
+
if (!targetParams) return false;
|
|
155
|
+
const params = { ...targetParams };
|
|
156
|
+
if (account) params.account = account;
|
|
157
|
+
if (opts.stop) params.stop = true;
|
|
158
|
+
await signalRpcRequest("sendTyping", params, {
|
|
159
|
+
baseUrl,
|
|
160
|
+
timeoutMs: opts.timeoutMs,
|
|
161
|
+
apiMode: cfg.channels?.signal?.apiMode
|
|
162
|
+
});
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
async function sendReadReceiptSignal(to, targetTimestamp, opts) {
|
|
166
|
+
if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) return false;
|
|
167
|
+
const accountInfo = await resolveSignalRpcAccountInfo(opts);
|
|
168
|
+
const cfg = requireRuntimeConfig(opts.cfg, "Signal read receipt");
|
|
169
|
+
const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
|
|
170
|
+
const targetParams = buildTargetParams(parseTarget(to), { recipient: true });
|
|
171
|
+
if (!targetParams) return false;
|
|
172
|
+
const params = {
|
|
173
|
+
...targetParams,
|
|
174
|
+
targetTimestamp,
|
|
175
|
+
type: opts.type ?? "read"
|
|
176
|
+
};
|
|
177
|
+
if (account) params.account = account;
|
|
178
|
+
await signalRpcRequest("sendReceipt", params, {
|
|
179
|
+
baseUrl,
|
|
180
|
+
timeoutMs: opts.timeoutMs,
|
|
181
|
+
apiMode: cfg.channels?.signal?.apiMode
|
|
182
|
+
});
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
export { sendReadReceiptSignal as n, sendTypingSignal as r, sendMessageSignal as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as sendTypingSignal, t as sendMessageSignal } from "./send-
|
|
1
|
+
import { r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
|
|
2
2
|
export { sendMessageSignal, sendTypingSignal };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/signal",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.7.1-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/signal",
|
|
9
|
-
"version": "2026.
|
|
9
|
+
"version": "2026.7.1-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ws": "8.21.0"
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/signal",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.7.1-beta.1",
|
|
4
4
|
"description": "OpenClaw Signal channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"allowInvalidConfigRecovery": true
|
|
45
45
|
},
|
|
46
46
|
"compat": {
|
|
47
|
-
"pluginApi": ">=2026.
|
|
47
|
+
"pluginApi": ">=2026.7.1-beta.1"
|
|
48
48
|
},
|
|
49
49
|
"build": {
|
|
50
|
-
"openclawVersion": "2026.
|
|
50
|
+
"openclawVersion": "2026.7.1-beta.1",
|
|
51
51
|
"bundledDist": false
|
|
52
52
|
},
|
|
53
53
|
"release": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"README.md"
|
|
71
71
|
],
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"openclaw": ">=2026.
|
|
73
|
+
"openclaw": ">=2026.7.1-beta.1"
|
|
74
74
|
},
|
|
75
75
|
"peerDependenciesMeta": {
|
|
76
76
|
"openclaw": {
|