@openclaw/imessage 2026.10.1 → 2026.10.5-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/.setup/{accounts-evTpvJMv.mjs → accounts-DacCvDBt.mjs} +23 -45
- package/dist/.setup/{actions-DJqbUmbN.mjs → actions-Hxh12myO.mjs} +54 -101
- package/dist/.setup/{actions.runtime-DL5i-Y4J.mjs → actions.runtime-DOIX6Fkf.mjs} +29 -37
- package/dist/.setup/{api-oq_MryN7.mjs → api-BV8qHfLl.mjs} +7 -7
- package/dist/.setup/{api-SAVMfMoY.mjs → api-DC1yHVGj.mjs} +8 -8
- package/dist/.setup/{approval-handler.runtime-Bj2NGNXF.mjs → approval-handler.runtime-Dc3KzakG.mjs} +38 -66
- package/dist/.setup/{approval-reactions-L9Ul7PAu.mjs → approval-reactions-JvzJCJ4a.mjs} +26 -33
- package/dist/.setup/{channel-CL73qdMG.mjs → channel-9TWBUDkP.mjs} +14 -16
- package/dist/.setup/{channel.runtime-DY7JJ0_9.mjs → channel.runtime-DrLDEY4R.mjs} +198 -362
- package/dist/.setup/{client-12apu4Ip.mjs → client-HixFQQWY.mjs} +34 -38
- package/dist/.setup/{media-contract-DjQGZlfl.mjs → media-contract-BwWs5PM7.mjs} +1 -1
- package/dist/.setup/{message-tool-api-CqfRxLlT.mjs → message-tool-api-B5NfPnFL.mjs} +2 -2
- package/dist/.setup/{question-reactions-DJV-TnA8.mjs → question-reactions-9jrqVZgE.mjs} +20 -25
- package/dist/.setup/{reaction-context-By7kUMBC.mjs → reaction-context-CRXpeYAr.mjs} +1 -1
- package/dist/.setup/{remote-file-BU7pA-Zi.mjs → remote-file-Dq5Asi_F.mjs} +10 -16
- package/dist/.setup/{sanitize-outbound-C0x4BPky.mjs → sanitize-outbound-DpdQERYJ.mjs} +27 -62
- package/dist/.setup/{send-pkYwL6Rt.mjs → send-BZZzMbdi.mjs} +186 -251
- package/dist/.setup/{setup-core-DqOBe-n0.mjs → setup-core-CaRGbZOL.mjs} +15 -46
- package/dist/.setup/{setup-surface-zKhIinwY.mjs → setup-surface-BMWS7VuY.mjs} +2 -2
- package/dist/.setup/{targets-BicBiYsM.mjs → targets-B4oU7n-v.mjs} +47 -69
- package/dist/api.js +7 -7
- package/dist/channel-plugin-api.js +1 -1
- package/dist/contract-api.js +1 -1
- package/dist/doctor-contract-api.js +21 -45
- package/dist/media-contract-api.js +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/runtime-api.js +1 -1
- package/dist/setup-entry.js +1 -1
- package/dist/src/chat-db.worker.js +1 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { normalizeAccountId, resolveAccountEntry } from "openclaw/plugin-sdk/account-resolution";
|
|
3
3
|
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
4
4
|
import { accessSync, constants, readFileSync, realpathSync, statSync } from "node:fs";
|
|
@@ -184,12 +184,7 @@ async function resolveIMessageRemoteHost(params) {
|
|
|
184
184
|
const { listAccountIds, resolveDefaultAccountId, resolveAccountConfig: resolveMergedIMessageAccountConfig } = createAccountListHelpers("imessage", { implicitDefaultAccount: { channelKeys: ["cliPath", "dbPath"] } });
|
|
185
185
|
const listIMessageAccountIds = listAccountIds;
|
|
186
186
|
const resolveDefaultIMessageAccountId = resolveDefaultAccountId;
|
|
187
|
-
function
|
|
188
|
-
return asOptionalRecord(value);
|
|
189
|
-
}
|
|
190
|
-
function mergeIMessageStreamingConfig(base, account) {
|
|
191
|
-
const baseConfig = asStreamingConfigObject(base);
|
|
192
|
-
const accountConfig = asStreamingConfigObject(account);
|
|
187
|
+
function mergeIMessageStreamingConfig(baseConfig, accountConfig) {
|
|
193
188
|
if (!baseConfig || !accountConfig) return accountConfig ?? baseConfig;
|
|
194
189
|
return {
|
|
195
190
|
...baseConfig,
|
|
@@ -207,7 +202,7 @@ function mergeIMessageStreamingConfig(base, account) {
|
|
|
207
202
|
function mergeIMessageAccountConfig(cfg, accountId) {
|
|
208
203
|
const accountConfig = resolveAccountEntry(cfg.channels?.imessage?.accounts, accountId);
|
|
209
204
|
const merged = resolveMergedIMessageAccountConfig(cfg, accountId);
|
|
210
|
-
const streaming = mergeIMessageStreamingConfig(
|
|
205
|
+
const streaming = mergeIMessageStreamingConfig(cfg.channels?.imessage?.streaming, accountConfig?.streaming);
|
|
211
206
|
return streaming !== void 0 ? {
|
|
212
207
|
...merged,
|
|
213
208
|
streaming
|
|
@@ -253,22 +248,23 @@ function resolveIMessageAccountSourceSignature(account) {
|
|
|
253
248
|
""
|
|
254
249
|
]);
|
|
255
250
|
}
|
|
256
|
-
function
|
|
257
|
-
|
|
258
|
-
for (const
|
|
259
|
-
const
|
|
260
|
-
cfg
|
|
261
|
-
accountId
|
|
251
|
+
function groupIMessageAccountsBySource(cfg) {
|
|
252
|
+
const groups = /* @__PURE__ */ new Map();
|
|
253
|
+
for (const accountId of listIMessageAccountIds(cfg)) {
|
|
254
|
+
const account = resolveIMessageAccount({
|
|
255
|
+
cfg,
|
|
256
|
+
accountId
|
|
262
257
|
});
|
|
263
|
-
if (!
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
return candidate.accountId;
|
|
258
|
+
if (!account.enabled || !account.configured) continue;
|
|
259
|
+
const signature = resolveIMessageAccountSourceSignature(account);
|
|
260
|
+
const accounts = groups.get(signature) ?? [];
|
|
261
|
+
accounts.push(account);
|
|
262
|
+
groups.set(signature, accounts);
|
|
270
263
|
}
|
|
271
|
-
return
|
|
264
|
+
return groups;
|
|
265
|
+
}
|
|
266
|
+
function resolveIMessageAccountSourceOwner(accounts) {
|
|
267
|
+
return accounts.find((account) => account.accountId !== DEFAULT_ACCOUNT_ID) ?? accounts[0];
|
|
272
268
|
}
|
|
273
269
|
function resolveIMessageDatabaseFileIdentity(dbPath) {
|
|
274
270
|
try {
|
|
@@ -288,11 +284,9 @@ function resolveIMessageDatabaseFileIdentity(dbPath) {
|
|
|
288
284
|
*/
|
|
289
285
|
function resolveIMessageDuplicateSourceOwner(params) {
|
|
290
286
|
if (!params.account.enabled || !params.account.configured) return;
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
});
|
|
295
|
-
return owner && owner !== params.account.accountId ? owner : void 0;
|
|
287
|
+
const signature = resolveIMessageAccountSourceSignature(params.account);
|
|
288
|
+
const owner = resolveIMessageAccountSourceOwner(groupIMessageAccountsBySource(params.cfg).get(signature) ?? []);
|
|
289
|
+
return owner && owner.accountId !== params.account.accountId ? owner.accountId : void 0;
|
|
296
290
|
}
|
|
297
291
|
function listEnabledIMessageAccounts(cfg) {
|
|
298
292
|
return listIMessageAccountIds(cfg).map((accountId) => resolveIMessageAccount({
|
|
@@ -325,27 +319,11 @@ function hasExclusiveIMessageLocalDatabase(params) {
|
|
|
325
319
|
return true;
|
|
326
320
|
}
|
|
327
321
|
function collectIMessageDuplicateAccountSourceWarnings(params) {
|
|
328
|
-
const groups =
|
|
329
|
-
for (const accountId of listIMessageAccountIds(params.cfg)) {
|
|
330
|
-
const account = resolveIMessageAccount({
|
|
331
|
-
cfg: params.cfg,
|
|
332
|
-
accountId
|
|
333
|
-
});
|
|
334
|
-
if (!account.enabled || !account.configured) continue;
|
|
335
|
-
const signature = resolveIMessageAccountSourceSignature(account);
|
|
336
|
-
const existing = groups.get(signature);
|
|
337
|
-
if (existing) existing.push(account);
|
|
338
|
-
else groups.set(signature, [account]);
|
|
339
|
-
}
|
|
322
|
+
const groups = groupIMessageAccountsBySource(params.cfg);
|
|
340
323
|
const warnings = [];
|
|
341
324
|
for (const collisions of groups.values()) {
|
|
342
325
|
if (collisions.length < 2) continue;
|
|
343
|
-
const
|
|
344
|
-
const ownerId = resolveIMessageAccountSourceOwner({
|
|
345
|
-
cfg: params.cfg,
|
|
346
|
-
signature: resolveIMessageAccountSourceSignature(firstCollision)
|
|
347
|
-
});
|
|
348
|
-
const owner = collisions.find((a) => a.accountId === ownerId) ?? firstCollision;
|
|
326
|
+
const owner = expectDefined(resolveIMessageAccountSourceOwner(collisions), "duplicate iMessage account source");
|
|
349
327
|
const dupIds = collisions.filter((a) => a.accountId !== owner.accountId).map((a) => `"${a.accountId}"`).join(", ");
|
|
350
328
|
const cliPath = normalizeIMessageCliPath(owner.config.cliPath);
|
|
351
329
|
const dbPath = normalizeIMessageDbPath(owner.config.dbPath);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as parseIMessageTarget } from "./targets-
|
|
2
|
-
import { l as resolveIMessageRemoteHost, n as hasExclusiveIMessageLocalDatabase, o as resolveIMessageAccount, u as expandIMessageUserPath } from "./accounts-
|
|
3
|
-
import { a as setCachedIMessagePrivateApiStatus, n as getCachedIMessagePrivateApiStatus, o as IMESSAGE_ACTIONS, r as imessageRpcSupportsMethod, s as IMESSAGE_ACTION_NAMES, t as describeIMessageMessageTool } from "./message-tool-api-
|
|
4
|
-
import { a as isIMessageCurrentMessageInChat, b as chatContextFromIMessageTarget, c as rememberIMessageReplyCache, i as findLatestIMessageEntryForChat, n as createIMessageRpcClient, o as isIMessageCurrentMessageInChatAsync } from "./client-
|
|
5
|
-
import { l as isAutoManagedIMessageCliPath, n as IMESSAGE_UPDATE_COMMAND, t as IMESSAGE_INSTALL_COMMAND } from "./setup-core-
|
|
1
|
+
import { c as parseIMessageTarget } from "./targets-B4oU7n-v.mjs";
|
|
2
|
+
import { l as resolveIMessageRemoteHost, n as hasExclusiveIMessageLocalDatabase, o as resolveIMessageAccount, u as expandIMessageUserPath } from "./accounts-DacCvDBt.mjs";
|
|
3
|
+
import { a as setCachedIMessagePrivateApiStatus, n as getCachedIMessagePrivateApiStatus, o as IMESSAGE_ACTIONS, r as imessageRpcSupportsMethod, s as IMESSAGE_ACTION_NAMES, t as describeIMessageMessageTool } from "./message-tool-api-B5NfPnFL.mjs";
|
|
4
|
+
import { a as isIMessageCurrentMessageInChat, b as chatContextFromIMessageTarget, c as rememberIMessageReplyCache, i as findLatestIMessageEntryForChat, n as createIMessageRpcClient, o as isIMessageCurrentMessageInChatAsync } from "./client-HixFQQWY.mjs";
|
|
5
|
+
import { l as isAutoManagedIMessageCliPath, n as IMESSAGE_UPDATE_COMMAND, t as IMESSAGE_INSTALL_COMMAND } from "./setup-core-CaRGbZOL.mjs";
|
|
6
6
|
import { filterStringEntries, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
|
|
8
8
|
import path from "node:path";
|
|
@@ -68,16 +68,6 @@ function cacheIMessagePrivateApiStatus(cliPath, status) {
|
|
|
68
68
|
const expiresAt = resolveExpiresAtMsFromDurationMs(PRIVATE_API_NEGATIVE_TTL_MS);
|
|
69
69
|
if (expiresAt !== void 0) setCachedIMessagePrivateApiStatus(cliPath, status, expiresAt);
|
|
70
70
|
}
|
|
71
|
-
function getCachedRpcSupport(cliPath) {
|
|
72
|
-
const cached = rpcSupportCache.get(cliPath);
|
|
73
|
-
if (!cached) return;
|
|
74
|
-
const now = asDateTimestampMs(Date.now());
|
|
75
|
-
if (now === void 0 || cached.expiresAt <= now) {
|
|
76
|
-
rpcSupportCache.delete(cliPath);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
return cached.result;
|
|
80
|
-
}
|
|
81
71
|
function setCachedRpcSupport(cliPath, result) {
|
|
82
72
|
const expiresAt = resolveExpiresAtMsFromDurationMs(RPC_SUPPORT_CACHE_TTL_MS);
|
|
83
73
|
if (expiresAt === void 0) return;
|
|
@@ -86,17 +76,13 @@ function setCachedRpcSupport(cliPath, result) {
|
|
|
86
76
|
expiresAt
|
|
87
77
|
});
|
|
88
78
|
}
|
|
89
|
-
function isDefaultLocalIMessageCliPath(cliPath) {
|
|
90
|
-
const trimmed = cliPath.trim();
|
|
91
|
-
return trimmed === "imsg" || !trimmed.includes("/") && path.basename(trimmed) === "imsg";
|
|
92
|
-
}
|
|
93
|
-
function resolveIMessageNonMacHostError(cliPath, platform = process.platform) {
|
|
94
|
-
if (platform === "darwin" || !isDefaultLocalIMessageCliPath(cliPath)) return;
|
|
95
|
-
return "iMessage via the default imsg CLI must run on macOS. Run OpenClaw on the signed-in Messages Mac, or set channels.imessage.cliPath to an SSH wrapper that runs imsg on that Mac.";
|
|
96
|
-
}
|
|
97
79
|
async function probeRpcSupport(cliPath, timeoutMs) {
|
|
98
|
-
const cached =
|
|
99
|
-
if (cached)
|
|
80
|
+
const cached = rpcSupportCache.get(cliPath);
|
|
81
|
+
if (cached) {
|
|
82
|
+
const now = asDateTimestampMs(Date.now());
|
|
83
|
+
if (now !== void 0 && cached.expiresAt > now) return cached.result;
|
|
84
|
+
rpcSupportCache.delete(cliPath);
|
|
85
|
+
}
|
|
100
86
|
try {
|
|
101
87
|
const result = await runCommandWithTimeout([
|
|
102
88
|
expandIMessageUserPath(cliPath),
|
|
@@ -130,24 +116,6 @@ async function probeRpcSupport(cliPath, timeoutMs) {
|
|
|
130
116
|
};
|
|
131
117
|
}
|
|
132
118
|
}
|
|
133
|
-
function parseStatusPayload(stdout) {
|
|
134
|
-
const lines = normalizeStringEntries(stdout.split(/\r?\n/));
|
|
135
|
-
for (const line of lines.toReversed()) try {
|
|
136
|
-
const value = JSON.parse(line);
|
|
137
|
-
if (value && typeof value === "object" && !Array.isArray(value)) return { payload: value };
|
|
138
|
-
} catch {}
|
|
139
|
-
return {
|
|
140
|
-
payload: null,
|
|
141
|
-
firstLineSnippet: lines[0] ? truncateUtf16Safe(lines[0], 120) : void 0
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
function selectorsFromPayload(payload) {
|
|
145
|
-
const raw = payload.selectors;
|
|
146
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
147
|
-
const selectors = {};
|
|
148
|
-
for (const [key, value] of Object.entries(raw)) if (typeof value === "boolean") selectors[key] = value;
|
|
149
|
-
return selectors;
|
|
150
|
-
}
|
|
151
119
|
async function probeIMessageCliFlag(cliPath, timeoutMs, command, flag) {
|
|
152
120
|
try {
|
|
153
121
|
const result = await runCommandWithTimeout([
|
|
@@ -191,8 +159,21 @@ async function probeIMessagePrivateApi(cliPath, timeoutMs, options = {}) {
|
|
|
191
159
|
cacheIMessagePrivateApiStatus(key, status);
|
|
192
160
|
return status;
|
|
193
161
|
}
|
|
194
|
-
const
|
|
195
|
-
|
|
162
|
+
const lines = normalizeStringEntries(result.stdout.split(/\r?\n/));
|
|
163
|
+
let payload = null;
|
|
164
|
+
for (const line of lines.toReversed()) try {
|
|
165
|
+
const value = JSON.parse(line);
|
|
166
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
167
|
+
payload = value;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
} catch {}
|
|
171
|
+
const firstLineSnippet = !payload && lines[0] ? truncateUtf16Safe(lines[0], 120) : void 0;
|
|
172
|
+
const rawSelectors = payload?.selectors;
|
|
173
|
+
const selectors = {};
|
|
174
|
+
if (rawSelectors && typeof rawSelectors === "object" && !Array.isArray(rawSelectors)) {
|
|
175
|
+
for (const [selector, value] of Object.entries(rawSelectors)) if (typeof value === "boolean") selectors[selector] = value;
|
|
176
|
+
}
|
|
196
177
|
const rpcMethods = filterStringEntries(payload?.rpc_methods);
|
|
197
178
|
const advancedFeatures = payload?.advanced_features === true;
|
|
198
179
|
const v2Ready = payload?.v2_ready === true;
|
|
@@ -239,11 +220,10 @@ async function probeIMessage(timeoutMs, opts = {}) {
|
|
|
239
220
|
remoteHost: opts.remoteHost ?? cfg?.channels?.imessage?.remoteHost
|
|
240
221
|
});
|
|
241
222
|
const effectiveTimeout = timeoutMs ?? cfg?.channels?.imessage?.probeTimeoutMs ?? 1e4;
|
|
242
|
-
|
|
243
|
-
if (nonMacHostError) return {
|
|
223
|
+
if ((opts.platform ?? process.platform) !== "darwin" && (cliPath === "imsg" || !cliPath.includes("/") && path.basename(cliPath) === "imsg")) return {
|
|
244
224
|
ok: false,
|
|
245
225
|
fatal: true,
|
|
246
|
-
error:
|
|
226
|
+
error: "iMessage via the default imsg CLI must run on macOS. Run OpenClaw on the signed-in Messages Mac, or set channels.imessage.cliPath to an SSH wrapper that runs imsg on that Mac."
|
|
247
227
|
};
|
|
248
228
|
if (!await detectBinary(expandIMessageUserPath(cliPath))) return {
|
|
249
229
|
ok: false,
|
|
@@ -280,7 +260,7 @@ async function probeIMessage(timeoutMs, opts = {}) {
|
|
|
280
260
|
}
|
|
281
261
|
//#endregion
|
|
282
262
|
//#region extensions/imessage/src/actions.ts
|
|
283
|
-
const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-
|
|
263
|
+
const loadIMessageActionsRuntime = createLazyRuntimeNamedExport(() => import("./actions.runtime-DOIX6Fkf.mjs"), "imessageActionsRuntime");
|
|
284
264
|
const log = createSubsystemLogger("channels/imessage");
|
|
285
265
|
const providerId = "imessage";
|
|
286
266
|
const SUPPORTED_ACTIONS = /* @__PURE__ */ new Set([...IMESSAGE_ACTION_NAMES, "upload-file"]);
|
|
@@ -348,21 +328,6 @@ function createIMessageTargetAliases(resourceAliases = []) {
|
|
|
348
328
|
}
|
|
349
329
|
};
|
|
350
330
|
}
|
|
351
|
-
async function completeOutboundBridgeMessage(params) {
|
|
352
|
-
const messageId = normalizeIMessageMessageId(params.messageId);
|
|
353
|
-
if (messageId) await rememberIMessageReplyCache({
|
|
354
|
-
accountId: params.accountId,
|
|
355
|
-
messageId,
|
|
356
|
-
chatGuid: params.chatGuid,
|
|
357
|
-
timestamp: Date.now(),
|
|
358
|
-
isFromMe: true
|
|
359
|
-
});
|
|
360
|
-
return jsonResult({
|
|
361
|
-
ok: true,
|
|
362
|
-
messageId: params.messageId,
|
|
363
|
-
...params.details
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
331
|
/** An omitted action reference targets the most recent inbound in the same chat. */
|
|
367
332
|
function readMessageIdWithChatFallback(params, chatContext) {
|
|
368
333
|
const explicit = readStringParam(params, "messageId");
|
|
@@ -545,7 +510,7 @@ const imessageMessageActions = {
|
|
|
545
510
|
}
|
|
546
511
|
};
|
|
547
512
|
const opts = {
|
|
548
|
-
cliPath:
|
|
513
|
+
cliPath: cliPathForProbe,
|
|
549
514
|
dbPath: account.config.dbPath?.trim() || void 0,
|
|
550
515
|
remoteHost,
|
|
551
516
|
timeoutMs: account.config.probeTimeoutMs
|
|
@@ -592,6 +557,21 @@ const imessageMessageActions = {
|
|
|
592
557
|
}
|
|
593
558
|
});
|
|
594
559
|
};
|
|
560
|
+
const completeOutboundBridgeMessage = async (result, targetChatGuid, details) => {
|
|
561
|
+
const messageId = normalizeIMessageMessageId(result.messageId);
|
|
562
|
+
if (messageId) await rememberIMessageReplyCache({
|
|
563
|
+
accountId: account.accountId,
|
|
564
|
+
messageId,
|
|
565
|
+
chatGuid: targetChatGuid,
|
|
566
|
+
timestamp: Date.now(),
|
|
567
|
+
isFromMe: true
|
|
568
|
+
});
|
|
569
|
+
return jsonResult({
|
|
570
|
+
ok: true,
|
|
571
|
+
messageId: result.messageId,
|
|
572
|
+
...details
|
|
573
|
+
});
|
|
574
|
+
};
|
|
595
575
|
await assertPrivateApiEnabled();
|
|
596
576
|
if (action === "react") {
|
|
597
577
|
const { emoji, remove, isEmpty } = readReactionParams(params, { removeErrorMessage: "Emoji is required to remove an iMessage reaction." });
|
|
@@ -664,38 +644,26 @@ const imessageMessageActions = {
|
|
|
664
644
|
if (!opts.remoteHost && privateApiStatus?.cliCapabilities?.sendRichSupportsAttachment !== true) throw new Error("iMessage reply with an attachment needs an imsg build that exposes `send-rich --file` (openclaw/imsg#114). Upgrade imsg, or use action 'upload-file' (with filePath/filename) or action 'send' (with media) to deliver the file plus a separate 'reply' for any text.");
|
|
665
645
|
}
|
|
666
646
|
const partIndex = readNonNegativeIntegerParam(params, "partIndex");
|
|
667
|
-
|
|
647
|
+
return await completeOutboundBridgeMessage(await runtime.sendRichMessage({
|
|
668
648
|
chatGuid: reference.chatGuid,
|
|
669
649
|
text,
|
|
670
650
|
replyToMessageId: reference.messageId,
|
|
671
651
|
partIndex,
|
|
672
652
|
attachment: attachment?.spec ?? void 0,
|
|
673
653
|
options: opts
|
|
674
|
-
});
|
|
675
|
-
return await completeOutboundBridgeMessage({
|
|
676
|
-
accountId: account.accountId,
|
|
677
|
-
messageId: result.messageId,
|
|
678
|
-
chatGuid: reference.chatGuid,
|
|
679
|
-
details: { repliedTo: reference.messageId }
|
|
680
|
-
});
|
|
654
|
+
}), reference.chatGuid, { repliedTo: reference.messageId });
|
|
681
655
|
}
|
|
682
656
|
if (action === "sendWithEffect") {
|
|
683
657
|
const text = readMessageText(params);
|
|
684
658
|
const effectId = effectIdFromParam(readStringParam(params, "effectId") ?? readStringParam(params, "effect"));
|
|
685
659
|
if (!text || !effectId) throw new Error("iMessage sendWithEffect requires text/message and effect/effectId.");
|
|
686
660
|
const resolvedChatGuid = await chatGuid();
|
|
687
|
-
|
|
661
|
+
return await completeOutboundBridgeMessage(await runtime.sendRichMessage({
|
|
688
662
|
chatGuid: resolvedChatGuid,
|
|
689
663
|
text,
|
|
690
664
|
effectId,
|
|
691
665
|
options: opts
|
|
692
|
-
});
|
|
693
|
-
return await completeOutboundBridgeMessage({
|
|
694
|
-
accountId: account.accountId,
|
|
695
|
-
messageId: result.messageId,
|
|
696
|
-
chatGuid: resolvedChatGuid,
|
|
697
|
-
details: { effect: effectId }
|
|
698
|
-
});
|
|
666
|
+
}), resolvedChatGuid, { effect: effectId });
|
|
699
667
|
}
|
|
700
668
|
if (action === "renameGroup") {
|
|
701
669
|
const displayName = readStringParam(params, "displayName") ?? readStringParam(params, "name");
|
|
@@ -757,18 +725,13 @@ const imessageMessageActions = {
|
|
|
757
725
|
const filename = readStringParam(params, "filename", { required: true });
|
|
758
726
|
const asVoice = readBooleanParam(params, "asVoice");
|
|
759
727
|
const resolvedChatGuid = await chatGuid();
|
|
760
|
-
|
|
728
|
+
return await completeOutboundBridgeMessage(await runtime.sendAttachment({
|
|
761
729
|
chatGuid: resolvedChatGuid,
|
|
762
730
|
buffer: decodeBase64Buffer(params, action),
|
|
763
731
|
filename,
|
|
764
732
|
asVoice: asVoice ?? void 0,
|
|
765
733
|
options: opts
|
|
766
|
-
});
|
|
767
|
-
return await completeOutboundBridgeMessage({
|
|
768
|
-
accountId: account.accountId,
|
|
769
|
-
messageId: result.messageId,
|
|
770
|
-
chatGuid: resolvedChatGuid
|
|
771
|
-
});
|
|
734
|
+
}), resolvedChatGuid);
|
|
772
735
|
}
|
|
773
736
|
if (action === "poll") {
|
|
774
737
|
if (privateApiStatus?.selectors?.pollPayloadMessage !== true) await probePrivateApiStatus(true);
|
|
@@ -780,17 +743,12 @@ const imessageMessageActions = {
|
|
|
780
743
|
options: rawChoices
|
|
781
744
|
}, { maxOptions: 12 });
|
|
782
745
|
const resolvedChatGuid = await chatGuid();
|
|
783
|
-
|
|
746
|
+
return await completeOutboundBridgeMessage(await runtime.sendPoll({
|
|
784
747
|
chatGuid: resolvedChatGuid,
|
|
785
748
|
question: poll.question,
|
|
786
749
|
choices: poll.options,
|
|
787
750
|
options: opts
|
|
788
|
-
});
|
|
789
|
-
return await completeOutboundBridgeMessage({
|
|
790
|
-
accountId: account.accountId,
|
|
791
|
-
messageId: result.messageId,
|
|
792
|
-
chatGuid: resolvedChatGuid
|
|
793
|
-
});
|
|
751
|
+
}), resolvedChatGuid);
|
|
794
752
|
}
|
|
795
753
|
if (action === "poll-vote") {
|
|
796
754
|
if (privateApiStatus?.selectors?.pollVoteMessage !== true || !imessageRpcSupportsMethod(privateApiStatus, "poll.vote")) await probePrivateApiStatus(true);
|
|
@@ -817,12 +775,7 @@ const imessageMessageActions = {
|
|
|
817
775
|
optionText: optionText ?? void 0,
|
|
818
776
|
options: opts
|
|
819
777
|
});
|
|
820
|
-
return await completeOutboundBridgeMessage({
|
|
821
|
-
accountId: account.accountId,
|
|
822
|
-
messageId: result.messageId,
|
|
823
|
-
chatGuid: pollReference.chatGuid,
|
|
824
|
-
details: result.optionText ? { pollVotedOption: result.optionText } : void 0
|
|
825
|
-
});
|
|
778
|
+
return await completeOutboundBridgeMessage(result, pollReference.chatGuid, result.optionText ? { pollVotedOption: result.optionText } : void 0);
|
|
826
779
|
}
|
|
827
780
|
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
|
|
828
781
|
}
|
|
@@ -1,42 +1,19 @@
|
|
|
1
|
-
import { S as normalizeDirectChatIdentifier, n as createIMessageRpcClient, r as runIMessageCliJsonCommand, u as resolveIMessageMessageId } from "./client-
|
|
2
|
-
import { n as sanitizeIMessageFinalOutboundText } from "./sanitize-outbound-
|
|
3
|
-
import { n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-
|
|
1
|
+
import { S as normalizeDirectChatIdentifier, n as createIMessageRpcClient, r as runIMessageCliJsonCommand, u as resolveIMessageMessageId } from "./client-HixFQQWY.mjs";
|
|
2
|
+
import { n as sanitizeIMessageFinalOutboundText } from "./sanitize-outbound-DpdQERYJ.mjs";
|
|
3
|
+
import { n as authorizeIMessageResourceReference, t as withIMessageRemoteFile } from "./remote-file-Dq5Asi_F.mjs";
|
|
4
4
|
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { basename, parse, win32 } from "node:path";
|
|
6
6
|
import { asDateTimestampMs, parseStrictInteger, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
7
7
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
8
|
+
import { captureChannelReadAuthority, captureEffectAuthority } from "openclaw/plugin-sdk/fetch-runtime";
|
|
8
9
|
import { sanitizeUntrustedFileName } from "openclaw/plugin-sdk/security-runtime";
|
|
9
10
|
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
|
|
10
11
|
//#region extensions/imessage/src/actions-chat-guid.ts
|
|
11
12
|
const CHAT_LIST_CACHE_TTL_MS = 3e4;
|
|
12
13
|
const chatListCache = /* @__PURE__ */ new Map();
|
|
13
|
-
function asChatList(value) {
|
|
14
|
-
if (!isRecord(value)) return [];
|
|
15
|
-
return Array.isArray(value.chats) ? value.chats.filter(isRecord) : [];
|
|
16
|
-
}
|
|
17
14
|
function numberFromUnknown(value) {
|
|
18
15
|
return typeof value === "number" && Number.isFinite(value) ? value : parseStrictInteger(value);
|
|
19
16
|
}
|
|
20
|
-
function chatListCacheKey(options) {
|
|
21
|
-
return `${options.cliPath}\0${options.dbPath ?? ""}\0${options.remoteHost ?? ""}`;
|
|
22
|
-
}
|
|
23
|
-
function chatListCacheGet(options) {
|
|
24
|
-
const key = chatListCacheKey(options);
|
|
25
|
-
const entry = chatListCache.get(key);
|
|
26
|
-
const now = asDateTimestampMs(Date.now());
|
|
27
|
-
if (!entry || now === void 0 || entry.expiresAt <= now) {
|
|
28
|
-
chatListCache.delete(key);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
return entry.list;
|
|
32
|
-
}
|
|
33
|
-
function chatListCacheSet(options, list) {
|
|
34
|
-
const expiresAt = resolveExpiresAtMsFromDurationMs(CHAT_LIST_CACHE_TTL_MS);
|
|
35
|
-
if (expiresAt !== void 0) chatListCache.set(chatListCacheKey(options), {
|
|
36
|
-
list,
|
|
37
|
-
expiresAt
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
17
|
function findChatGuid(chats, target) {
|
|
41
18
|
if (target.kind === "chat_id") {
|
|
42
19
|
for (const chat of chats) {
|
|
@@ -55,12 +32,21 @@ function findChatGuid(chats, target) {
|
|
|
55
32
|
return null;
|
|
56
33
|
}
|
|
57
34
|
async function resolveIMessageActionChatGuid(params) {
|
|
58
|
-
const
|
|
59
|
-
|
|
35
|
+
const { cliPath, dbPath, remoteHost } = params.options;
|
|
36
|
+
const key = `${cliPath}\0${dbPath ?? ""}\0${remoteHost ?? ""}`;
|
|
37
|
+
const cached = chatListCache.get(key);
|
|
38
|
+
const now = asDateTimestampMs(Date.now());
|
|
39
|
+
if (cached && now !== void 0 && cached.expiresAt > now) return findChatGuid(cached.list, params.target);
|
|
40
|
+
chatListCache.delete(key);
|
|
60
41
|
const client = await createIMessageRpcClient(params.options);
|
|
61
42
|
try {
|
|
62
|
-
const
|
|
63
|
-
|
|
43
|
+
const result = await client.request("chats.list", { limit: 1e3 }, { timeoutMs: params.options.timeoutMs });
|
|
44
|
+
const list = isRecord(result) && Array.isArray(result.chats) ? result.chats.filter(isRecord) : [];
|
|
45
|
+
const expiresAt = resolveExpiresAtMsFromDurationMs(CHAT_LIST_CACHE_TTL_MS);
|
|
46
|
+
if (expiresAt !== void 0) chatListCache.set(key, {
|
|
47
|
+
list,
|
|
48
|
+
expiresAt
|
|
49
|
+
});
|
|
64
50
|
return findChatGuid(list, params.target);
|
|
65
51
|
} finally {
|
|
66
52
|
await client.stop();
|
|
@@ -79,12 +65,18 @@ function throwIMessageRemoteUnsupported(message) {
|
|
|
79
65
|
throw new IMessageRemoteUnsupportedError(`iMessage Remote Mac limitation: ${message}`);
|
|
80
66
|
}
|
|
81
67
|
async function runIMessageAction(options, method, params, args) {
|
|
82
|
-
if (!options.remoteHost)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
if (!options.remoteHost) {
|
|
69
|
+
const assertReadAuthority = captureChannelReadAuthority();
|
|
70
|
+
return await captureEffectAuthority().initiate(() => {
|
|
71
|
+
assertReadAuthority?.();
|
|
72
|
+
return runIMessageCliJsonCommand({
|
|
73
|
+
args,
|
|
74
|
+
cliPath: options.cliPath,
|
|
75
|
+
dbPath: options.dbPath,
|
|
76
|
+
timeoutMs: options.timeoutMs
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
88
80
|
const client = await createIMessageRpcClient({
|
|
89
81
|
cliPath: options.cliPath,
|
|
90
82
|
dbPath: options.dbPath,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as looksLikeIMessageExplicitTargetId, c as parseIMessageTarget,
|
|
2
|
-
import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./accounts-
|
|
3
|
-
import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./message-tool-api-
|
|
4
|
-
import { v as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./client-
|
|
5
|
-
import { n as probeIMessage } from "./actions-
|
|
6
|
-
import { c as matchIMessageAcpConversation, i as resolveIMessageGroupRequireMention, l as normalizeIMessageAcpConversationId, o as resolveIMessageGroupToolPolicy, s as resolveIMessageInboundConversationId, t as imessagePlugin, u as resolveIMessageConversationIdFromTarget } from "./channel-
|
|
1
|
+
import { a as looksLikeIMessageExplicitTargetId, c as parseIMessageTarget, d as normalizeIMessageMessagingTarget, i as isAllowedIMessageSender, n as inferIMessageTargetChatType, o as normalizeIMessageHandle, s as parseIMessageAllowTarget, t as formatIMessageChatTarget, u as looksLikeIMessageTargetId } from "./targets-B4oU7n-v.mjs";
|
|
2
|
+
import { a as resolveDefaultIMessageAccountId, i as listIMessageAccountIds, o as resolveIMessageAccount, r as listEnabledIMessageAccounts } from "./accounts-DacCvDBt.mjs";
|
|
3
|
+
import { o as IMESSAGE_ACTIONS, s as IMESSAGE_ACTION_NAMES } from "./message-tool-api-B5NfPnFL.mjs";
|
|
4
|
+
import { v as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./client-HixFQQWY.mjs";
|
|
5
|
+
import { n as probeIMessage } from "./actions-Hxh12myO.mjs";
|
|
6
|
+
import { c as matchIMessageAcpConversation, i as resolveIMessageGroupRequireMention, l as normalizeIMessageAcpConversationId, o as resolveIMessageGroupToolPolicy, s as resolveIMessageInboundConversationId, t as imessagePlugin, u as resolveIMessageConversationIdFromTarget } from "./channel-9TWBUDkP.mjs";
|
|
7
7
|
import { t as createIMessageConversationBindingManager } from "./conversation-bindings-GDQ_Laxj.mjs";
|
|
8
|
-
import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./api-
|
|
8
|
+
import { a as resolveServicePrefixedChatTarget, c as imessageSetupPlugin, i as resolveServicePrefixedAllowTarget, n as parseChatAllowTargetPrefixes, o as resolveServicePrefixedOrChatAllowTarget, r as parseChatTargetPrefixesOrThrow, s as resolveServicePrefixedTarget, t as createAllowedChatSenderMatcher } from "./api-DC1yHVGj.mjs";
|
|
9
9
|
import { t as IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS } from "./outbound-send-deps-B-QEsLSM.mjs";
|
|
10
10
|
export { DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS, IMESSAGE_ACTIONS, IMESSAGE_ACTION_NAMES, IMESSAGE_LEGACY_OUTBOUND_SEND_DEP_KEYS, createAllowedChatSenderMatcher, createIMessageConversationBindingManager, formatIMessageChatTarget, imessagePlugin, imessageSetupPlugin, inferIMessageTargetChatType, isAllowedIMessageSender, listEnabledIMessageAccounts, listIMessageAccountIds, looksLikeIMessageExplicitTargetId, looksLikeIMessageTargetId, matchIMessageAcpConversation, normalizeIMessageAcpConversationId, normalizeIMessageHandle, normalizeIMessageMessagingTarget, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, parseIMessageAllowTarget, parseIMessageTarget, probeIMessage, resolveDefaultIMessageAccountId, resolveIMessageAccount, resolveIMessageConversationIdFromTarget, resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy, resolveIMessageInboundConversationId, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget, resolveServicePrefixedOrChatAllowTarget, resolveServicePrefixedTarget };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import "./targets-
|
|
2
|
-
import "./accounts-
|
|
3
|
-
import "./message-tool-api-
|
|
4
|
-
import "./actions-
|
|
5
|
-
import { s as imessageSetupContract } from "./setup-core-
|
|
6
|
-
import { n as createIMessagePluginBase, r as imessageSetupWizard } from "./channel-
|
|
1
|
+
import "./targets-B4oU7n-v.mjs";
|
|
2
|
+
import "./accounts-DacCvDBt.mjs";
|
|
3
|
+
import "./message-tool-api-B5NfPnFL.mjs";
|
|
4
|
+
import "./actions-Hxh12myO.mjs";
|
|
5
|
+
import { s as imessageSetupContract } from "./setup-core-CaRGbZOL.mjs";
|
|
6
|
+
import { n as createIMessagePluginBase, r as imessageSetupWizard } from "./channel-9TWBUDkP.mjs";
|
|
7
7
|
import "./conversation-bindings-GDQ_Laxj.mjs";
|
|
8
8
|
import { createAllowedChatSenderMatcher as createAllowedChatSenderMatcher$1, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow as parseChatTargetPrefixesOrThrow$1, resolveServicePrefixedAllowTarget, resolveServicePrefixedChatTarget as resolveServicePrefixedChatTarget$1, resolveServicePrefixedOrChatAllowTarget as resolveServicePrefixedOrChatAllowTarget$1, resolveServicePrefixedTarget } from "openclaw/plugin-sdk/channel-targets";
|
|
9
9
|
//#region extensions/imessage/src/channel.setup.ts
|
|
10
|
-
const imessageSetupPlugin =
|
|
10
|
+
const imessageSetupPlugin = createIMessagePluginBase({
|
|
11
11
|
setupWizard: imessageSetupWizard,
|
|
12
12
|
setupContract: imessageSetupContract
|
|
13
|
-
})
|
|
13
|
+
});
|
|
14
14
|
//#endregion
|
|
15
15
|
export { resolveServicePrefixedChatTarget$1 as a, imessageSetupPlugin as c, resolveServicePrefixedAllowTarget as i, parseChatAllowTargetPrefixes as n, resolveServicePrefixedOrChatAllowTarget$1 as o, parseChatTargetPrefixesOrThrow$1 as r, resolveServicePrefixedTarget as s, createAllowedChatSenderMatcher$1 as t };
|