@openclaw/line 2026.7.1 → 2026.7.2-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +2 -2
- package/dist/{card-command--jtkAqp8.js → card-command-DQ-epsgt.js} +7 -3
- package/dist/{channel-C_8hLniz.js → channel-BHR-GoJ0.js} +63 -84
- package/dist/channel-plugin-api.js +1 -1
- package/dist/channel.runtime-DFgZ_Xwn.js +4 -0
- package/dist/{flex-templates-DEIXn69v.js → flex-templates-K1lS9i8L.js} +2 -3
- package/dist/index.js +1 -1
- package/dist/{markdown-to-line-DmpZY78n.js → markdown-to-line-XceqeKRP.js} +20 -20
- package/dist/{monitor-0eXlx_Pe.js → monitor-Db2rZsSX.js} +283 -228
- package/dist/monitor.runtime-CZuQgsEE.js +2 -0
- package/dist/{outbound.runtime-BwC7Y2U9.js → outbound.runtime-DnpU0Cms.js} +1 -1
- package/dist/{reply-payload-transform-C7r5npxP.js → reply-payload-transform-r9sa-TYT.js} +121 -84
- package/dist/runtime-api.js +8 -34
- package/dist/setup-api.js +1 -1
- package/dist/{setup-surface-Bc36YSS3.js → setup-surface-B7W6pwn3.js} +36 -44
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +57 -57
- package/package.json +4 -4
- package/dist/channel.runtime-Bh_AQM0k.js +0 -4
- package/dist/monitor.runtime-BGIpxzfB.js +0 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, D as sendMessageLine, S as pushMessageLine, T as pushTextMessageWithQuickReplies, c as processLineMessage, m as createQuickReplyItems, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage } from "./markdown-to-line-
|
|
1
|
+
import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, D as sendMessageLine, S as pushMessageLine, T as pushTextMessageWithQuickReplies, c as processLineMessage, m as createQuickReplyItems, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage } from "./markdown-to-line-XceqeKRP.js";
|
|
2
2
|
export { buildTemplateMessageFromPayload, createQuickReplyItems, processLineMessage, pushFlexMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, sendMessageLine };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { i as createMediaPlayerCard, l as createAgendaCard, n as createAppleTvRemoteCard, r as createDeviceControlCard, u as createEventCard } from "./flex-templates-
|
|
1
|
+
import { i as createMediaPlayerCard, l as createAgendaCard, n as createAppleTvRemoteCard, r as createDeviceControlCard, u as createEventCard } from "./flex-templates-K1lS9i8L.js";
|
|
2
2
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
3
3
|
import { resolveAccountEntry } from "openclaw/plugin-sdk/account-resolution";
|
|
4
4
|
import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
-
import { buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
5
|
+
import { DmPolicySchema, GroupPolicySchema, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
6
6
|
import { requireChannelOpenAllowFrom } from "openclaw/plugin-sdk/extension-shared";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
9
9
|
import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
10
|
import { resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
11
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
11
12
|
import { parseStrictFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
|
|
12
13
|
//#region extensions/line/src/group-keys.ts
|
|
13
14
|
function resolveLineGroupLookupIds(groupId) {
|
|
@@ -42,23 +43,12 @@ function resolveLineGroupsConfig(cfg, accountId) {
|
|
|
42
43
|
return resolveAccountEntry(lineConfig.accounts, normalizedAccountId)?.groups ?? lineConfig.groups;
|
|
43
44
|
}
|
|
44
45
|
function resolveExactLineGroupConfigKey(params) {
|
|
45
|
-
const groups =
|
|
46
|
+
const { groups } = params;
|
|
46
47
|
if (!groups) return;
|
|
47
48
|
return resolveLineGroupLookupIds(params.groupId).find((candidate) => Object.hasOwn(groups, candidate));
|
|
48
49
|
}
|
|
49
50
|
//#endregion
|
|
50
51
|
//#region extensions/line/src/config-schema.ts
|
|
51
|
-
const DmPolicySchema = z.enum([
|
|
52
|
-
"open",
|
|
53
|
-
"allowlist",
|
|
54
|
-
"pairing",
|
|
55
|
-
"disabled"
|
|
56
|
-
]);
|
|
57
|
-
const GroupPolicySchema = z.enum([
|
|
58
|
-
"open",
|
|
59
|
-
"allowlist",
|
|
60
|
-
"disabled"
|
|
61
|
-
]);
|
|
62
52
|
const ThreadBindingsSchema = z.object({
|
|
63
53
|
enabled: z.boolean().optional(),
|
|
64
54
|
idleHours: z.number().optional(),
|
|
@@ -84,39 +74,26 @@ const LineCommonConfigSchemaBase = z.object({
|
|
|
84
74
|
webhookPath: z.string().optional(),
|
|
85
75
|
threadBindings: ThreadBindingsSchema.optional()
|
|
86
76
|
});
|
|
87
|
-
const LineGroupConfigSchema =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
requireMention: z.boolean().optional(),
|
|
91
|
-
systemPrompt: z.string().optional(),
|
|
92
|
-
skills: z.array(z.string()).optional()
|
|
93
|
-
}).strict();
|
|
94
|
-
const LineAccountConfigSchema = LineCommonConfigSchemaBase.extend({ groups: z.record(z.string(), LineGroupConfigSchema.optional()).optional() }).strict().superRefine((value, ctx) => {
|
|
95
|
-
requireChannelOpenAllowFrom({
|
|
96
|
-
channel: "line",
|
|
97
|
-
policy: value.dmPolicy,
|
|
98
|
-
allowFrom: value.allowFrom,
|
|
99
|
-
ctx,
|
|
100
|
-
requireOpenAllowFrom
|
|
101
|
-
});
|
|
77
|
+
const LineGroupConfigSchema = buildGroupEntrySchema().omit({
|
|
78
|
+
tools: true,
|
|
79
|
+
toolsBySender: true
|
|
102
80
|
});
|
|
103
|
-
const LineConfigSchema = LineCommonConfigSchemaBase.extend({
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
81
|
+
const LineConfigSchema = buildMultiAccountChannelSchema(LineCommonConfigSchemaBase.extend({ groups: z.record(z.string(), LineGroupConfigSchema.optional()).optional() }).strict(), {
|
|
82
|
+
optionalAccount: true,
|
|
83
|
+
refine: (value, ctx) => {
|
|
84
|
+
requireChannelOpenAllowFrom({
|
|
85
|
+
channel: "line",
|
|
86
|
+
policy: value.dmPolicy,
|
|
87
|
+
allowFrom: value.allowFrom,
|
|
88
|
+
ctx,
|
|
89
|
+
requireOpenAllowFrom
|
|
90
|
+
});
|
|
91
|
+
}
|
|
115
92
|
});
|
|
116
93
|
const LineChannelConfigSchema = buildChannelConfigSchema(LineConfigSchema);
|
|
117
94
|
//#endregion
|
|
118
95
|
//#region extensions/line/src/runtime.ts
|
|
119
|
-
const { setRuntime: setLineRuntime,
|
|
96
|
+
const { setRuntime: setLineRuntime, getRuntime: getLineRuntime } = createPluginRuntimeStore({
|
|
120
97
|
pluginId: "line",
|
|
121
98
|
errorMessage: "LINE runtime not initialized - plugin not registered"
|
|
122
99
|
});
|
|
@@ -128,9 +105,9 @@ async function validateLineMediaUrl(url) {
|
|
|
128
105
|
try {
|
|
129
106
|
parsed = new URL(url);
|
|
130
107
|
} catch {
|
|
131
|
-
throw new Error(
|
|
108
|
+
throw new Error("LINE outbound media URL must be a valid URL");
|
|
132
109
|
}
|
|
133
|
-
if (parsed.protocol !== "https:") throw new Error(
|
|
110
|
+
if (parsed.protocol !== "https:") throw new Error("LINE outbound media URL must use HTTPS");
|
|
134
111
|
if (url.length > 2e3) throw new Error(`LINE outbound media URL must be 2000 chars or less (got ${url.length})`);
|
|
135
112
|
await resolvePinnedHostnameWithPolicy(parsed.hostname, { policy: LINE_OUTBOUND_MEDIA_SSRF_POLICY });
|
|
136
113
|
}
|
|
@@ -165,13 +142,47 @@ async function resolveLineOutboundMedia(mediaUrl, opts = {}) {
|
|
|
165
142
|
...opts.trackingId ? { trackingId: opts.trackingId } : {}
|
|
166
143
|
};
|
|
167
144
|
}
|
|
145
|
+
let parsed;
|
|
168
146
|
try {
|
|
169
|
-
|
|
170
|
-
} catch
|
|
171
|
-
|
|
172
|
-
}
|
|
147
|
+
parsed = new URL(trimmedUrl);
|
|
148
|
+
} catch {}
|
|
149
|
+
if (parsed) throw new Error("LINE outbound media URL must use HTTPS");
|
|
173
150
|
throw new Error("LINE outbound media currently requires a public HTTPS URL");
|
|
174
151
|
}
|
|
152
|
+
function isLineUserTarget(target) {
|
|
153
|
+
const normalized = target.trim().replace(/^line:(group|room|user):/i, "").replace(/^line:/i, "");
|
|
154
|
+
return /^U/i.test(normalized);
|
|
155
|
+
}
|
|
156
|
+
function hasLineSpecificMediaOptions(lineData) {
|
|
157
|
+
return lineData.mediaKind !== void 0 || Boolean(lineData.previewImageUrl?.trim()) || typeof lineData.durationMs === "number" || Boolean(lineData.trackingId?.trim());
|
|
158
|
+
}
|
|
159
|
+
function buildLineMediaMessageObject(resolved, opts) {
|
|
160
|
+
switch (resolved.mediaKind) {
|
|
161
|
+
case "video": {
|
|
162
|
+
const previewImageUrl = resolved.previewImageUrl?.trim();
|
|
163
|
+
if (!previewImageUrl) throw new Error("LINE video messages require previewImageUrl to reference an image URL");
|
|
164
|
+
return {
|
|
165
|
+
type: "video",
|
|
166
|
+
originalContentUrl: resolved.mediaUrl,
|
|
167
|
+
previewImageUrl,
|
|
168
|
+
...opts?.allowTrackingId && resolved.trackingId ? { trackingId: resolved.trackingId } : {}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
case "audio": return {
|
|
172
|
+
type: "audio",
|
|
173
|
+
originalContentUrl: resolved.mediaUrl,
|
|
174
|
+
duration: resolved.durationMs ?? 6e4
|
|
175
|
+
};
|
|
176
|
+
default: return {
|
|
177
|
+
type: "image",
|
|
178
|
+
originalContentUrl: resolved.mediaUrl,
|
|
179
|
+
previewImageUrl: resolved.previewImageUrl ?? resolved.mediaUrl
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function buildLineMediaMessage(mediaUrl, opts, target) {
|
|
184
|
+
return buildLineMediaMessageObject(await resolveLineOutboundMedia(mediaUrl, opts), { allowTrackingId: isLineUserTarget(target) });
|
|
185
|
+
}
|
|
175
186
|
//#endregion
|
|
176
187
|
//#region extensions/line/src/quick-reply-fallback.ts
|
|
177
188
|
function buildLineQuickReplyFallbackText(labels) {
|
|
@@ -223,17 +234,31 @@ function parseLineDirectives(payload) {
|
|
|
223
234
|
if (extras) for (const [key, value] of Object.entries(extras)) base.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
224
235
|
return base.join("&");
|
|
225
236
|
};
|
|
237
|
+
const parseConfirmAction = (part) => {
|
|
238
|
+
const colonIndex = part.indexOf(":");
|
|
239
|
+
if (colonIndex === -1) return {
|
|
240
|
+
label: part,
|
|
241
|
+
data: normalizeLowercaseStringOrEmpty(part)
|
|
242
|
+
};
|
|
243
|
+
return {
|
|
244
|
+
label: part.slice(0, colonIndex).trim(),
|
|
245
|
+
data: part.slice(colonIndex + 1).trim()
|
|
246
|
+
};
|
|
247
|
+
};
|
|
226
248
|
const quickRepliesMatch = text.match(/\[\[quick_replies:\s*([^\]]+)\]\]/i);
|
|
227
249
|
if (quickRepliesMatch) {
|
|
228
|
-
const options = normalizeStringEntries(quickRepliesMatch[1].split(","));
|
|
250
|
+
const options = normalizeStringEntries(expectDefined(quickRepliesMatch[1], "quick replies directive body").split(","));
|
|
229
251
|
if (options.length > 0) lineData.quickReplies = [...lineData.quickReplies || [], ...options];
|
|
230
252
|
text = text.replace(quickRepliesMatch[0], "").trim();
|
|
231
253
|
}
|
|
232
254
|
const locationMatch = text.match(/\[\[location:\s*([^\]]+)\]\]/i);
|
|
233
255
|
if (locationMatch && !lineData.location) {
|
|
234
|
-
const parts = locationMatch[1].split("|").map((s) => s.trim());
|
|
256
|
+
const parts = expectDefined(locationMatch[1], "location directive body").split("|").map((s) => s.trim());
|
|
235
257
|
if (parts.length >= 4) {
|
|
236
|
-
const
|
|
258
|
+
const title = expectDefined(parts[0], "location title field");
|
|
259
|
+
const address = expectDefined(parts[1], "location address field");
|
|
260
|
+
const latStr = expectDefined(parts[2], "location latitude field");
|
|
261
|
+
const lonStr = expectDefined(parts[3], "location longitude field");
|
|
237
262
|
const latitude = parseStrictFiniteNumber(latStr);
|
|
238
263
|
const longitude = parseStrictFiniteNumber(lonStr);
|
|
239
264
|
if (latitude !== void 0 && longitude !== void 0) lineData.location = {
|
|
@@ -247,18 +272,20 @@ function parseLineDirectives(payload) {
|
|
|
247
272
|
}
|
|
248
273
|
const confirmMatch = text.match(/\[\[confirm:\s*([^\]]+)\]\]/i);
|
|
249
274
|
if (confirmMatch && !lineData.templateMessage) {
|
|
250
|
-
const parts = confirmMatch[1].split("|").map((s) => s.trim());
|
|
275
|
+
const parts = expectDefined(confirmMatch[1], "confirm directive body").split("|").map((s) => s.trim());
|
|
251
276
|
if (parts.length >= 3) {
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
const
|
|
255
|
-
|
|
277
|
+
const question = expectDefined(parts[0], "confirm question field");
|
|
278
|
+
const yesPart = expectDefined(parts[1], "confirm yes field");
|
|
279
|
+
const noPart = expectDefined(parts[2], "confirm no field");
|
|
280
|
+
const yesAction = parseConfirmAction(yesPart);
|
|
281
|
+
const noAction = parseConfirmAction(noPart);
|
|
282
|
+
if (question && yesAction.label && noAction.label) lineData.templateMessage = {
|
|
256
283
|
type: "confirm",
|
|
257
284
|
text: question,
|
|
258
|
-
confirmLabel:
|
|
259
|
-
confirmData:
|
|
260
|
-
cancelLabel:
|
|
261
|
-
cancelData:
|
|
285
|
+
confirmLabel: yesAction.label,
|
|
286
|
+
confirmData: yesAction.data,
|
|
287
|
+
cancelLabel: noAction.label,
|
|
288
|
+
cancelData: noAction.data,
|
|
262
289
|
altText: question
|
|
263
290
|
};
|
|
264
291
|
}
|
|
@@ -266,10 +293,11 @@ function parseLineDirectives(payload) {
|
|
|
266
293
|
}
|
|
267
294
|
const buttonsMatch = text.match(/\[\[buttons:\s*([^\]]+)\]\]/i);
|
|
268
295
|
if (buttonsMatch && !lineData.templateMessage) {
|
|
269
|
-
const parts = buttonsMatch[1].split("|").map((s) => s.trim());
|
|
296
|
+
const parts = expectDefined(buttonsMatch[1], "buttons directive body").split("|").map((s) => s.trim());
|
|
270
297
|
if (parts.length >= 3) {
|
|
271
|
-
const
|
|
272
|
-
const
|
|
298
|
+
const title = expectDefined(parts[0], "buttons title field");
|
|
299
|
+
const bodyText = expectDefined(parts[1], "buttons text field");
|
|
300
|
+
const actions = expectDefined(parts[2], "buttons actions field").split(",").map((actionStr) => {
|
|
273
301
|
const trimmed = actionStr.trim();
|
|
274
302
|
const colonIndex = (() => {
|
|
275
303
|
const index = trimmed.indexOf(":");
|
|
@@ -302,22 +330,23 @@ function parseLineDirectives(payload) {
|
|
|
302
330
|
label,
|
|
303
331
|
data: data || label
|
|
304
332
|
};
|
|
305
|
-
});
|
|
306
|
-
if (actions.length > 0) lineData.templateMessage = {
|
|
333
|
+
}).filter((action) => action.label);
|
|
334
|
+
if (actions.length > 0 && bodyText) lineData.templateMessage = {
|
|
307
335
|
type: "buttons",
|
|
308
|
-
title,
|
|
336
|
+
...title ? { title } : {},
|
|
309
337
|
text: bodyText,
|
|
310
338
|
actions: actions.slice(0, 4),
|
|
311
|
-
altText: `${title}: ${bodyText}`
|
|
339
|
+
altText: title ? `${title}: ${bodyText}` : bodyText
|
|
312
340
|
};
|
|
313
341
|
}
|
|
314
342
|
text = text.replace(buttonsMatch[0], "").trim();
|
|
315
343
|
}
|
|
316
344
|
const mediaPlayerMatch = text.match(/\[\[media_player:\s*([^\]]+)\]\]/i);
|
|
317
345
|
if (mediaPlayerMatch && !lineData.flexMessage) {
|
|
318
|
-
const parts = mediaPlayerMatch[1].split("|").map((s) => s.trim());
|
|
346
|
+
const parts = expectDefined(mediaPlayerMatch[1], "media player directive body").split("|").map((s) => s.trim());
|
|
319
347
|
if (parts.length >= 1) {
|
|
320
|
-
const
|
|
348
|
+
const title = expectDefined(parts[0], "media player title field");
|
|
349
|
+
const [, artist, source, imageUrl, statusStr] = parts;
|
|
321
350
|
const isPlaying = normalizeLowercaseStringOrEmpty(statusStr) === "playing";
|
|
322
351
|
const validImageUrl = imageUrl?.startsWith("https://") ? imageUrl : void 0;
|
|
323
352
|
const deviceKey = toSlug(source || title || "media");
|
|
@@ -343,9 +372,13 @@ function parseLineDirectives(payload) {
|
|
|
343
372
|
}
|
|
344
373
|
const eventMatch = text.match(/\[\[event:\s*([^\]]+)\]\]/i);
|
|
345
374
|
if (eventMatch && !lineData.flexMessage) {
|
|
346
|
-
const parts = eventMatch[1].split("|").map((s) => s.trim());
|
|
375
|
+
const parts = expectDefined(eventMatch[1], "event directive body").split("|").map((s) => s.trim());
|
|
347
376
|
if (parts.length >= 2) {
|
|
348
|
-
const
|
|
377
|
+
const title = expectDefined(parts[0], "event title field");
|
|
378
|
+
const date = expectDefined(parts[1], "event date field");
|
|
379
|
+
const time = parts[2];
|
|
380
|
+
const location = parts[3];
|
|
381
|
+
const description = parts[4];
|
|
349
382
|
const card = createEventCard({
|
|
350
383
|
title: title || "Event",
|
|
351
384
|
date: date || "TBD",
|
|
@@ -362,9 +395,10 @@ function parseLineDirectives(payload) {
|
|
|
362
395
|
}
|
|
363
396
|
const appleTvMatch = text.match(/\[\[appletv_remote:\s*([^\]]+)\]\]/i);
|
|
364
397
|
if (appleTvMatch && !lineData.flexMessage) {
|
|
365
|
-
const parts = appleTvMatch[1].split("|").map((s) => s.trim());
|
|
398
|
+
const parts = expectDefined(appleTvMatch[1], "Apple TV directive body").split("|").map((s) => s.trim());
|
|
366
399
|
if (parts.length >= 1) {
|
|
367
|
-
const
|
|
400
|
+
const deviceName = expectDefined(parts[0], "Apple TV device name field");
|
|
401
|
+
const [, status] = parts;
|
|
368
402
|
const deviceKey = toSlug(deviceName || "apple_tv");
|
|
369
403
|
const card = createAppleTvRemoteCard({
|
|
370
404
|
deviceName: deviceName || "Apple TV",
|
|
@@ -393,10 +427,10 @@ function parseLineDirectives(payload) {
|
|
|
393
427
|
}
|
|
394
428
|
const agendaMatch = text.match(/\[\[agenda:\s*([^\]]+)\]\]/i);
|
|
395
429
|
if (agendaMatch && !lineData.flexMessage) {
|
|
396
|
-
const parts = agendaMatch[1].split("|").map((s) => s.trim());
|
|
430
|
+
const parts = expectDefined(agendaMatch[1], "agenda directive body").split("|").map((s) => s.trim());
|
|
397
431
|
if (parts.length >= 2) {
|
|
398
|
-
const
|
|
399
|
-
const events =
|
|
432
|
+
const title = expectDefined(parts[0], "agenda title field");
|
|
433
|
+
const events = normalizeStringEntries(expectDefined(parts[1], "agenda events field").split(",")).map((eventStr) => {
|
|
400
434
|
const trimmed = eventStr.trim();
|
|
401
435
|
const colonIdx = trimmed.lastIndexOf(":");
|
|
402
436
|
if (colonIdx > 0) return {
|
|
@@ -418,17 +452,20 @@ function parseLineDirectives(payload) {
|
|
|
418
452
|
}
|
|
419
453
|
const deviceMatch = text.match(/\[\[device:\s*([^\]]+)\]\]/i);
|
|
420
454
|
if (deviceMatch && !lineData.flexMessage) {
|
|
421
|
-
const parts = deviceMatch[1].split("|").map((s) => s.trim());
|
|
455
|
+
const parts = expectDefined(deviceMatch[1], "device directive body").split("|").map((s) => s.trim());
|
|
422
456
|
if (parts.length >= 1) {
|
|
423
|
-
const
|
|
457
|
+
const deviceName = expectDefined(parts[0], "device name field");
|
|
458
|
+
const [, deviceType, status, controlsStr] = parts;
|
|
424
459
|
const deviceKey = toSlug(deviceName || "device");
|
|
425
|
-
const controls = controlsStr ? controlsStr.split(",").
|
|
426
|
-
const
|
|
427
|
-
const
|
|
428
|
-
return
|
|
460
|
+
const controls = controlsStr ? normalizeStringEntries(controlsStr.split(",")).flatMap((ctrlStr) => {
|
|
461
|
+
const controlParts = ctrlStr.split(":").map((s) => s.trim());
|
|
462
|
+
const label = expectDefined(controlParts[0], "device control label");
|
|
463
|
+
if (!label) return [];
|
|
464
|
+
const action = controlParts[1] || normalizeLowercaseStringOrEmpty(label).replace(/\s+/g, "_");
|
|
465
|
+
return [{
|
|
429
466
|
label,
|
|
430
467
|
data: lineActionData(action, { "line.device": deviceKey })
|
|
431
|
-
};
|
|
468
|
+
}];
|
|
432
469
|
}) : [];
|
|
433
470
|
const card = createDeviceControlCard({
|
|
434
471
|
deviceName: deviceName || "Device",
|
|
@@ -455,4 +492,4 @@ function hasLineDirectives(text) {
|
|
|
455
492
|
return /\[\[(quick_replies|location|confirm|buttons|media_player|event|agenda|device|appletv_remote):/i.test(text);
|
|
456
493
|
}
|
|
457
494
|
//#endregion
|
|
458
|
-
export {
|
|
495
|
+
export { buildLineMediaMessage as a, validateLineMediaUrl as c, LineChannelConfigSchema as d, LineConfigSchema as f, resolveLineGroupsConfig as g, resolveLineGroupLookupIds as h, buildLineQuickReplyFallbackText as i, getLineRuntime as l, resolveLineGroupConfigEntry as m, parseLineDirectives as n, hasLineSpecificMediaOptions as o, resolveExactLineGroupConfigKey as p, createLineSendReceipt as r, resolveLineOutboundMedia as s, hasLineDirectives as t, setLineRuntime as u };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-DJVOv1JI.js";
|
|
2
|
-
import {
|
|
3
|
-
import { _ as createNotificationBubble, a as datetimePickerAction, c as uriAction, d as createReceiptCard, f as createActionCard, g as createListCard, h as createInfoCard, i as createMediaPlayerCard, l as createAgendaCard, m as createImageCard, n as createAppleTvRemoteCard, o as messageAction, p as createCarousel, r as createDeviceControlCard, s as postbackAction, t as toFlexMessage, u as createEventCard } from "./flex-templates-
|
|
4
|
-
import { a as validateLineSignature, c as normalizeAllowFrom, i as parseLineWebhookBody, n as createLineNodeWebhookHandler, o as downloadLineMedia, r as readLineWebhookRequestBody, s as firstDefined, t as monitorLineProvider } from "./monitor-
|
|
2
|
+
import { d as LineChannelConfigSchema, f as LineConfigSchema, g as resolveLineGroupsConfig, h as resolveLineGroupLookupIds, m as resolveLineGroupConfigEntry, n as parseLineDirectives, p as resolveExactLineGroupConfigKey, t as hasLineDirectives, u as setLineRuntime } from "./reply-payload-transform-r9sa-TYT.js";
|
|
3
|
+
import { _ as createNotificationBubble, a as datetimePickerAction, c as uriAction, d as createReceiptCard, f as createActionCard, g as createListCard, h as createInfoCard, i as createMediaPlayerCard, l as createAgendaCard, m as createImageCard, n as createAppleTvRemoteCard, o as messageAction, p as createCarousel, r as createDeviceControlCard, s as postbackAction, t as toFlexMessage, u as createEventCard } from "./flex-templates-K1lS9i8L.js";
|
|
4
|
+
import { a as validateLineSignature, c as normalizeAllowFrom, i as parseLineWebhookBody, n as createLineNodeWebhookHandler, o as downloadLineMedia, r as readLineWebhookRequestBody, s as firstDefined, t as monitorLineProvider } from "./monitor-Db2rZsSX.js";
|
|
5
5
|
import { t as probeLineBot } from "./probe-BslD77tJ.js";
|
|
6
|
-
import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, I as createImageCarouselColumn, L as createLinkMenu, M as createButtonTemplate, N as createCarouselColumn, O as showLoadingAnimation, P as createConfirmTemplate, R as createProductCarousel, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, a as extractLinks, b as pushImageMessage, c as processLineMessage, d as createFlexMessage, f as createImageMessage, g as createVideoMessage, h as createTextMessageWithQuickReplies, i as extractCodeBlocks, j as createButtonMenu, k as resolveLineChannelAccessToken, l as stripMarkdown, m as createQuickReplyItems, n as convertLinksToFlexBubble, o as extractMarkdownTables, p as createLocationMessage, r as convertTableToFlexBubble, s as hasMarkdownToConvert, t as convertCodeBlockToFlexBubble, u as createAudioMessage, v as getUserProfile, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage, z as createTemplateCarousel } from "./markdown-to-line-
|
|
6
|
+
import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, I as createImageCarouselColumn, L as createLinkMenu, M as createButtonTemplate, N as createCarouselColumn, O as showLoadingAnimation, P as createConfirmTemplate, R as createProductCarousel, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, a as extractLinks, b as pushImageMessage, c as processLineMessage, d as createFlexMessage, f as createImageMessage, g as createVideoMessage, h as createTextMessageWithQuickReplies, i as extractCodeBlocks, j as createButtonMenu, k as resolveLineChannelAccessToken, l as stripMarkdown, m as createQuickReplyItems, n as convertLinksToFlexBubble, o as extractMarkdownTables, p as createLocationMessage, r as convertTableToFlexBubble, s as hasMarkdownToConvert, t as convertCodeBlockToFlexBubble, u as createAudioMessage, v as getUserProfile, w as pushTemplateMessage, x as pushLocationMessage, y as pushFlexMessage, z as createTemplateCarousel } from "./markdown-to-line-XceqeKRP.js";
|
|
7
7
|
import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
|
|
8
8
|
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
|
|
9
9
|
import { createMessageReceiveContext } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
10
|
import { DEFAULT_ACCOUNT_ID, formatDocsLink, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
11
11
|
import { buildComputedAccountStatusSnapshot, buildTokenChannelStatusSummary } from "openclaw/plugin-sdk/status-helpers";
|
|
12
|
-
import { messagingApi } from "@line/bot-sdk";
|
|
13
12
|
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
13
|
+
import { messagingApi } from "@line/bot-sdk";
|
|
14
|
+
import { runDetachedWebhookWork } from "openclaw/plugin-sdk/webhook-request-guards";
|
|
14
15
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/agent-media-payload";
|
|
15
16
|
import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
|
|
16
17
|
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
|
|
@@ -69,7 +70,7 @@ function createLineWebhookMiddleware(options) {
|
|
|
69
70
|
if (receiveContext.shouldAckAfter("receive_record")) await receiveContext.ack();
|
|
70
71
|
if (body.events && body.events.length > 0) {
|
|
71
72
|
logVerbose(`line: received ${body.events.length} webhook events`);
|
|
72
|
-
|
|
73
|
+
runDetachedWebhookWork(() => onEvents(body)).catch((err) => logLineWebhookDispatchError(runtime, err));
|
|
73
74
|
}
|
|
74
75
|
} catch (err) {
|
|
75
76
|
await receiveContext?.nack(err);
|
|
@@ -92,7 +93,6 @@ function startLineWebhook(options) {
|
|
|
92
93
|
}
|
|
93
94
|
//#endregion
|
|
94
95
|
//#region extensions/line/src/rich-menu.ts
|
|
95
|
-
const USER_BATCH_SIZE = 500;
|
|
96
96
|
const graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
97
97
|
function getClient(opts) {
|
|
98
98
|
const account = resolveLineAccount({
|
|
@@ -110,11 +110,6 @@ function getBlobClient(opts) {
|
|
|
110
110
|
const token = resolveLineChannelAccessToken(opts.channelAccessToken, account);
|
|
111
111
|
return new messagingApi.MessagingApiBlobClient({ channelAccessToken: token });
|
|
112
112
|
}
|
|
113
|
-
function chunkUserIds(userIds) {
|
|
114
|
-
const batches = [];
|
|
115
|
-
for (let i = 0; i < userIds.length; i += USER_BATCH_SIZE) batches.push(userIds.slice(i, i + USER_BATCH_SIZE));
|
|
116
|
-
return batches;
|
|
117
|
-
}
|
|
118
113
|
function truncateGraphemes(input, maxLength) {
|
|
119
114
|
let result = "";
|
|
120
115
|
let count = 0;
|
|
@@ -163,27 +158,6 @@ async function getDefaultRichMenuId(opts) {
|
|
|
163
158
|
return null;
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
|
-
async function linkRichMenuToUser(userId, richMenuId, opts) {
|
|
167
|
-
await getClient(opts).linkRichMenuIdToUser(userId, richMenuId);
|
|
168
|
-
if (opts.verbose) logVerbose(`line: linked rich menu ${richMenuId} to user ${userId}`);
|
|
169
|
-
}
|
|
170
|
-
async function linkRichMenuToUsers(userIds, richMenuId, opts) {
|
|
171
|
-
const client = getClient(opts);
|
|
172
|
-
for (const batch of chunkUserIds(userIds)) await client.linkRichMenuIdToUsers({
|
|
173
|
-
richMenuId,
|
|
174
|
-
userIds: batch
|
|
175
|
-
});
|
|
176
|
-
if (opts.verbose) logVerbose(`line: linked rich menu ${richMenuId} to ${userIds.length} users`);
|
|
177
|
-
}
|
|
178
|
-
async function unlinkRichMenuFromUser(userId, opts) {
|
|
179
|
-
await getClient(opts).unlinkRichMenuIdFromUser(userId);
|
|
180
|
-
if (opts.verbose) logVerbose(`line: unlinked rich menu from user ${userId}`);
|
|
181
|
-
}
|
|
182
|
-
async function unlinkRichMenuFromUsers(userIds, opts) {
|
|
183
|
-
const client = getClient(opts);
|
|
184
|
-
for (const batch of chunkUserIds(userIds)) await client.unlinkRichMenuIdFromUsers({ userIds: batch });
|
|
185
|
-
if (opts.verbose) logVerbose(`line: unlinked rich menu from ${userIds.length} users`);
|
|
186
|
-
}
|
|
187
161
|
async function getRichMenuIdOfUser(userId, opts) {
|
|
188
162
|
const client = getClient(opts);
|
|
189
163
|
try {
|
|
@@ -298,4 +272,4 @@ function createDefaultMenuConfig() {
|
|
|
298
272
|
};
|
|
299
273
|
}
|
|
300
274
|
//#endregion
|
|
301
|
-
export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, convertLinksToFlexBubble, convertTableToFlexBubble, createActionCard, createAgendaCard, createAppleTvRemoteCard, createAudioMessage, createButtonMenu, createButtonTemplate, createCarousel, createCarouselColumn, createConfirmTemplate, createDefaultMenuConfig, createDeviceControlCard, createEventCard, createFlexMessage, createGridLayout, createImageCard, createImageCarousel, createImageCarouselColumn, createImageMessage, createInfoCard, createLineNodeWebhookHandler, createLineWebhookMiddleware, createLinkMenu, createListCard, createLocationMessage, createMediaPlayerCard, createNotificationBubble, createProductCarousel, createQuickReplyItems, createReceiptCard, createRichMenu, createRichMenuAlias, createTemplateCarousel, createTextMessageWithQuickReplies, createVideoMessage, createYesNoConfirm, datetimePickerAction, deleteRichMenu, deleteRichMenuAlias, downloadLineMedia, extractCodeBlocks, extractLinks, extractMarkdownTables, firstDefined, formatDocsLink, getDefaultRichMenuId, getRichMenu, getRichMenuIdOfUser, getRichMenuList, getUserDisplayName, getUserProfile, hasLineDirectives, hasMarkdownToConvert,
|
|
275
|
+
export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, convertLinksToFlexBubble, convertTableToFlexBubble, createActionCard, createAgendaCard, createAppleTvRemoteCard, createAudioMessage, createButtonMenu, createButtonTemplate, createCarousel, createCarouselColumn, createConfirmTemplate, createDefaultMenuConfig, createDeviceControlCard, createEventCard, createFlexMessage, createGridLayout, createImageCard, createImageCarousel, createImageCarouselColumn, createImageMessage, createInfoCard, createLineNodeWebhookHandler, createLineWebhookMiddleware, createLinkMenu, createListCard, createLocationMessage, createMediaPlayerCard, createNotificationBubble, createProductCarousel, createQuickReplyItems, createReceiptCard, createRichMenu, createRichMenuAlias, createTemplateCarousel, createTextMessageWithQuickReplies, createVideoMessage, createYesNoConfirm, datetimePickerAction, deleteRichMenu, deleteRichMenuAlias, downloadLineMedia, extractCodeBlocks, extractLinks, extractMarkdownTables, firstDefined, formatDocsLink, getDefaultRichMenuId, getRichMenu, getRichMenuIdOfUser, getRichMenuList, getUserDisplayName, getUserProfile, hasLineDirectives, hasMarkdownToConvert, listLineAccountIds, messageAction, monitorLineProvider, normalizeAccountId, normalizeAllowFrom, parseLineDirectives, parseLineWebhookBody, postbackAction, probeLineBot, processLineMessage, pushFlexMessage, pushImageMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, readLineWebhookRequestBody, replyMessageLine, resolveDefaultLineAccountId, resolveExactLineGroupConfigKey, resolveLineAccount, resolveLineChannelAccessToken, resolveLineGroupConfigEntry, resolveLineGroupLookupIds, resolveLineGroupsConfig, sendMessageLine, setDefaultRichMenu, setLineRuntime, setSetupChannelEnabled, showLoadingAnimation, splitSetupEntries, startLineWebhook, stripMarkdown, toFlexMessage, uploadRichMenuImage, uriAction, validateLineSignature };
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-
|
|
1
|
+
import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-B7W6pwn3.js";
|
|
2
2
|
export { lineSetupAdapter, lineSetupWizard };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-DJVOv1JI.js";
|
|
2
2
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
-
import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
3
|
+
import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
|
|
4
4
|
//#region extensions/line/src/account-helpers.ts
|
|
5
5
|
function hasLineCredentials(account) {
|
|
6
6
|
return Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim());
|
|
@@ -173,8 +173,10 @@ const lineSetupWizard = {
|
|
|
173
173
|
lines: LINE_SETUP_HELP_LINES,
|
|
174
174
|
shouldShow: ({ cfg, accountId }) => !isLineConfigured(cfg, accountId ?? resolveDefaultLineAccountId(cfg))
|
|
175
175
|
},
|
|
176
|
-
credentials: [{
|
|
176
|
+
credentials: [defineTokenCredential({
|
|
177
177
|
inputKey: "token",
|
|
178
|
+
configKey: "channelAccessToken",
|
|
179
|
+
configuredFields: ["channelAccessToken", "tokenFile"],
|
|
178
180
|
providerHint: channel,
|
|
179
181
|
credentialLabel: t("wizard.line.channelAccessToken"),
|
|
180
182
|
preferredEnvVar: "LINE_CHANNEL_ACCESS_TOKEN",
|
|
@@ -184,34 +186,30 @@ const lineSetupWizard = {
|
|
|
184
186
|
keepPrompt: t("wizard.line.tokenKeepPrompt"),
|
|
185
187
|
inputPrompt: t("wizard.line.tokenInputPrompt"),
|
|
186
188
|
allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
|
|
187
|
-
|
|
188
|
-
const resolved = resolveLineAccount({
|
|
189
|
-
cfg,
|
|
190
|
-
accountId
|
|
191
|
-
});
|
|
192
|
-
return {
|
|
193
|
-
accountConfigured: Boolean(normalizeOptionalString(resolved.channelAccessToken) && normalizeOptionalString(resolved.channelSecret)),
|
|
194
|
-
hasConfiguredValue: Boolean(normalizeOptionalString(resolved.config.channelAccessToken) ?? normalizeOptionalString(resolved.config.tokenFile)),
|
|
195
|
-
resolvedValue: normalizeOptionalString(resolved.channelAccessToken),
|
|
196
|
-
envValue: accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_ACCESS_TOKEN) : void 0
|
|
197
|
-
};
|
|
198
|
-
},
|
|
199
|
-
applyUseEnv: ({ cfg, accountId }) => patchLineAccountConfig({
|
|
189
|
+
resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
|
|
200
190
|
cfg,
|
|
201
|
-
accountId
|
|
202
|
-
enabled: true,
|
|
203
|
-
clearFields: ["channelAccessToken", "tokenFile"],
|
|
204
|
-
patch: {}
|
|
191
|
+
accountId
|
|
205
192
|
}),
|
|
206
|
-
|
|
193
|
+
accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
|
|
194
|
+
hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelAccessToken) ?? normalizeOptionalString(account.config.tokenFile)),
|
|
195
|
+
resolvedValue: (account) => normalizeOptionalString(account.channelAccessToken),
|
|
196
|
+
envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_ACCESS_TOKEN) : void 0,
|
|
197
|
+
patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
|
|
207
198
|
cfg,
|
|
208
199
|
accountId,
|
|
209
200
|
enabled: true,
|
|
201
|
+
clearFields,
|
|
202
|
+
patch
|
|
203
|
+
}),
|
|
204
|
+
useEnv: { clearFields: ["channelAccessToken", "tokenFile"] },
|
|
205
|
+
set: {
|
|
210
206
|
clearFields: ["tokenFile"],
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
}, {
|
|
207
|
+
value: "resolved"
|
|
208
|
+
}
|
|
209
|
+
}), defineTokenCredential({
|
|
214
210
|
inputKey: "password",
|
|
211
|
+
configKey: "channelSecret",
|
|
212
|
+
configuredFields: ["channelSecret", "secretFile"],
|
|
215
213
|
providerHint: "line-secret",
|
|
216
214
|
credentialLabel: t("wizard.line.channelSecret"),
|
|
217
215
|
preferredEnvVar: "LINE_CHANNEL_SECRET",
|
|
@@ -221,33 +219,27 @@ const lineSetupWizard = {
|
|
|
221
219
|
keepPrompt: t("wizard.line.secretKeepPrompt"),
|
|
222
220
|
inputPrompt: t("wizard.line.secretInputPrompt"),
|
|
223
221
|
allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
|
|
224
|
-
|
|
225
|
-
const resolved = resolveLineAccount({
|
|
226
|
-
cfg,
|
|
227
|
-
accountId
|
|
228
|
-
});
|
|
229
|
-
return {
|
|
230
|
-
accountConfigured: Boolean(normalizeOptionalString(resolved.channelAccessToken) && normalizeOptionalString(resolved.channelSecret)),
|
|
231
|
-
hasConfiguredValue: Boolean(normalizeOptionalString(resolved.config.channelSecret) ?? normalizeOptionalString(resolved.config.secretFile)),
|
|
232
|
-
resolvedValue: normalizeOptionalString(resolved.channelSecret),
|
|
233
|
-
envValue: accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_SECRET) : void 0
|
|
234
|
-
};
|
|
235
|
-
},
|
|
236
|
-
applyUseEnv: ({ cfg, accountId }) => patchLineAccountConfig({
|
|
222
|
+
resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
|
|
237
223
|
cfg,
|
|
238
|
-
accountId
|
|
239
|
-
enabled: true,
|
|
240
|
-
clearFields: ["channelSecret", "secretFile"],
|
|
241
|
-
patch: {}
|
|
224
|
+
accountId
|
|
242
225
|
}),
|
|
243
|
-
|
|
226
|
+
accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
|
|
227
|
+
hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelSecret) ?? normalizeOptionalString(account.config.secretFile)),
|
|
228
|
+
resolvedValue: (account) => normalizeOptionalString(account.channelSecret),
|
|
229
|
+
envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_SECRET) : void 0,
|
|
230
|
+
patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
|
|
244
231
|
cfg,
|
|
245
232
|
accountId,
|
|
246
233
|
enabled: true,
|
|
234
|
+
clearFields,
|
|
235
|
+
patch
|
|
236
|
+
}),
|
|
237
|
+
useEnv: { clearFields: ["channelSecret", "secretFile"] },
|
|
238
|
+
set: {
|
|
247
239
|
clearFields: ["secretFile"],
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
}],
|
|
240
|
+
value: "resolved"
|
|
241
|
+
}
|
|
242
|
+
})],
|
|
251
243
|
allowFrom: createAllowFromSection({
|
|
252
244
|
helpTitle: t("wizard.line.allowlistTitle"),
|
|
253
245
|
helpLines: LINE_ALLOW_FROM_HELP_LINES,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/line",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/line",
|
|
9
|
-
"version": "2026.7.
|
|
9
|
+
"version": "2026.7.2-beta.2",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@line/bot-sdk": "11.1.0",
|
|
12
12
|
"zod": "4.4.3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.7.
|
|
15
|
+
"openclaw": ">=2026.7.2-beta.2"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|