@openclaw/imessage 2026.8.1-beta.2 → 2026.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accounts-D00Njxg2.js → accounts-CCirBEIm.js} +4 -5
- package/dist/{actions.runtime-DTFKDN5p.js → actions.runtime-CAl3WcqD.js} +2 -3
- package/dist/api.js +6 -5
- package/dist/{approval-handler.runtime-BtLs4gho.js → approval-handler.runtime-UBd1j2Sg.js} +15 -9
- package/dist/approval-reactions-LL5yn1Rc.js +562 -0
- package/dist/{channel-lppmI51h.js → channel-DNI9DKGN.js} +26 -21
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-5wpCKQb7.js → channel.runtime-HSkrmWfW.js} +58 -11
- package/dist/{config-schema-DV0KP5nC.js → config-schema-DuGbA8Kp.js} +8 -7
- package/dist/contract-api.js +1 -1
- package/dist/doctor-contract-api.js +8 -281
- package/dist/{group-policy-DF9xSdik.js → group-policy-Dvc-BcWo.js} +19 -651
- package/dist/{media-contract-BEgdvYhW.js → media-contract-D-FhGE98.js} +1 -1
- package/dist/media-contract-api.js +1 -1
- package/dist/{message-tool-api-CPDfJJoE.js → message-tool-api-CvIgJpOo.js} +7 -4
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-DnxJ8pW9.js → monitor-BywJn1QW.js} +343 -111
- package/dist/{question-reactions-DVe50UhB.js → question-reactions-viP7ZcyG.js} +2 -1
- package/dist/reaction-context-BAYI7pz0.js +105 -0
- package/dist/{remote-file-DLwO9ved.js → remote-file-6mCj2ZBy.js} +7 -3
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/runtime-Cza4CY5T.js +8 -0
- package/dist/runtime-api.js +10 -9
- package/dist/{sanitize-outbound-CoTZLXMw.js → sanitize-outbound-Du-r1lNQ.js} +345 -58
- package/dist/{send-BUXW76tw.js → send-mgWPKqSV.js} +147 -26
- package/dist/state-contract-4TK_cDDb.js +56 -0
- package/dist/state-migrations-SFdKp3GQ.js +277 -0
- package/node_modules/typebox/build/format/date.d.mts +1 -1
- package/node_modules/typebox/build/format/date.mjs +1 -1
- package/node_modules/typebox/build/format/date_time.d.mts +2 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -3
- package/node_modules/typebox/build/format/email.d.mts +1 -1
- package/node_modules/typebox/build/format/email.mjs +2 -2
- package/node_modules/typebox/build/format/hostname.mjs +2 -10
- package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_email.mjs +3 -3
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
- package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
- package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
- package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
- package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
- package/node_modules/typebox/build/format/idna/index.mjs +2 -0
- package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
- package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
- package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
- package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
- package/node_modules/typebox/build/format/ipv4.mjs +2 -32
- package/node_modules/typebox/build/format/ipv6.mjs +2 -61
- package/node_modules/typebox/build/format/iri.d.mts +2 -2
- package/node_modules/typebox/build/format/iri.mjs +26 -8
- package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
- package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
- package/node_modules/typebox/build/format/regex.d.mts +1 -2
- package/node_modules/typebox/build/format/regex.mjs +2 -6
- package/node_modules/typebox/build/format/time.d.mts +2 -2
- package/node_modules/typebox/build/format/time.mjs +19 -14
- package/node_modules/typebox/build/format/uri.d.mts +1 -1
- package/node_modules/typebox/build/format/uri.mjs +3 -130
- package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
- package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
- package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
- package/node_modules/typebox/build/format/uri_template.mjs +4 -5
- package/node_modules/typebox/build/format/url.d.mts +3 -3
- package/node_modules/typebox/build/format/url.mjs +4 -5
- package/node_modules/typebox/build/guard/emit.d.mts +3 -1
- package/node_modules/typebox/build/guard/emit.mjs +12 -5
- package/node_modules/typebox/build/guard/guard.d.mts +8 -2
- package/node_modules/typebox/build/guard/guard.mjs +25 -4
- package/node_modules/typebox/build/guard/string.d.mts +2 -2
- package/node_modules/typebox/build/guard/string.mjs +7 -7
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
- package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
- package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
- package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
- package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
- package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
- package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
- package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/types/index.mjs +0 -2
- package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
- package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
- package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
- package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
- package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
- package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
- package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
- package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
- package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
- package/node_modules/typebox/build/type/script/parser.mjs +27 -23
- package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
- package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
- package/node_modules/typebox/package.json +27 -27
- package/node_modules/typebox/readme.md +79 -82
- package/openclaw.plugin.json +0 -6
- package/package.json +5 -5
- package/dist/catchup-D32oYNxR.js +0 -294
- package/dist/monitor-reply-cache-DKlYGd5x.js +0 -348
- package/dist/persisted-echo-cache-BPWGUK-L.js +0 -143
- package/node_modules/typebox/build/format/_idna.d.mts +0 -2
- package/node_modules/typebox/build/format/_idna.mjs +0 -246
- package/node_modules/typebox/build/format/_puny.d.mts +0 -1
- package/node_modules/typebox/build/format/_puny.mjs +0 -77
- package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
- package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
- package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
- package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { l as parseIMessageTarget, s as normalizeIMessageHandle } from "./message-tool-api-CvIgJpOo.js";
|
|
3
|
+
import { l as getIMessageApprovalApprovers, u as imessageApprovalAuth } from "./group-policy-Dvc-BcWo.js";
|
|
4
|
+
import { n as getOptionalIMessageRuntime } from "./runtime-Cza4CY5T.js";
|
|
5
|
+
import { t as resolveIMessageReactionContext } from "./reaction-context-BAYI7pz0.js";
|
|
6
|
+
import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
|
|
7
|
+
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
|
+
import { asDateTimestampMs, isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
9
|
+
import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
|
|
10
|
+
import { addApprovalReactionHintToText, approvalReactionDecisionSetsMatch, buildApprovalReactionDeliveredBindingMarker, buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, normalizeApprovalReactionDecision, readApprovalReactionDecisionList, readApprovalReactionDeliveredBinding, readApprovalReactionPresentationBinding, resolveTypedApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
11
|
+
import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
|
|
12
|
+
//#region extensions/imessage/src/approval-target-keys.ts
|
|
13
|
+
/** Strip the `p:<n>/` part prefix Messages puts on some GUIDs so keys match. */
|
|
14
|
+
function normalizeIMessageGuid(value) {
|
|
15
|
+
return value.trim().replace(/^p:\d+\//iu, "");
|
|
16
|
+
}
|
|
17
|
+
function chatIdToKeyValue(chatId) {
|
|
18
|
+
if (chatId == null || chatId === "") return null;
|
|
19
|
+
if (typeof chatId === "number") return Number.isFinite(chatId) && chatId > 0 ? String(chatId) : null;
|
|
20
|
+
return chatId.trim() || null;
|
|
21
|
+
}
|
|
22
|
+
function enumerateConversationKeyForms(conversation) {
|
|
23
|
+
const forms = [];
|
|
24
|
+
const chatGuid = conversation.chatGuid?.trim();
|
|
25
|
+
if (chatGuid) forms.push(`chat_guid:${chatGuid}`);
|
|
26
|
+
const chatIdentifier = conversation.chatIdentifier?.trim();
|
|
27
|
+
if (chatIdentifier) forms.push(`chat_identifier:${chatIdentifier}`);
|
|
28
|
+
const chatIdValue = chatIdToKeyValue(conversation.chatId);
|
|
29
|
+
if (chatIdValue) forms.push(`chat_id:${chatIdValue}`);
|
|
30
|
+
const handle = conversation.handle?.trim();
|
|
31
|
+
if (handle) forms.push(`handle:${handle}`);
|
|
32
|
+
return forms;
|
|
33
|
+
}
|
|
34
|
+
function normalizeConversationKey(conversation) {
|
|
35
|
+
return enumerateConversationKeyForms(conversation)[0];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Index a binding under every key derivable from the conversation. Outbound and
|
|
39
|
+
* inbound disagree about which key exists: send may only know
|
|
40
|
+
* `{handle: "+1..."}` for a DM, while the bridge populates chat_guid on the
|
|
41
|
+
* inbound event. Enumerating all forms keeps the two symmetric without making
|
|
42
|
+
* callers guess which one the bridge will pick.
|
|
43
|
+
*/
|
|
44
|
+
function enumerateApprovalTargetKeys(params) {
|
|
45
|
+
const accountId = params.accountId.trim();
|
|
46
|
+
const messageId = params.messageId.trim();
|
|
47
|
+
if (!accountId || !messageId) return [];
|
|
48
|
+
return enumerateConversationKeyForms(params.conversation).map((form) => `${accountId}:${form}:${messageId}`);
|
|
49
|
+
}
|
|
50
|
+
function buildIMessageApprovalConversationKeyForTarget(to) {
|
|
51
|
+
try {
|
|
52
|
+
const target = parseIMessageTarget(to);
|
|
53
|
+
if (target.kind === "chat_id") return { chatId: target.chatId };
|
|
54
|
+
if (target.kind === "chat_guid") return { chatGuid: target.chatGuid };
|
|
55
|
+
if (target.kind === "chat_identifier") return { chatIdentifier: target.chatIdentifier };
|
|
56
|
+
const handle = normalizeIMessageHandle(target.to);
|
|
57
|
+
return handle ? { handle } : null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Conversation key for an inbound event, mirroring the outbound key forms. */
|
|
63
|
+
function buildIMessageApprovalConversationKeyForInbound(params) {
|
|
64
|
+
return {
|
|
65
|
+
...params.chatGuid?.trim() ? { chatGuid: params.chatGuid.trim() } : {},
|
|
66
|
+
...params.chatIdentifier?.trim() ? { chatIdentifier: params.chatIdentifier.trim() } : {},
|
|
67
|
+
...chatIdToKeyValue(params.chatId ?? void 0) ? { chatId: params.chatId } : {},
|
|
68
|
+
...params.isGroup ? {} : { handle: params.actorHandle }
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region extensions/imessage/src/approval-reaction-poll-targets.ts
|
|
73
|
+
const PERSISTENT_POLL_TARGET_NAMESPACE = "imessage.approval-reaction-poll-targets";
|
|
74
|
+
const PERSISTENT_MAX_ENTRIES$1 = 1e3;
|
|
75
|
+
const DEFAULT_REACTION_TARGET_TTL_MS$1 = 1440 * 60 * 1e3;
|
|
76
|
+
const pendingReactionPollTargets = /* @__PURE__ */ new Map();
|
|
77
|
+
function prunePendingReactionPollTargets(nowMs = Date.now()) {
|
|
78
|
+
for (const [key, target] of pendingReactionPollTargets.entries()) if (!isFutureDateTimestampMs(target.expiresAtMs, { nowMs })) pendingReactionPollTargets.delete(key);
|
|
79
|
+
}
|
|
80
|
+
function resolvePendingReactionPollExpiry(ttlMs) {
|
|
81
|
+
const nowMs = asDateTimestampMs(Date.now());
|
|
82
|
+
if (nowMs === void 0) return;
|
|
83
|
+
const expiresAtMs = resolveExpiresAtMsFromDurationMs(ttlMs ?? DEFAULT_REACTION_TARGET_TTL_MS$1, { nowMs }) ?? resolveExpiresAtMsFromDurationMs(DEFAULT_REACTION_TARGET_TTL_MS$1, { nowMs });
|
|
84
|
+
if (expiresAtMs === void 0) return;
|
|
85
|
+
return {
|
|
86
|
+
ttlMs: expiresAtMs - nowMs,
|
|
87
|
+
expiresAtMs
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function mergePollTargetConversation(left, right) {
|
|
91
|
+
return {
|
|
92
|
+
chatGuid: left.chatGuid ?? right.chatGuid,
|
|
93
|
+
chatIdentifier: left.chatIdentifier ?? right.chatIdentifier,
|
|
94
|
+
chatId: left.chatId ?? right.chatId,
|
|
95
|
+
handle: left.handle ?? right.handle
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const reportPersistentApprovalReactionError$1 = createPluginStateErrorReporter(getOptionalIMessageRuntime, "imessage", "approval-reaction-state", "iMessage persistent approval reaction state failed");
|
|
99
|
+
let pendingReactionPollTargetStore;
|
|
100
|
+
let pendingReactionPollTargetStoreDisabled = false;
|
|
101
|
+
function disablePendingReactionPollTargetStore(error) {
|
|
102
|
+
pendingReactionPollTargetStoreDisabled = true;
|
|
103
|
+
pendingReactionPollTargetStore = void 0;
|
|
104
|
+
reportPersistentApprovalReactionError$1(error);
|
|
105
|
+
}
|
|
106
|
+
function getPendingReactionPollTargetStore() {
|
|
107
|
+
if (pendingReactionPollTargetStoreDisabled) return;
|
|
108
|
+
if (pendingReactionPollTargetStore) return pendingReactionPollTargetStore;
|
|
109
|
+
try {
|
|
110
|
+
pendingReactionPollTargetStore = getOptionalIMessageRuntime()?.state.openKeyedStore({
|
|
111
|
+
namespace: PERSISTENT_POLL_TARGET_NAMESPACE,
|
|
112
|
+
maxEntries: PERSISTENT_MAX_ENTRIES$1,
|
|
113
|
+
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS$1
|
|
114
|
+
});
|
|
115
|
+
return pendingReactionPollTargetStore;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
disablePendingReactionPollTargetStore(error);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function readPersistedPollTarget(value) {
|
|
122
|
+
const target = asOptionalRecord(value);
|
|
123
|
+
if (!target) return null;
|
|
124
|
+
const accountId = typeof target.accountId === "string" ? target.accountId.trim() : "";
|
|
125
|
+
const messageId = typeof target.messageId === "string" ? target.messageId.trim() : "";
|
|
126
|
+
const approvalId = typeof target.approvalId === "string" ? target.approvalId.trim() : "";
|
|
127
|
+
const expiresAtMs = asDateTimestampMs(target.expiresAtMs);
|
|
128
|
+
const allowedDecisions = readApprovalReactionDecisionList(target.allowedDecisions);
|
|
129
|
+
const rawConversation = asOptionalRecord(target.conversation) ?? {};
|
|
130
|
+
const conversation = {
|
|
131
|
+
...typeof rawConversation.chatGuid === "string" ? { chatGuid: rawConversation.chatGuid.trim() } : {},
|
|
132
|
+
...typeof rawConversation.chatIdentifier === "string" ? { chatIdentifier: rawConversation.chatIdentifier.trim() } : {},
|
|
133
|
+
...typeof rawConversation.chatId === "string" || typeof rawConversation.chatId === "number" ? { chatId: rawConversation.chatId } : {},
|
|
134
|
+
...typeof rawConversation.handle === "string" ? { handle: rawConversation.handle.trim() } : {}
|
|
135
|
+
};
|
|
136
|
+
if (!accountId || !messageId || !approvalId || expiresAtMs === void 0 || !allowedDecisions || target.approvalKind !== "exec" && target.approvalKind !== "plugin" || !normalizeConversationKey(conversation)) return null;
|
|
137
|
+
return {
|
|
138
|
+
accountId,
|
|
139
|
+
conversation,
|
|
140
|
+
messageId,
|
|
141
|
+
approvalId,
|
|
142
|
+
approvalKind: target.approvalKind,
|
|
143
|
+
allowedDecisions,
|
|
144
|
+
expiresAtMs
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function recordIMessageApprovalReactionPollTarget(params) {
|
|
148
|
+
const expiry = resolvePendingReactionPollExpiry(params.ttlMs);
|
|
149
|
+
if (!expiry || params.keys.length === 0) return null;
|
|
150
|
+
const target = {
|
|
151
|
+
accountId: params.accountId,
|
|
152
|
+
conversation: params.conversation,
|
|
153
|
+
messageId: params.messageId,
|
|
154
|
+
approvalId: params.approvalId,
|
|
155
|
+
approvalKind: params.approvalKind,
|
|
156
|
+
allowedDecisions: params.allowedDecisions,
|
|
157
|
+
expiresAtMs: expiry.expiresAtMs
|
|
158
|
+
};
|
|
159
|
+
const store = getPendingReactionPollTargetStore();
|
|
160
|
+
for (const key of params.keys) {
|
|
161
|
+
pendingReactionPollTargets.set(key, target);
|
|
162
|
+
store?.register(key, target, { ttlMs: expiry.ttlMs }).catch(disablePendingReactionPollTargetStore);
|
|
163
|
+
}
|
|
164
|
+
prunePendingReactionPollTargets();
|
|
165
|
+
return expiry;
|
|
166
|
+
}
|
|
167
|
+
function deleteIMessageApprovalReactionPollTargets(keys) {
|
|
168
|
+
const store = getPendingReactionPollTargetStore();
|
|
169
|
+
for (const key of keys) {
|
|
170
|
+
pendingReactionPollTargets.delete(key);
|
|
171
|
+
store?.delete(key).catch(disablePendingReactionPollTargetStore);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function listPendingIMessageApprovalReactionPollTargets(params) {
|
|
175
|
+
const accountId = params.accountId.trim();
|
|
176
|
+
if (!accountId) return [];
|
|
177
|
+
const nowMs = Date.now();
|
|
178
|
+
const store = getPendingReactionPollTargetStore();
|
|
179
|
+
if (store) try {
|
|
180
|
+
for (const entry of await store.entries()) {
|
|
181
|
+
const target = readPersistedPollTarget(entry.value);
|
|
182
|
+
if (!target || !isFutureDateTimestampMs(target.expiresAtMs, { nowMs })) {
|
|
183
|
+
await store.delete(entry.key);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
pendingReactionPollTargets.set(entry.key, target);
|
|
187
|
+
}
|
|
188
|
+
} catch (error) {
|
|
189
|
+
disablePendingReactionPollTargetStore(error);
|
|
190
|
+
}
|
|
191
|
+
prunePendingReactionPollTargets(nowMs);
|
|
192
|
+
const targetByApprovalAndMessage = /* @__PURE__ */ new Map();
|
|
193
|
+
for (const target of pendingReactionPollTargets.values()) {
|
|
194
|
+
if (target.accountId !== accountId) continue;
|
|
195
|
+
const key = `${target.approvalId}:${normalizeIMessageGuid(target.messageId)}`;
|
|
196
|
+
const existing = targetByApprovalAndMessage.get(key);
|
|
197
|
+
if (!existing) {
|
|
198
|
+
targetByApprovalAndMessage.set(key, target);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
targetByApprovalAndMessage.set(key, {
|
|
202
|
+
...existing,
|
|
203
|
+
conversation: mergePollTargetConversation(existing.conversation, target.conversation),
|
|
204
|
+
expiresAtMs: Math.max(existing.expiresAtMs, target.expiresAtMs)
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return [...targetByApprovalAndMessage.values()];
|
|
208
|
+
}
|
|
209
|
+
function clearIMessageApprovalReactionPollTargetsForTest() {
|
|
210
|
+
pendingReactionPollTargets.clear();
|
|
211
|
+
pendingReactionPollTargetStore = void 0;
|
|
212
|
+
pendingReactionPollTargetStoreDisabled = false;
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region extensions/imessage/src/approval-reactions.ts
|
|
216
|
+
var approval_reactions_exports = /* @__PURE__ */ __exportAll({
|
|
217
|
+
addIMessageApprovalReactionHintToStructuredPayload: () => addIMessageApprovalReactionHintToStructuredPayload,
|
|
218
|
+
buildIMessageApprovalConversationKeyForTarget: () => buildIMessageApprovalConversationKeyForTarget,
|
|
219
|
+
clearIMessageApprovalReactionTargetsForTest: () => clearIMessageApprovalReactionTargetsForTest,
|
|
220
|
+
handleIMessageApprovalReaction: () => handleIMessageApprovalReaction,
|
|
221
|
+
maybeResolveIMessageApprovalReaction: () => maybeResolveIMessageApprovalReaction,
|
|
222
|
+
registerIMessageApprovalReactionTarget: () => registerIMessageApprovalReactionTarget,
|
|
223
|
+
registerIMessageApprovalReactionTargetForDeliveredPayload: () => registerIMessageApprovalReactionTargetForDeliveredPayload,
|
|
224
|
+
resolveIMessageApprovalReactionTargetWithPersistence: () => resolveIMessageApprovalReactionTargetWithPersistence,
|
|
225
|
+
unregisterIMessageApprovalReactionTarget: () => unregisterIMessageApprovalReactionTarget
|
|
226
|
+
});
|
|
227
|
+
const PERSISTENT_NAMESPACE = "imessage.approval-reactions";
|
|
228
|
+
const PERSISTENT_MAX_ENTRIES = 1e3;
|
|
229
|
+
const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
|
|
230
|
+
const loadResolveApprovalOverGateway = createLazyRuntimeSurface(() => import("openclaw/plugin-sdk/approval-gateway-runtime"), (runtime) => runtime.resolveApprovalOverGateway);
|
|
231
|
+
const reportPersistentApprovalReactionError = createPluginStateErrorReporter(getOptionalIMessageRuntime, "imessage", "approval-reaction-state", "iMessage persistent approval reaction state failed");
|
|
232
|
+
function reportApprovalBindingCorrelationMismatch(binding) {
|
|
233
|
+
try {
|
|
234
|
+
getOptionalIMessageRuntime()?.logging.getChildLogger({
|
|
235
|
+
plugin: "imessage",
|
|
236
|
+
feature: "approval-reaction-state"
|
|
237
|
+
}).warn("iMessage approval prompt text failed binding correlation; tapbacks disabled", {
|
|
238
|
+
approvalId: binding.approvalId,
|
|
239
|
+
approvalKind: binding.approvalKind
|
|
240
|
+
});
|
|
241
|
+
} catch {}
|
|
242
|
+
}
|
|
243
|
+
function readPersistedTarget(value) {
|
|
244
|
+
const target = value;
|
|
245
|
+
if (!target || typeof target.approvalId !== "string" || target.approvalKind !== "exec" && target.approvalKind !== "plugin") return null;
|
|
246
|
+
const allowedDecisions = readApprovalReactionDecisionList(target.allowedDecisions);
|
|
247
|
+
if (!allowedDecisions) return null;
|
|
248
|
+
return {
|
|
249
|
+
approvalId: target.approvalId,
|
|
250
|
+
approvalKind: target.approvalKind,
|
|
251
|
+
allowedDecisions
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
const imessageApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
255
|
+
namespace: PERSISTENT_NAMESPACE,
|
|
256
|
+
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
257
|
+
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS,
|
|
258
|
+
openStore: (params) => getOptionalIMessageRuntime()?.state.openKeyedStore(params),
|
|
259
|
+
logPersistentError: reportPersistentApprovalReactionError,
|
|
260
|
+
readPersistedTarget
|
|
261
|
+
});
|
|
262
|
+
const IMESSAGE_APPROVAL_DELIVERY_BINDING_KEY = "imessageApprovalReactionBindingV1";
|
|
263
|
+
function visibleApprovalBindingMatches(text, binding, options) {
|
|
264
|
+
if (!text) return false;
|
|
265
|
+
const lines = text.split(/\r?\n/).map((line) => line.replace(/\*\*/g, "").trim());
|
|
266
|
+
const normalizedHeaders = lines.map((line) => line.replace(/^[^A-Za-z0-9]*/, ""));
|
|
267
|
+
const hasKindHeader = binding.approvalKind === "exec" ? lines.includes("Approval required.") || normalizedHeaders.some((line) => /^Exec approval required$/i.test(line)) : normalizedHeaders.some((line) => /^Plugin approval required$/i.test(line));
|
|
268
|
+
const hasId = lines.includes(`ID: ${binding.approvalId}`) || lines.includes(`Full id: \`${binding.approvalId}\``) || lines.includes(`Full id: ${binding.approvalId}`);
|
|
269
|
+
if (!hasKindHeader || !hasId) return false;
|
|
270
|
+
const visibleDecisions = [];
|
|
271
|
+
for (const line of lines) {
|
|
272
|
+
const match = line.match(APPROVE_COMMAND_LINE_RE);
|
|
273
|
+
const approvalId = match?.[1];
|
|
274
|
+
const decisionsText = match?.[2];
|
|
275
|
+
if (!approvalId || !decisionsText || approvalId !== binding.approvalId && approvalId !== binding.approvalSlug) continue;
|
|
276
|
+
for (const token of decisionsText.split(/[\s|,]+/)) {
|
|
277
|
+
const decision = normalizeApprovalReactionDecision(token);
|
|
278
|
+
if (decision && !visibleDecisions.includes(decision)) visibleDecisions.push(decision);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (!approvalReactionDecisionSetsMatch(binding.allowedDecisions, visibleDecisions)) return false;
|
|
282
|
+
if (!options.requireReactionHint) return true;
|
|
283
|
+
const hint = buildApprovalReactionHint({ allowedDecisions: binding.allowedDecisions });
|
|
284
|
+
return Boolean(hint && text.includes(hint));
|
|
285
|
+
}
|
|
286
|
+
/** Preserve a validated typed approval binding until the iMessage GUID is known. */
|
|
287
|
+
function addIMessageApprovalReactionHintToStructuredPayload(params) {
|
|
288
|
+
const metadata = readApprovalReactionPresentationBinding({
|
|
289
|
+
payload: params.payload,
|
|
290
|
+
requireApprovalSlug: true,
|
|
291
|
+
trimApprovalId: true
|
|
292
|
+
});
|
|
293
|
+
const text = params.payload.text;
|
|
294
|
+
if (metadata?.approvalKind !== params.approvalKind || !text) return null;
|
|
295
|
+
if (!visibleApprovalBindingMatches(text, metadata, { requireReactionHint: false })) {
|
|
296
|
+
reportApprovalBindingCorrelationMismatch(metadata);
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
...params.payload,
|
|
301
|
+
text: addApprovalReactionHintToText({
|
|
302
|
+
text,
|
|
303
|
+
allowedDecisions: metadata.allowedDecisions
|
|
304
|
+
}),
|
|
305
|
+
channelData: {
|
|
306
|
+
...params.payload.channelData,
|
|
307
|
+
[IMESSAGE_APPROVAL_DELIVERY_BINDING_KEY]: buildApprovalReactionDeliveredBindingMarker({
|
|
308
|
+
approvalId: metadata.approvalId,
|
|
309
|
+
approvalSlug: metadata.approvalSlug,
|
|
310
|
+
approvalKind: metadata.approvalKind,
|
|
311
|
+
allowedDecisions: metadata.allowedDecisions
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const APPROVE_COMMAND_LINE_RE = /\/approve(?:@[^\s]+)?\s+([A-Za-z0-9][A-Za-z0-9._:-]*)\s+(.+)$/i;
|
|
317
|
+
function registerIMessageApprovalReactionTarget(params) {
|
|
318
|
+
const accountId = params.accountId.trim();
|
|
319
|
+
const messageId = params.messageId.trim();
|
|
320
|
+
const approvalId = params.approvalId.trim();
|
|
321
|
+
const allowedDecisions = listApprovalReactionBindings({ allowedDecisions: params.allowedDecisions }).map((binding) => binding.decision);
|
|
322
|
+
if (!accountId || !messageId || !approvalId || params.approvalKind !== "exec" && params.approvalKind !== "plugin" || allowedDecisions.length === 0) return null;
|
|
323
|
+
const target = {
|
|
324
|
+
approvalId,
|
|
325
|
+
approvalKind: params.approvalKind,
|
|
326
|
+
allowedDecisions
|
|
327
|
+
};
|
|
328
|
+
const keys = enumerateApprovalTargetKeys({
|
|
329
|
+
accountId,
|
|
330
|
+
conversation: params.conversation,
|
|
331
|
+
messageId
|
|
332
|
+
});
|
|
333
|
+
if (keys.length === 0) return null;
|
|
334
|
+
const expiry = recordIMessageApprovalReactionPollTarget({
|
|
335
|
+
keys,
|
|
336
|
+
accountId,
|
|
337
|
+
conversation: params.conversation,
|
|
338
|
+
messageId,
|
|
339
|
+
approvalId,
|
|
340
|
+
approvalKind: params.approvalKind,
|
|
341
|
+
allowedDecisions,
|
|
342
|
+
ttlMs: params.ttlMs
|
|
343
|
+
});
|
|
344
|
+
if (!expiry) return null;
|
|
345
|
+
for (const key of keys) imessageApprovalReactionTargets.register(key, target, { ttlMs: expiry.ttlMs });
|
|
346
|
+
return target;
|
|
347
|
+
}
|
|
348
|
+
function listDeliveredIMessageApprovalGuids(params) {
|
|
349
|
+
const deliveries = [];
|
|
350
|
+
const seen = /* @__PURE__ */ new Set();
|
|
351
|
+
for (const result of params.results) {
|
|
352
|
+
if (result.channel !== "imessage") continue;
|
|
353
|
+
const guid = typeof result.meta?.imessageMessageGuid === "string" ? result.meta.imessageMessageGuid.trim() : "";
|
|
354
|
+
const visibleText = result.meta?.imessageVisibleText;
|
|
355
|
+
if (!guid || /^\d+$/.test(guid) || seen.has(guid) || typeof visibleText !== "string") continue;
|
|
356
|
+
seen.add(guid);
|
|
357
|
+
deliveries.push({
|
|
358
|
+
guid,
|
|
359
|
+
visibleText
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
if (!visibleApprovalBindingMatches(deliveries.map((delivery) => delivery.visibleText).join("\n"), params.binding, { requireReactionHint: true })) {
|
|
363
|
+
if (params.results.some((result) => result.channel === "imessage")) reportApprovalBindingCorrelationMismatch(params.binding);
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
return deliveries.map((delivery) => delivery.guid);
|
|
367
|
+
}
|
|
368
|
+
/** Bind a typed forwarded approval after iMessage returns the stable tapback GUID. */
|
|
369
|
+
function registerIMessageApprovalReactionTargetForDeliveredPayload(params) {
|
|
370
|
+
if (params.target.channel.trim().toLowerCase() !== "imessage") return false;
|
|
371
|
+
const binding = readApprovalReactionDeliveredBinding({
|
|
372
|
+
payload: params.payload,
|
|
373
|
+
channelDataKey: IMESSAGE_APPROVAL_DELIVERY_BINDING_KEY,
|
|
374
|
+
requireApprovalSlug: true,
|
|
375
|
+
trimApprovalId: true
|
|
376
|
+
});
|
|
377
|
+
if (!binding) return false;
|
|
378
|
+
const conversation = buildIMessageApprovalConversationKeyForTarget(params.target.to);
|
|
379
|
+
if (!conversation) return false;
|
|
380
|
+
let registered = false;
|
|
381
|
+
for (const messageId of listDeliveredIMessageApprovalGuids({
|
|
382
|
+
binding,
|
|
383
|
+
results: params.results
|
|
384
|
+
})) registered = Boolean(registerIMessageApprovalReactionTarget({
|
|
385
|
+
accountId: params.accountId,
|
|
386
|
+
conversation,
|
|
387
|
+
messageId,
|
|
388
|
+
approvalId: binding.approvalId,
|
|
389
|
+
approvalKind: binding.approvalKind,
|
|
390
|
+
allowedDecisions: binding.allowedDecisions,
|
|
391
|
+
ttlMs: params.ttlMs
|
|
392
|
+
})) || registered;
|
|
393
|
+
return registered;
|
|
394
|
+
}
|
|
395
|
+
function unregisterIMessageApprovalReactionTarget(params) {
|
|
396
|
+
const keys = enumerateApprovalTargetKeys(params);
|
|
397
|
+
for (const key of keys) imessageApprovalReactionTargets.delete(key);
|
|
398
|
+
deleteIMessageApprovalReactionPollTargets(keys);
|
|
399
|
+
}
|
|
400
|
+
function resolveTarget(params) {
|
|
401
|
+
const target = resolveTypedApprovalReactionTarget(params);
|
|
402
|
+
return target ? {
|
|
403
|
+
approvalId: target.approvalId,
|
|
404
|
+
approvalKind: target.approvalKind,
|
|
405
|
+
decision: target.decision
|
|
406
|
+
} : null;
|
|
407
|
+
}
|
|
408
|
+
function formatCanonicalApprovalTerminalState(approval) {
|
|
409
|
+
const decision = approval.status === "allowed" || approval.status === "denied" ? ` decision=${approval.decision}` : "";
|
|
410
|
+
return `status=${approval.status}${decision} reason=${approval.reason}`;
|
|
411
|
+
}
|
|
412
|
+
async function resolveIMessageApprovalReactionTargetWithPersistence(params) {
|
|
413
|
+
const keys = enumerateApprovalTargetKeys(params);
|
|
414
|
+
for (const key of keys) {
|
|
415
|
+
const target = resolveTarget({
|
|
416
|
+
target: await imessageApprovalReactionTargets.lookup(key),
|
|
417
|
+
reactionKey: params.reactionKey
|
|
418
|
+
});
|
|
419
|
+
if (target) return target;
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
function readApprovalReactionEvent(message, bodyText) {
|
|
424
|
+
const reaction = resolveIMessageReactionContext(message, bodyText);
|
|
425
|
+
if (!reaction) return null;
|
|
426
|
+
const reactionKey = reaction.emoji.trim();
|
|
427
|
+
const candidates = (reaction.targetGuids ?? []).map((value) => value.trim()).filter((value) => value.length > 0);
|
|
428
|
+
const primary = reaction.targetGuid?.trim() || candidates[0] || "";
|
|
429
|
+
const messageIdCandidates = candidates.length > 0 ? candidates : primary ? [primary] : [];
|
|
430
|
+
const actorHandle = normalizeIMessageHandle((message.sender ?? "").trim());
|
|
431
|
+
if (!reactionKey || !primary || !actorHandle) return null;
|
|
432
|
+
const conversation = buildIMessageApprovalConversationKeyForInbound({
|
|
433
|
+
chatGuid: message.chat_guid,
|
|
434
|
+
chatIdentifier: message.chat_identifier,
|
|
435
|
+
chatId: message.chat_id,
|
|
436
|
+
isGroup: message.is_group,
|
|
437
|
+
actorHandle
|
|
438
|
+
});
|
|
439
|
+
if (!normalizeConversationKey(conversation)) return null;
|
|
440
|
+
return {
|
|
441
|
+
conversation,
|
|
442
|
+
messageId: primary,
|
|
443
|
+
messageIdCandidates,
|
|
444
|
+
actorHandle,
|
|
445
|
+
reactionKey,
|
|
446
|
+
action: reaction.action
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
async function handleIMessageApprovalReaction(params) {
|
|
450
|
+
const event = readApprovalReactionEvent(params.message, params.bodyText);
|
|
451
|
+
if (!event) return {
|
|
452
|
+
handled: false,
|
|
453
|
+
stopPolling: false
|
|
454
|
+
};
|
|
455
|
+
if (event.action === "removed") return {
|
|
456
|
+
handled: false,
|
|
457
|
+
stopPolling: false
|
|
458
|
+
};
|
|
459
|
+
let target = null;
|
|
460
|
+
let matchedMessageId = null;
|
|
461
|
+
for (const candidate of event.messageIdCandidates) {
|
|
462
|
+
target = await resolveIMessageApprovalReactionTargetWithPersistence({
|
|
463
|
+
accountId: params.accountId,
|
|
464
|
+
conversation: event.conversation,
|
|
465
|
+
messageId: candidate,
|
|
466
|
+
reactionKey: event.reactionKey
|
|
467
|
+
});
|
|
468
|
+
if (target) {
|
|
469
|
+
matchedMessageId = candidate;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (!target) return {
|
|
474
|
+
handled: false,
|
|
475
|
+
stopPolling: false
|
|
476
|
+
};
|
|
477
|
+
if (getIMessageApprovalApprovers({
|
|
478
|
+
cfg: params.cfg,
|
|
479
|
+
accountId: params.accountId
|
|
480
|
+
}).length === 0) {
|
|
481
|
+
params.logVerboseMessage?.(`imessage: approval reaction denied id=${target.approvalId}; reactions require explicit approvers`);
|
|
482
|
+
return {
|
|
483
|
+
handled: true,
|
|
484
|
+
stopPolling: false
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
if (!imessageApprovalAuth.authorizeActorAction({
|
|
488
|
+
cfg: params.cfg,
|
|
489
|
+
accountId: params.accountId,
|
|
490
|
+
senderId: event.actorHandle,
|
|
491
|
+
action: "approve",
|
|
492
|
+
approvalKind: target.approvalKind
|
|
493
|
+
}).authorized) {
|
|
494
|
+
params.logVerboseMessage?.(`imessage: approval reaction denied id=${target.approvalId} sender=${event.actorHandle}`);
|
|
495
|
+
return {
|
|
496
|
+
handled: true,
|
|
497
|
+
stopPolling: false
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const resolveApprovalOverGateway = await loadResolveApprovalOverGateway();
|
|
501
|
+
try {
|
|
502
|
+
const result = await resolveApprovalOverGateway({
|
|
503
|
+
cfg: params.cfg,
|
|
504
|
+
approvalId: target.approvalId,
|
|
505
|
+
approvalKind: target.approvalKind,
|
|
506
|
+
decision: target.decision,
|
|
507
|
+
channel: "imessage",
|
|
508
|
+
accountId: params.accountId,
|
|
509
|
+
senderId: event.actorHandle,
|
|
510
|
+
gatewayUrl: params.gatewayUrl,
|
|
511
|
+
...params.gatewayRuntime ? { gatewayRuntime: params.gatewayRuntime } : {}
|
|
512
|
+
});
|
|
513
|
+
for (const candidate of event.messageIdCandidates) unregisterIMessageApprovalReactionTarget({
|
|
514
|
+
accountId: params.accountId,
|
|
515
|
+
conversation: event.conversation,
|
|
516
|
+
messageId: candidate
|
|
517
|
+
});
|
|
518
|
+
const outcome = result.applied ? "resolved" : "already resolved";
|
|
519
|
+
params.logVerboseMessage?.(`imessage: approval reaction ${outcome} id=${target.approvalId} sender=${event.actorHandle} ${formatCanonicalApprovalTerminalState(result.approval)} via messageId=${matchedMessageId ?? event.messageId}`);
|
|
520
|
+
return {
|
|
521
|
+
handled: true,
|
|
522
|
+
stopPolling: true,
|
|
523
|
+
stopPollingReason: "resolved"
|
|
524
|
+
};
|
|
525
|
+
} catch (error) {
|
|
526
|
+
if (isApprovalNotFoundError(error)) {
|
|
527
|
+
for (const candidate of event.messageIdCandidates) unregisterIMessageApprovalReactionTarget({
|
|
528
|
+
accountId: params.accountId,
|
|
529
|
+
conversation: event.conversation,
|
|
530
|
+
messageId: candidate
|
|
531
|
+
});
|
|
532
|
+
params.logVerboseMessage?.(`imessage: approval reaction ignored for expired approval id=${target.approvalId} sender=${event.actorHandle}`);
|
|
533
|
+
return {
|
|
534
|
+
handled: true,
|
|
535
|
+
stopPolling: true,
|
|
536
|
+
stopPollingReason: "not-found"
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
try {
|
|
540
|
+
getOptionalIMessageRuntime()?.logging.getChildLogger({
|
|
541
|
+
plugin: "imessage",
|
|
542
|
+
feature: "approval-reactions"
|
|
543
|
+
}).warn("approval reaction failed", {
|
|
544
|
+
approvalId: target.approvalId,
|
|
545
|
+
senderId: event.actorHandle,
|
|
546
|
+
error: String(error)
|
|
547
|
+
});
|
|
548
|
+
} catch {}
|
|
549
|
+
params.logVerboseMessage?.(`imessage: approval reaction failed id=${target.approvalId} sender=${event.actorHandle}: ${String(error)}`);
|
|
550
|
+
throw error;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function maybeResolveIMessageApprovalReaction(params) {
|
|
554
|
+
return (await handleIMessageApprovalReaction(params)).handled;
|
|
555
|
+
}
|
|
556
|
+
function clearIMessageApprovalReactionTargetsForTest() {
|
|
557
|
+
imessageApprovalReactionTargets.clearForTest();
|
|
558
|
+
clearIMessageApprovalReactionPollTargetsForTest();
|
|
559
|
+
loadResolveApprovalOverGateway.clear();
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
562
|
+
export { unregisterIMessageApprovalReactionTarget as a, buildIMessageApprovalConversationKeyForTarget as c, normalizeConversationKey as d, normalizeIMessageGuid as f, registerIMessageApprovalReactionTarget as i, enumerateApprovalTargetKeys as l, handleIMessageApprovalReaction as n, listPendingIMessageApprovalReactionPollTargets as o, maybeResolveIMessageApprovalReaction as r, buildIMessageApprovalConversationKeyForInbound as s, approval_reactions_exports as t, enumerateConversationKeyForms as u };
|