@openclaw/line 2026.7.2-beta.1 → 2026.7.2-beta.3
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-DJVOv1JI.js → accounts-BUBOoW5Q.js} +95 -33
- package/dist/api.js +2 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-CnPxxRbJ.js → channel-uT5RTtpi.js} +65 -76
- package/dist/channel.runtime-BqNglqnr.js +4 -0
- package/dist/contract-api.js +1 -1
- package/dist/{markdown-to-line-CixmAKiG.js → markdown-to-line-D1vapcdP.js} +14 -5
- package/dist/{monitor-q3UE2J1g.js → monitor-Bk-lpoOZ.js} +522 -253
- package/dist/monitor.runtime-CHlqxGVL.js +2 -0
- package/dist/{outbound.runtime-CI-t7Z8P.js → outbound.runtime-ByZ0Dsvu.js} +1 -1
- package/dist/{reply-payload-transform-BsbwCJGH.js → reply-payload-transform-r9sa-TYT.js} +61 -50
- package/dist/runtime-api.js +7 -22
- package/dist/setup-api.js +1 -1
- package/dist/{setup-surface-Bc36YSS3.js → setup-surface-BEt4mazl.js} +38 -45
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +57 -57
- package/package.json +4 -4
- package/dist/channel.runtime-FPcRtjcT.js +0 -4
- package/dist/monitor.runtime-BiNrVz5G.js +0 -2
|
@@ -1,55 +1,113 @@
|
|
|
1
1
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId, normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
|
|
2
2
|
import { resolveAccountEntry } from "openclaw/plugin-sdk/account-resolution";
|
|
3
|
-
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/
|
|
3
|
+
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
|
|
4
4
|
//#region extensions/line/src/accounts.ts
|
|
5
|
-
function
|
|
6
|
-
return tryReadSecretFileSync(filePath, "LINE credential file", { rejectSymlink: true });
|
|
5
|
+
function readCredentialFile(filePath, configPath) {
|
|
6
|
+
return tryReadSecretFileSync(filePath, "LINE credential file", { rejectSymlink: true }, { configPath });
|
|
7
7
|
}
|
|
8
8
|
function resolveToken(params) {
|
|
9
9
|
const { accountId, baseConfig, accountConfig } = params;
|
|
10
10
|
if (accountConfig?.channelAccessToken?.trim()) return {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const accountFileToken = readFileIfExists(accountConfig?.tokenFile);
|
|
15
|
-
if (accountFileToken) return {
|
|
16
|
-
token: accountFileToken,
|
|
17
|
-
tokenSource: "file"
|
|
11
|
+
value: accountConfig.channelAccessToken.trim(),
|
|
12
|
+
source: "config",
|
|
13
|
+
status: "available"
|
|
18
14
|
};
|
|
15
|
+
if (accountConfig?.tokenFile?.trim()) {
|
|
16
|
+
const result = readCredentialFile(accountConfig.tokenFile, `channels.line.accounts.${accountId}.tokenFile`);
|
|
17
|
+
return result.status === "available" ? {
|
|
18
|
+
value: result.value,
|
|
19
|
+
source: "file",
|
|
20
|
+
status: "available"
|
|
21
|
+
} : {
|
|
22
|
+
value: "",
|
|
23
|
+
source: "file",
|
|
24
|
+
status: "configured_unavailable",
|
|
25
|
+
diagnostic: result.diagnostic
|
|
26
|
+
};
|
|
27
|
+
}
|
|
19
28
|
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
20
29
|
if (baseConfig?.channelAccessToken?.trim()) return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const baseFileToken = readFileIfExists(baseConfig?.tokenFile);
|
|
25
|
-
if (baseFileToken) return {
|
|
26
|
-
token: baseFileToken,
|
|
27
|
-
tokenSource: "file"
|
|
30
|
+
value: baseConfig.channelAccessToken.trim(),
|
|
31
|
+
source: "config",
|
|
32
|
+
status: "available"
|
|
28
33
|
};
|
|
34
|
+
if (baseConfig?.tokenFile?.trim()) {
|
|
35
|
+
const result = readCredentialFile(baseConfig.tokenFile, "channels.line.tokenFile");
|
|
36
|
+
return result.status === "available" ? {
|
|
37
|
+
value: result.value,
|
|
38
|
+
source: "file",
|
|
39
|
+
status: "available"
|
|
40
|
+
} : {
|
|
41
|
+
value: "",
|
|
42
|
+
source: "file",
|
|
43
|
+
status: "configured_unavailable",
|
|
44
|
+
diagnostic: result.diagnostic
|
|
45
|
+
};
|
|
46
|
+
}
|
|
29
47
|
const envToken = process.env.LINE_CHANNEL_ACCESS_TOKEN?.trim();
|
|
30
48
|
if (envToken) return {
|
|
31
|
-
|
|
32
|
-
|
|
49
|
+
value: envToken,
|
|
50
|
+
source: "env",
|
|
51
|
+
status: "available"
|
|
33
52
|
};
|
|
34
53
|
}
|
|
35
54
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
value: "",
|
|
56
|
+
source: "none",
|
|
57
|
+
status: "missing"
|
|
38
58
|
};
|
|
39
59
|
}
|
|
40
60
|
function resolveSecret(params) {
|
|
41
61
|
const { accountId, baseConfig, accountConfig } = params;
|
|
42
|
-
if (accountConfig?.channelSecret?.trim()) return
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
if (accountConfig?.channelSecret?.trim()) return {
|
|
63
|
+
value: accountConfig.channelSecret.trim(),
|
|
64
|
+
source: "config",
|
|
65
|
+
status: "available"
|
|
66
|
+
};
|
|
67
|
+
if (accountConfig?.secretFile?.trim()) {
|
|
68
|
+
const result = readCredentialFile(accountConfig.secretFile, `channels.line.accounts.${accountId}.secretFile`);
|
|
69
|
+
return result.status === "available" ? {
|
|
70
|
+
value: result.value,
|
|
71
|
+
source: "file",
|
|
72
|
+
status: "available"
|
|
73
|
+
} : {
|
|
74
|
+
value: "",
|
|
75
|
+
source: "file",
|
|
76
|
+
status: "configured_unavailable",
|
|
77
|
+
diagnostic: result.diagnostic
|
|
78
|
+
};
|
|
79
|
+
}
|
|
45
80
|
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
46
|
-
if (baseConfig?.channelSecret?.trim()) return
|
|
47
|
-
|
|
48
|
-
|
|
81
|
+
if (baseConfig?.channelSecret?.trim()) return {
|
|
82
|
+
value: baseConfig.channelSecret.trim(),
|
|
83
|
+
source: "config",
|
|
84
|
+
status: "available"
|
|
85
|
+
};
|
|
86
|
+
if (baseConfig?.secretFile?.trim()) {
|
|
87
|
+
const result = readCredentialFile(baseConfig.secretFile, "channels.line.secretFile");
|
|
88
|
+
return result.status === "available" ? {
|
|
89
|
+
value: result.value,
|
|
90
|
+
source: "file",
|
|
91
|
+
status: "available"
|
|
92
|
+
} : {
|
|
93
|
+
value: "",
|
|
94
|
+
source: "file",
|
|
95
|
+
status: "configured_unavailable",
|
|
96
|
+
diagnostic: result.diagnostic
|
|
97
|
+
};
|
|
98
|
+
}
|
|
49
99
|
const envSecret = process.env.LINE_CHANNEL_SECRET?.trim();
|
|
50
|
-
if (envSecret) return
|
|
100
|
+
if (envSecret) return {
|
|
101
|
+
value: envSecret,
|
|
102
|
+
source: "env",
|
|
103
|
+
status: "available"
|
|
104
|
+
};
|
|
51
105
|
}
|
|
52
|
-
return
|
|
106
|
+
return {
|
|
107
|
+
value: "",
|
|
108
|
+
source: "none",
|
|
109
|
+
status: "missing"
|
|
110
|
+
};
|
|
53
111
|
}
|
|
54
112
|
function resolveLineAccount(params) {
|
|
55
113
|
const cfg = params.cfg;
|
|
@@ -57,7 +115,7 @@ function resolveLineAccount(params) {
|
|
|
57
115
|
const lineConfig = cfg.channels?.line;
|
|
58
116
|
const accounts = lineConfig?.accounts;
|
|
59
117
|
const accountConfig = resolveAccountEntry(accounts, accountId);
|
|
60
|
-
const
|
|
118
|
+
const token = resolveToken({
|
|
61
119
|
accountId,
|
|
62
120
|
baseConfig: lineConfig,
|
|
63
121
|
accountConfig
|
|
@@ -79,9 +137,13 @@ function resolveLineAccount(params) {
|
|
|
79
137
|
accountId,
|
|
80
138
|
name: accountConfig?.name ?? (accountId === DEFAULT_ACCOUNT_ID ? lineConfig?.name : void 0),
|
|
81
139
|
enabled,
|
|
82
|
-
channelAccessToken: token,
|
|
83
|
-
channelSecret: secret,
|
|
84
|
-
tokenSource,
|
|
140
|
+
channelAccessToken: token.value,
|
|
141
|
+
channelSecret: secret.value,
|
|
142
|
+
tokenSource: token.source,
|
|
143
|
+
signingSecretSource: secret.source,
|
|
144
|
+
tokenStatus: token.status,
|
|
145
|
+
signingSecretStatus: secret.status,
|
|
146
|
+
...[token.diagnostic, secret.diagnostic].some(Boolean) ? { credentialDiagnostics: [token.diagnostic, secret.diagnostic].filter((diagnostic) => Boolean(diagnostic)) } : {},
|
|
85
147
|
config: mergedConfig
|
|
86
148
|
};
|
|
87
149
|
}
|
package/dist/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-
|
|
2
|
-
import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-
|
|
1
|
+
import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-uT5RTtpi.js";
|
|
2
|
+
import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-BEt4mazl.js";
|
|
3
3
|
//#region extensions/line/src/channel.setup.ts
|
|
4
4
|
const lineSetupPlugin = {
|
|
5
5
|
id: "line",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as linePlugin } from "./channel-
|
|
1
|
+
import { t as linePlugin } from "./channel-uT5RTtpi.js";
|
|
2
2
|
export { linePlugin };
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-
|
|
2
|
-
import { n as lineSetupAdapter, r as hasLineCredentials, t as lineSetupWizard } from "./setup-surface-
|
|
3
|
-
import { a as
|
|
1
|
+
import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BUBOoW5Q.js";
|
|
2
|
+
import { n as lineSetupAdapter, r as hasLineCredentials, t as lineSetupWizard } from "./setup-surface-BEt4mazl.js";
|
|
3
|
+
import { a as buildLineMediaMessage, d as LineChannelConfigSchema, i as buildLineQuickReplyFallbackText, l as getLineRuntime, n as parseLineDirectives, o as hasLineSpecificMediaOptions, p as resolveExactLineGroupConfigKey, r as createLineSendReceipt, s as resolveLineOutboundMedia, t as hasLineDirectives } from "./reply-payload-transform-r9sa-TYT.js";
|
|
4
4
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
5
|
+
import { buildDmGroupAccountAllowlistAdapter, createFlatAllowlistOverrideResolver } from "openclaw/plugin-sdk/allowlist-config-edit";
|
|
5
6
|
import { buildChannelOutboundSessionRoute, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
6
7
|
import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
|
|
7
8
|
import { buildChannelGroupsScopeTree, createRestrictSendersChannelSecurity, resolveScopeRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
8
9
|
import { createEmptyChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
|
|
9
10
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/account-id";
|
|
10
|
-
import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
|
|
11
11
|
import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
12
12
|
import { createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
13
13
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
14
|
+
import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
|
|
14
15
|
import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
|
|
15
16
|
import { createAttachedChannelResultAdapter, createEmptyChannelResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
16
17
|
import { resolveOutboundMediaUrls } from "openclaw/plugin-sdk/reply-payload";
|
|
18
|
+
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
17
19
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
18
20
|
import { buildTokenChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState, createDependentCredentialStatusIssueCollector } from "openclaw/plugin-sdk/status-helpers";
|
|
19
21
|
//#region extensions/line/src/bindings.ts
|
|
@@ -58,6 +60,22 @@ const lineBindingsAdapter = {
|
|
|
58
60
|
function normalizeLineAllowFrom(entry) {
|
|
59
61
|
return entry.replace(/^line:(?:user:)?/i, "");
|
|
60
62
|
}
|
|
63
|
+
const lineConfigAdapter = createScopedChannelConfigAdapter({
|
|
64
|
+
sectionKey: "line",
|
|
65
|
+
listAccountIds: listLineAccountIds,
|
|
66
|
+
resolveAccount: (cfg, accountId) => resolveLineAccount({
|
|
67
|
+
cfg,
|
|
68
|
+
accountId: accountId ?? void 0
|
|
69
|
+
}),
|
|
70
|
+
defaultAccountId: resolveDefaultLineAccountId,
|
|
71
|
+
clearBaseFields: [
|
|
72
|
+
"channelSecret",
|
|
73
|
+
"tokenFile",
|
|
74
|
+
"secretFile"
|
|
75
|
+
],
|
|
76
|
+
resolveAllowFrom: (account) => account.config.allowFrom,
|
|
77
|
+
formatAllowFrom: (allowFrom) => normalizeStringEntries(allowFrom).map(normalizeLineAllowFrom)
|
|
78
|
+
});
|
|
61
79
|
const lineChannelPluginCommon = {
|
|
62
80
|
meta: {
|
|
63
81
|
id: "line",
|
|
@@ -81,34 +99,24 @@ const lineChannelPluginCommon = {
|
|
|
81
99
|
reload: { configPrefixes: ["channels.line"] },
|
|
82
100
|
configSchema: LineChannelConfigSchema,
|
|
83
101
|
config: {
|
|
84
|
-
...
|
|
85
|
-
sectionKey: "line",
|
|
86
|
-
listAccountIds: listLineAccountIds,
|
|
87
|
-
resolveAccount: (cfg, accountId) => resolveLineAccount({
|
|
88
|
-
cfg,
|
|
89
|
-
accountId: accountId ?? void 0
|
|
90
|
-
}),
|
|
91
|
-
defaultAccountId: resolveDefaultLineAccountId,
|
|
92
|
-
clearBaseFields: [
|
|
93
|
-
"channelSecret",
|
|
94
|
-
"tokenFile",
|
|
95
|
-
"secretFile"
|
|
96
|
-
],
|
|
97
|
-
resolveAllowFrom: (account) => account.config.allowFrom,
|
|
98
|
-
formatAllowFrom: (allowFrom) => normalizeStringEntries(allowFrom).map(normalizeLineAllowFrom)
|
|
99
|
-
}),
|
|
102
|
+
...lineConfigAdapter,
|
|
100
103
|
isConfigured: (account) => hasLineCredentials(account),
|
|
101
104
|
describeAccount: (account) => describeWebhookAccountSnapshot({
|
|
102
105
|
account,
|
|
103
106
|
configured: hasLineCredentials(account),
|
|
104
|
-
extra: {
|
|
107
|
+
extra: {
|
|
108
|
+
tokenSource: account.tokenSource ?? void 0,
|
|
109
|
+
signingSecretSource: account.signingSecretSource ?? void 0,
|
|
110
|
+
tokenStatus: account.tokenStatus,
|
|
111
|
+
signingSecretStatus: account.signingSecretStatus
|
|
112
|
+
}
|
|
105
113
|
})
|
|
106
114
|
}
|
|
107
115
|
};
|
|
108
116
|
//#endregion
|
|
109
117
|
//#region extensions/line/src/gateway.ts
|
|
110
118
|
const loadLineProbeRuntime$1 = createLazyRuntimeModule(() => import("./probe.runtime-CRhVGqwl.js"));
|
|
111
|
-
const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-
|
|
119
|
+
const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-CHlqxGVL.js"));
|
|
112
120
|
const lineGatewayAdapter = {
|
|
113
121
|
startAccount: async (ctx) => {
|
|
114
122
|
const account = ctx.account;
|
|
@@ -223,42 +231,12 @@ function inferLineTargetChatType(target) {
|
|
|
223
231
|
}
|
|
224
232
|
//#endregion
|
|
225
233
|
//#region extensions/line/src/outbound.ts
|
|
226
|
-
const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-
|
|
227
|
-
function isLineUserTarget(target) {
|
|
228
|
-
const normalized = target.trim().replace(/^line:(group|room|user):/i, "").replace(/^line:/i, "");
|
|
229
|
-
return /^U/i.test(normalized);
|
|
230
|
-
}
|
|
231
|
-
function hasLineSpecificMediaOptions(lineData) {
|
|
232
|
-
return Boolean(lineData.mediaKind ?? lineData.previewImageUrl?.trim() ?? (typeof lineData.durationMs === "number" ? lineData.durationMs : void 0) ?? lineData.trackingId?.trim());
|
|
233
|
-
}
|
|
234
|
-
function buildLineMediaMessageObject(resolved, opts) {
|
|
235
|
-
switch (resolved.mediaKind) {
|
|
236
|
-
case "video": {
|
|
237
|
-
const previewImageUrl = resolved.previewImageUrl?.trim();
|
|
238
|
-
if (!previewImageUrl) throw new Error("LINE video messages require previewImageUrl to reference an image URL");
|
|
239
|
-
return {
|
|
240
|
-
type: "video",
|
|
241
|
-
originalContentUrl: resolved.mediaUrl,
|
|
242
|
-
previewImageUrl,
|
|
243
|
-
...opts?.allowTrackingId && resolved.trackingId ? { trackingId: resolved.trackingId } : {}
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
case "audio": return {
|
|
247
|
-
type: "audio",
|
|
248
|
-
originalContentUrl: resolved.mediaUrl,
|
|
249
|
-
duration: resolved.durationMs ?? 6e4
|
|
250
|
-
};
|
|
251
|
-
default: return {
|
|
252
|
-
type: "image",
|
|
253
|
-
originalContentUrl: resolved.mediaUrl,
|
|
254
|
-
previewImageUrl: resolved.previewImageUrl ?? resolved.mediaUrl
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
}
|
|
234
|
+
const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-ByZ0Dsvu.js"));
|
|
258
235
|
const lineOutboundAdapter = {
|
|
259
236
|
deliveryMode: "direct",
|
|
260
237
|
chunker: (text, limit) => getLineRuntime().channel.text.chunkMarkdownText(text, limit),
|
|
261
238
|
textChunkLimit: 5e3,
|
|
239
|
+
sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text),
|
|
262
240
|
sendPayload: async ({ to, payload, accountId, cfg, onDeliveryResult }) => {
|
|
263
241
|
const runtime = getLineRuntime();
|
|
264
242
|
const outboundRuntime = await loadLineOutboundRuntime();
|
|
@@ -300,6 +278,12 @@ const lineOutboundAdapter = {
|
|
|
300
278
|
const chunks = processed.text ? runtime.channel.text.chunkMarkdownText(processed.text, chunkLimit) : [];
|
|
301
279
|
const mediaUrls = resolveOutboundMediaUrls(payload);
|
|
302
280
|
const useLineSpecificMedia = hasLineSpecificMediaOptions(lineData);
|
|
281
|
+
const mediaOptions = {
|
|
282
|
+
mediaKind: useLineSpecificMedia ? lineData.mediaKind : "image",
|
|
283
|
+
previewImageUrl: lineData.previewImageUrl,
|
|
284
|
+
durationMs: lineData.durationMs,
|
|
285
|
+
trackingId: lineData.trackingId
|
|
286
|
+
};
|
|
303
287
|
const shouldSendQuickRepliesInline = chunks.length === 0 && hasQuickReplies;
|
|
304
288
|
const sendMediaMessages = async () => {
|
|
305
289
|
for (const url of mediaUrls) {
|
|
@@ -314,12 +298,7 @@ const lineOutboundAdapter = {
|
|
|
314
298
|
}));
|
|
315
299
|
continue;
|
|
316
300
|
}
|
|
317
|
-
const resolved = await resolveLineOutboundMedia(trimmed,
|
|
318
|
-
mediaKind: lineData.mediaKind,
|
|
319
|
-
previewImageUrl: lineData.previewImageUrl,
|
|
320
|
-
durationMs: lineData.durationMs,
|
|
321
|
-
trackingId: lineData.trackingId
|
|
322
|
-
});
|
|
301
|
+
const resolved = await resolveLineOutboundMedia(trimmed, mediaOptions);
|
|
323
302
|
await recordResult((lineRuntime?.sendMessageLine ?? outboundRuntime.sendMessageLine)(to, "", {
|
|
324
303
|
verbose: false,
|
|
325
304
|
mediaUrl: resolved.mediaUrl,
|
|
@@ -401,21 +380,7 @@ const lineOutboundAdapter = {
|
|
|
401
380
|
for (const url of mediaUrls) {
|
|
402
381
|
const trimmed = url?.trim();
|
|
403
382
|
if (!trimmed) continue;
|
|
404
|
-
|
|
405
|
-
quickReplyMessages.push({
|
|
406
|
-
type: "image",
|
|
407
|
-
originalContentUrl: trimmed,
|
|
408
|
-
previewImageUrl: trimmed
|
|
409
|
-
});
|
|
410
|
-
continue;
|
|
411
|
-
}
|
|
412
|
-
const resolved = await resolveLineOutboundMedia(trimmed, {
|
|
413
|
-
mediaKind: lineData.mediaKind,
|
|
414
|
-
previewImageUrl: lineData.previewImageUrl,
|
|
415
|
-
durationMs: lineData.durationMs,
|
|
416
|
-
trackingId: lineData.trackingId
|
|
417
|
-
});
|
|
418
|
-
quickReplyMessages.push(buildLineMediaMessageObject(resolved, { allowTrackingId: isLineUserTarget(to) }));
|
|
383
|
+
quickReplyMessages.push(await buildLineMediaMessage(trimmed, mediaOptions, to));
|
|
419
384
|
}
|
|
420
385
|
if (quickReplyMessages.length > 0 && quickReply) {
|
|
421
386
|
const lastIndex = quickReplyMessages.length - 1;
|
|
@@ -554,13 +519,16 @@ const lineStatusAdapter = createComputedAccountStatusAdapter({
|
|
|
554
519
|
configured: hasLineCredentials(account),
|
|
555
520
|
extra: {
|
|
556
521
|
tokenSource: account.tokenSource,
|
|
522
|
+
signingSecretSource: account.signingSecretSource,
|
|
523
|
+
tokenStatus: account.tokenStatus,
|
|
524
|
+
signingSecretStatus: account.signingSecretStatus,
|
|
557
525
|
mode: "webhook"
|
|
558
526
|
}
|
|
559
527
|
})
|
|
560
528
|
});
|
|
561
529
|
//#endregion
|
|
562
530
|
//#region extensions/line/src/channel.ts
|
|
563
|
-
const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-
|
|
531
|
+
const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-BqNglqnr.js"));
|
|
564
532
|
const lineSecurityAdapter = createRestrictSendersChannelSecurity({
|
|
565
533
|
channelKey: "line",
|
|
566
534
|
resolveDmPolicy: (account) => account.config.dmPolicy,
|
|
@@ -581,6 +549,27 @@ const linePlugin = createChatChannelPlugin({
|
|
|
581
549
|
...lineChannelPluginCommon,
|
|
582
550
|
setupWizard: lineSetupWizard,
|
|
583
551
|
groups: { resolveRequireMention: resolveLineGroupRequireMention },
|
|
552
|
+
allowlist: buildDmGroupAccountAllowlistAdapter({
|
|
553
|
+
channelId: "line",
|
|
554
|
+
resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
|
|
555
|
+
cfg,
|
|
556
|
+
accountId: accountId ?? void 0
|
|
557
|
+
}),
|
|
558
|
+
normalize: ({ cfg, accountId, values }) => lineConfigAdapter.formatAllowFrom({
|
|
559
|
+
cfg,
|
|
560
|
+
accountId,
|
|
561
|
+
allowFrom: values
|
|
562
|
+
}),
|
|
563
|
+
resolveDmAllowFrom: (account) => account.config.allowFrom,
|
|
564
|
+
resolveGroupAllowFrom: (account) => account.config.groupAllowFrom,
|
|
565
|
+
resolveDmPolicy: (account) => account.config.dmPolicy,
|
|
566
|
+
resolveGroupPolicy: (account) => account.config.groupPolicy,
|
|
567
|
+
resolveGroupOverrides: createFlatAllowlistOverrideResolver({
|
|
568
|
+
resolveRecord: (account) => account.config.groups,
|
|
569
|
+
label: (groupId) => groupId,
|
|
570
|
+
resolveEntries: (groupCfg) => groupCfg?.allowFrom
|
|
571
|
+
})
|
|
572
|
+
}),
|
|
584
573
|
messaging: {
|
|
585
574
|
targetPrefixes: ["line"],
|
|
586
575
|
normalizeTarget: normalizeLineMessagingTarget,
|
package/dist/contract-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-
|
|
1
|
+
import { i as resolveLineAccount, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BUBOoW5Q.js";
|
|
2
2
|
export { listLineAccountIds, resolveDefaultLineAccountId, resolveLineAccount };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { i as resolveLineAccount } from "./accounts-
|
|
2
|
-
import {
|
|
1
|
+
import { i as resolveLineAccount } from "./accounts-BUBOoW5Q.js";
|
|
2
|
+
import { c as validateLineMediaUrl, r as createLineSendReceipt } from "./reply-payload-transform-r9sa-TYT.js";
|
|
3
3
|
import { c as uriAction, d as createReceiptCard, o as messageAction, s as postbackAction, t as toFlexMessage } from "./flex-templates-K1lS9i8L.js";
|
|
4
|
+
import { stripMarkdown, stripMarkdown as stripMarkdown$1 } from "openclaw/plugin-sdk/text-chunking";
|
|
4
5
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
6
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
6
|
-
import { messagingApi } from "@line/bot-sdk";
|
|
7
7
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
8
|
+
import { messagingApi } from "@line/bot-sdk";
|
|
8
9
|
import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
|
|
10
|
+
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
9
11
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
10
|
-
import { stripMarkdown, stripMarkdown as stripMarkdown$1 } from "openclaw/plugin-sdk/text-chunking";
|
|
11
12
|
//#region extensions/line/src/template-messages.ts
|
|
12
13
|
const COMPACT_TEMPLATE_TEXT_LIMIT = 60;
|
|
13
14
|
const graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -221,6 +222,14 @@ function resolveLineChannelAccessToken(explicit, params) {
|
|
|
221
222
|
//#region extensions/line/src/send.ts
|
|
222
223
|
const userProfileCache = /* @__PURE__ */ new Map();
|
|
223
224
|
const PROFILE_CACHE_TTL_MS = 300 * 1e3;
|
|
225
|
+
const PROFILE_CACHE_MAX_ENTRIES = 1e3;
|
|
226
|
+
function cacheUserProfile(userId, profile) {
|
|
227
|
+
userProfileCache.delete(userId);
|
|
228
|
+
userProfileCache.set(userId, profile);
|
|
229
|
+
if (userProfileCache.size <= PROFILE_CACHE_MAX_ENTRIES) return;
|
|
230
|
+
for (const [key, cached] of userProfileCache) if (profile.fetchedAt - cached.fetchedAt >= PROFILE_CACHE_TTL_MS) userProfileCache.delete(key);
|
|
231
|
+
pruneMapToMaxSize(userProfileCache, PROFILE_CACHE_MAX_ENTRIES);
|
|
232
|
+
}
|
|
224
233
|
function normalizeTarget(to) {
|
|
225
234
|
const trimmed = to.trim();
|
|
226
235
|
if (!trimmed) throw new Error("Recipient is required for LINE sends");
|
|
@@ -469,7 +478,7 @@ async function getUserProfile(userId, opts) {
|
|
|
469
478
|
displayName: profile.displayName,
|
|
470
479
|
pictureUrl: profile.pictureUrl
|
|
471
480
|
};
|
|
472
|
-
|
|
481
|
+
cacheUserProfile(userId, {
|
|
473
482
|
...result,
|
|
474
483
|
fetchedAt: Date.now()
|
|
475
484
|
});
|