@openclaw/line 2026.7.2-beta.7 → 2026.8.1-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 -3
- package/dist/{card-command-ty11OJNt.js → card-command-DALdUSnc.js} +14 -22
- package/dist/{channel-D4i_K4fQ.js → channel-CAdQJRw7.js} +74 -76
- package/dist/channel-plugin-api.js +1 -1
- package/dist/channel.runtime-CuKoy9xw.js +4 -0
- package/dist/{flex-templates-iKJsyCq-.js → flex-templates-BBBlNqpV.js} +108 -81
- package/dist/index.js +1 -1
- package/dist/markdown-to-line-D4I-6lm6.js +499 -0
- package/dist/{monitor-DXEodYFJ.js → monitor-QEh_ZqyR.js} +94 -43
- package/dist/monitor.runtime-72isajCp.js +2 -0
- package/dist/outbound.runtime-CWQMIE7N.js +3 -0
- package/dist/{reply-payload-transform-D5-dHB8b.js → reply-payload-transform-BOPGHVPo.js} +4 -3
- package/dist/runtime-api.js +6 -5
- package/dist/send-CFFr0-rZ.js +366 -0
- package/dist/setup-api.js +1 -1
- package/dist/{setup-surface-DRQ7n0En.js → setup-surface-W0Dbgu58.js} +2 -1
- package/openclaw.plugin.json +7 -0
- package/package.json +9 -5
- package/dist/channel.runtime-BdhK8Xw7.js +0 -4
- package/dist/markdown-to-line-DMDQTMhx.js +0 -799
- package/dist/monitor.runtime-CZquR7jI.js +0 -2
- package/dist/outbound.runtime-BS0IhU_M.js +0 -2
- package/dist/send-receipt-CY2ey8XH.js +0 -107
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { i as resolveLineAccount } from "./accounts-BqEVsDoB.js";
|
|
2
|
+
import { _ as createLineSendReceipt, f as messageAction, m as normalizeLineMessageActions, x as validateLineMediaUrl } from "./flex-templates-BBBlNqpV.js";
|
|
3
|
+
import { createChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
|
|
4
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
|
+
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
6
|
+
import { fetchWithRuntimeDispatcherOrMockedGlobal } from "openclaw/plugin-sdk/runtime-fetch";
|
|
7
|
+
import { HTTPFetchError, messagingApi } from "@line/bot-sdk";
|
|
8
|
+
import lineBotSdkPackage from "@line/bot-sdk/package.json" with { type: "json" };
|
|
9
|
+
import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
|
|
10
|
+
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
11
|
+
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
12
|
+
//#region extensions/line/src/channel-access-token.ts
|
|
13
|
+
function resolveLineChannelAccessToken(explicit, params) {
|
|
14
|
+
if (explicit?.trim()) return explicit.trim();
|
|
15
|
+
if (!params.channelAccessToken) throw new Error(`LINE channel access token missing for account "${params.accountId}" (set channels.line.channelAccessToken or LINE_CHANNEL_ACCESS_TOKEN).`);
|
|
16
|
+
return params.channelAccessToken.trim();
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region extensions/line/src/send.ts
|
|
20
|
+
const userProfileCache = /* @__PURE__ */ new Map();
|
|
21
|
+
const PROFILE_CACHE_TTL_MS = 300 * 1e3;
|
|
22
|
+
const PROFILE_CACHE_MAX_ENTRIES = 1e3;
|
|
23
|
+
const LINE_FLEX_ALT_TEXT_LIMIT = 1500;
|
|
24
|
+
function cacheUserProfile(userId, profile) {
|
|
25
|
+
userProfileCache.delete(userId);
|
|
26
|
+
userProfileCache.set(userId, profile);
|
|
27
|
+
if (userProfileCache.size <= PROFILE_CACHE_MAX_ENTRIES) return;
|
|
28
|
+
for (const [key, cached] of userProfileCache) if (profile.fetchedAt - cached.fetchedAt >= PROFILE_CACHE_TTL_MS) userProfileCache.delete(key);
|
|
29
|
+
pruneMapToMaxSize(userProfileCache, PROFILE_CACHE_MAX_ENTRIES);
|
|
30
|
+
}
|
|
31
|
+
function resolveLineProviderMessageIds(response, operation) {
|
|
32
|
+
const sentMessages = Array.isArray(response?.sentMessages) ? response.sentMessages : [];
|
|
33
|
+
const messageIds = sentMessages.flatMap((entry) => {
|
|
34
|
+
const id = entry && typeof entry === "object" ? entry.id : void 0;
|
|
35
|
+
const messageId = typeof id === "string" ? id.trim() : "";
|
|
36
|
+
return messageId ? [messageId] : [];
|
|
37
|
+
});
|
|
38
|
+
const messageId = messageIds[0];
|
|
39
|
+
if (!messageId || messageIds.length !== sentMessages.length) throw createChannelPartialDeliveryError(/* @__PURE__ */ new Error(`LINE ${operation} response did not include a sent message id`), {
|
|
40
|
+
messageIds,
|
|
41
|
+
visibleReplySent: true
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
messageId,
|
|
45
|
+
messageIds
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function normalizeTarget(to) {
|
|
49
|
+
const trimmed = to.trim();
|
|
50
|
+
if (!trimmed) throw new Error("Recipient is required for LINE sends");
|
|
51
|
+
const normalized = trimmed.replace(/^line:group:/i, "").replace(/^line:room:/i, "").replace(/^line:user:/i, "").replace(/^line:/i, "");
|
|
52
|
+
if (!normalized) throw new Error("Recipient is required for LINE sends");
|
|
53
|
+
if (normalized.length >= 33 && !/^[CUR]/.test(normalized)) throw new Error(`Recipient is not a valid LINE id (case-sensitive; expected leading capital C/U/R): ${truncateUtf16Safe(normalized, 4)}…`);
|
|
54
|
+
return normalized;
|
|
55
|
+
}
|
|
56
|
+
function isLineUserChatId(chatId) {
|
|
57
|
+
return /^U/i.test(chatId);
|
|
58
|
+
}
|
|
59
|
+
function resolveLineMessagingAccount(opts) {
|
|
60
|
+
const account = resolveLineAccount({
|
|
61
|
+
cfg: requireRuntimeConfig(opts.cfg, "LINE send"),
|
|
62
|
+
accountId: opts.accountId
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
account,
|
|
66
|
+
token: resolveLineChannelAccessToken(opts.channelAccessToken, account)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function createLineMessagingClient(opts) {
|
|
70
|
+
const { account, token } = resolveLineMessagingAccount(opts);
|
|
71
|
+
return {
|
|
72
|
+
account,
|
|
73
|
+
client: new messagingApi.MessagingApiClient({ channelAccessToken: token })
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function createLinePushContext(to, opts) {
|
|
77
|
+
const { account, token } = resolveLineMessagingAccount(opts);
|
|
78
|
+
return {
|
|
79
|
+
account,
|
|
80
|
+
token,
|
|
81
|
+
chatId: normalizeTarget(to)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function sendLineProviderMessages(operation, token, request) {
|
|
85
|
+
const response = await fetchWithRuntimeDispatcherOrMockedGlobal(`https://api.line.me/v2/bot/message/${operation}`, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
Authorization: `Bearer ${token}`,
|
|
90
|
+
"User-Agent": `@line/bot-sdk/${lineBotSdkPackage.version}`
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify(request)
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok) throw new HTTPFetchError(`${response.status} - ${response.statusText}`, {
|
|
95
|
+
status: response.status,
|
|
96
|
+
statusText: response.statusText,
|
|
97
|
+
headers: response.headers,
|
|
98
|
+
body: await response.text()
|
|
99
|
+
});
|
|
100
|
+
try {
|
|
101
|
+
const text = await response.text();
|
|
102
|
+
return text ? JSON.parse(text) : null;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw createChannelPartialDeliveryError(error, {
|
|
105
|
+
messageIds: [],
|
|
106
|
+
visibleReplySent: true
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function createTextMessage(text) {
|
|
111
|
+
return {
|
|
112
|
+
type: "text",
|
|
113
|
+
text
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function createImageMessage(originalContentUrl, previewImageUrl) {
|
|
117
|
+
return {
|
|
118
|
+
type: "image",
|
|
119
|
+
originalContentUrl,
|
|
120
|
+
previewImageUrl: previewImageUrl ?? originalContentUrl
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function createVideoMessage(originalContentUrl, previewImageUrl, trackingId) {
|
|
124
|
+
return {
|
|
125
|
+
type: "video",
|
|
126
|
+
originalContentUrl,
|
|
127
|
+
previewImageUrl,
|
|
128
|
+
...trackingId ? { trackingId } : {}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function createAudioMessage(originalContentUrl, durationMs) {
|
|
132
|
+
return {
|
|
133
|
+
type: "audio",
|
|
134
|
+
originalContentUrl,
|
|
135
|
+
duration: durationMs
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function isValidLineLocation(location) {
|
|
139
|
+
return location.title.trim().length > 0 && location.address.trim().length > 0;
|
|
140
|
+
}
|
|
141
|
+
function createLocationMessage(location) {
|
|
142
|
+
if (!isValidLineLocation(location)) return null;
|
|
143
|
+
return {
|
|
144
|
+
type: "location",
|
|
145
|
+
title: truncateUtf16Safe(location.title, 100),
|
|
146
|
+
address: truncateUtf16Safe(location.address, 100),
|
|
147
|
+
latitude: location.latitude,
|
|
148
|
+
longitude: location.longitude
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function logLineHttpError(err, context) {
|
|
152
|
+
if (!err || typeof err !== "object") return;
|
|
153
|
+
const { status, statusText, body } = err;
|
|
154
|
+
if (typeof body === "string") logVerbose(`line: ${context} failed (${status ? `${status} ${statusText ?? ""}`.trim() : "unknown status"}): ${body}`);
|
|
155
|
+
}
|
|
156
|
+
function recordLineOutboundActivity(accountId, delivery) {
|
|
157
|
+
try {
|
|
158
|
+
recordChannelActivity({
|
|
159
|
+
channel: "line",
|
|
160
|
+
accountId,
|
|
161
|
+
direction: "outbound"
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw createChannelPartialDeliveryError(error, {
|
|
165
|
+
messageIds: delivery.messageIds,
|
|
166
|
+
...delivery.receipt ? { receipt: delivery.receipt } : {},
|
|
167
|
+
visibleReplySent: true
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function resolveLineReceiptKind(messages) {
|
|
172
|
+
const types = new Set(messages.map((message) => message.type));
|
|
173
|
+
if (types.has("audio")) return "voice";
|
|
174
|
+
if (types.has("image") || types.has("video")) return "media";
|
|
175
|
+
if (types.has("flex") || types.has("template") || types.has("location")) return "card";
|
|
176
|
+
if (types.has("text")) return "text";
|
|
177
|
+
return "unknown";
|
|
178
|
+
}
|
|
179
|
+
async function pushLineMessages(to, messages, opts, behavior = {}) {
|
|
180
|
+
if (messages.length === 0) throw new Error("Message must be non-empty for LINE sends");
|
|
181
|
+
const { account, token, chatId } = createLinePushContext(to, opts);
|
|
182
|
+
const pushRequest = sendLineProviderMessages("push", token, {
|
|
183
|
+
to: chatId,
|
|
184
|
+
messages: messages.map(normalizeLineMessageActions)
|
|
185
|
+
});
|
|
186
|
+
const { messageId, messageIds } = resolveLineProviderMessageIds(behavior.errorContext ? await pushRequest.catch((err) => {
|
|
187
|
+
logLineHttpError(err, behavior.errorContext);
|
|
188
|
+
throw err;
|
|
189
|
+
}) : await pushRequest, "push");
|
|
190
|
+
const result = {
|
|
191
|
+
messageId,
|
|
192
|
+
chatId,
|
|
193
|
+
receipt: createLineSendReceipt({
|
|
194
|
+
messageId,
|
|
195
|
+
messageIds,
|
|
196
|
+
chatId,
|
|
197
|
+
kind: resolveLineReceiptKind(messages),
|
|
198
|
+
messageCount: messages.length
|
|
199
|
+
})
|
|
200
|
+
};
|
|
201
|
+
recordLineOutboundActivity(account.accountId, {
|
|
202
|
+
messageIds,
|
|
203
|
+
receipt: result.receipt
|
|
204
|
+
});
|
|
205
|
+
if (opts.verbose) logVerbose(behavior.verboseMessage?.(chatId, messages.length) ?? `line: pushed ${messages.length} messages to ${chatId}`);
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
async function replyLineMessages(replyToken, messages, opts) {
|
|
209
|
+
const { account, token } = resolveLineMessagingAccount(opts);
|
|
210
|
+
return {
|
|
211
|
+
...resolveLineProviderMessageIds(await sendLineProviderMessages("reply", token, {
|
|
212
|
+
replyToken,
|
|
213
|
+
messages: messages.map(normalizeLineMessageActions)
|
|
214
|
+
}), "reply"),
|
|
215
|
+
accountId: account.accountId
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async function sendMessageLine(to, text, opts) {
|
|
219
|
+
const chatId = normalizeTarget(to);
|
|
220
|
+
const messages = [];
|
|
221
|
+
const mediaUrl = opts.mediaUrl?.trim();
|
|
222
|
+
if (mediaUrl) {
|
|
223
|
+
await validateLineMediaUrl(mediaUrl);
|
|
224
|
+
switch (opts.mediaKind) {
|
|
225
|
+
case "video": {
|
|
226
|
+
const previewImageUrl = opts.previewImageUrl?.trim();
|
|
227
|
+
if (!previewImageUrl) throw new Error("LINE video messages require previewImageUrl to reference an image URL");
|
|
228
|
+
await validateLineMediaUrl(previewImageUrl);
|
|
229
|
+
const trackingId = isLineUserChatId(chatId) ? opts.trackingId : void 0;
|
|
230
|
+
messages.push(createVideoMessage(mediaUrl, previewImageUrl, trackingId));
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case "audio":
|
|
234
|
+
messages.push(createAudioMessage(mediaUrl, opts.durationMs ?? 6e4));
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
{
|
|
238
|
+
const previewImageUrl = opts.previewImageUrl?.trim() || mediaUrl;
|
|
239
|
+
await validateLineMediaUrl(previewImageUrl);
|
|
240
|
+
messages.push(createImageMessage(mediaUrl, previewImageUrl));
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (text?.trim()) messages.push(createTextMessage(text.trim()));
|
|
246
|
+
if (messages.length === 0) throw new Error("Message must be non-empty for LINE sends");
|
|
247
|
+
if (opts.replyToken) {
|
|
248
|
+
const { messageId, messageIds, accountId } = await replyLineMessages(opts.replyToken, messages, opts);
|
|
249
|
+
const result = {
|
|
250
|
+
messageId,
|
|
251
|
+
chatId,
|
|
252
|
+
receipt: createLineSendReceipt({
|
|
253
|
+
messageId,
|
|
254
|
+
messageIds,
|
|
255
|
+
chatId,
|
|
256
|
+
kind: resolveLineReceiptKind(messages),
|
|
257
|
+
messageCount: messages.length
|
|
258
|
+
})
|
|
259
|
+
};
|
|
260
|
+
recordLineOutboundActivity(accountId, {
|
|
261
|
+
messageIds,
|
|
262
|
+
receipt: result.receipt
|
|
263
|
+
});
|
|
264
|
+
if (opts.verbose) logVerbose(`line: replied to ${chatId}`);
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
return pushLineMessages(chatId, messages, opts, { verboseMessage: (resolvedChatId) => `line: pushed message to ${resolvedChatId}` });
|
|
268
|
+
}
|
|
269
|
+
async function pushMessageLine(to, text, opts) {
|
|
270
|
+
return sendMessageLine(to, text, {
|
|
271
|
+
...opts,
|
|
272
|
+
replyToken: void 0
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
async function replyMessageLine(replyToken, messages, opts) {
|
|
276
|
+
const { messageIds, accountId } = await replyLineMessages(replyToken, messages, opts);
|
|
277
|
+
recordLineOutboundActivity(accountId, { messageIds });
|
|
278
|
+
if (opts.verbose) logVerbose(`line: replied with ${messages.length} messages`);
|
|
279
|
+
}
|
|
280
|
+
async function pushMessagesLine(to, messages, opts) {
|
|
281
|
+
return pushLineMessages(to, messages, opts, { errorContext: "push message" });
|
|
282
|
+
}
|
|
283
|
+
function createFlexMessage(altText, contents) {
|
|
284
|
+
return {
|
|
285
|
+
type: "flex",
|
|
286
|
+
altText: truncateUtf16Safe(altText, LINE_FLEX_ALT_TEXT_LIMIT),
|
|
287
|
+
contents
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
async function pushImageMessage(to, originalContentUrl, previewImageUrl, opts) {
|
|
291
|
+
await validateLineMediaUrl(originalContentUrl);
|
|
292
|
+
if (previewImageUrl) await validateLineMediaUrl(previewImageUrl);
|
|
293
|
+
return pushLineMessages(to, [createImageMessage(originalContentUrl, previewImageUrl)], opts, { verboseMessage: (chatId) => `line: pushed image to ${chatId}` });
|
|
294
|
+
}
|
|
295
|
+
async function pushLocationMessage(to, location, opts) {
|
|
296
|
+
const message = createLocationMessage(location);
|
|
297
|
+
if (!message) throw new Error("LINE location title and address must be non-empty");
|
|
298
|
+
return pushLineMessages(to, [message], opts, { verboseMessage: (chatId) => `line: pushed location to ${chatId}` });
|
|
299
|
+
}
|
|
300
|
+
async function pushFlexMessage(to, altText, contents, opts) {
|
|
301
|
+
return pushLineMessages(to, [createFlexMessage(altText, contents)], opts, {
|
|
302
|
+
errorContext: "push flex message",
|
|
303
|
+
verboseMessage: (chatId) => `line: pushed flex message to ${chatId}`
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
async function pushTemplateMessage(to, template, opts) {
|
|
307
|
+
return pushLineMessages(to, [template], opts, { verboseMessage: (chatId) => `line: pushed template message to ${chatId}` });
|
|
308
|
+
}
|
|
309
|
+
async function pushTextMessageWithQuickReplies(to, text, quickReplyLabels, opts) {
|
|
310
|
+
return pushLineMessages(to, [createTextMessageWithQuickReplies(text, quickReplyLabels)], opts, { verboseMessage: (chatId) => `line: pushed message with quick replies to ${chatId}` });
|
|
311
|
+
}
|
|
312
|
+
function createQuickReplyItems(labels) {
|
|
313
|
+
return { items: labels.slice(0, 13).map((label) => ({
|
|
314
|
+
type: "action",
|
|
315
|
+
action: messageAction(label, label)
|
|
316
|
+
})) };
|
|
317
|
+
}
|
|
318
|
+
function createTextMessageWithQuickReplies(text, quickReplyLabels) {
|
|
319
|
+
return {
|
|
320
|
+
type: "text",
|
|
321
|
+
text,
|
|
322
|
+
quickReply: createQuickReplyItems(quickReplyLabels)
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
async function showLoadingAnimation(chatId, opts) {
|
|
326
|
+
const { client } = createLineMessagingClient(opts);
|
|
327
|
+
try {
|
|
328
|
+
await client.showLoadingAnimation({
|
|
329
|
+
chatId: normalizeTarget(chatId),
|
|
330
|
+
loadingSeconds: opts.loadingSeconds ?? 20
|
|
331
|
+
});
|
|
332
|
+
logVerbose(`line: showing loading animation to ${chatId}`);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
logVerbose(`line: loading animation failed (non-fatal): ${String(err)}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
async function getUserProfile(userId, opts) {
|
|
338
|
+
if (opts.useCache ?? true) {
|
|
339
|
+
const cached = userProfileCache.get(userId);
|
|
340
|
+
if (cached && Date.now() - cached.fetchedAt < PROFILE_CACHE_TTL_MS) return {
|
|
341
|
+
displayName: cached.displayName,
|
|
342
|
+
pictureUrl: cached.pictureUrl
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
const { client } = createLineMessagingClient(opts);
|
|
346
|
+
try {
|
|
347
|
+
const profile = await client.getProfile(userId);
|
|
348
|
+
const result = {
|
|
349
|
+
displayName: profile.displayName,
|
|
350
|
+
pictureUrl: profile.pictureUrl
|
|
351
|
+
};
|
|
352
|
+
cacheUserProfile(userId, {
|
|
353
|
+
...result,
|
|
354
|
+
fetchedAt: Date.now()
|
|
355
|
+
});
|
|
356
|
+
return result;
|
|
357
|
+
} catch (err) {
|
|
358
|
+
logVerbose(`line: failed to fetch profile for ${userId}: ${String(err)}`);
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
async function getUserDisplayName(userId, opts) {
|
|
363
|
+
return (await getUserProfile(userId, opts))?.displayName ?? userId;
|
|
364
|
+
}
|
|
365
|
+
//#endregion
|
|
366
|
+
export { replyMessageLine as _, createQuickReplyItems as a, resolveLineChannelAccessToken as b, getUserDisplayName as c, pushImageMessage as d, pushLocationMessage as f, pushTextMessageWithQuickReplies as g, pushTemplateMessage as h, createLocationMessage as i, getUserProfile as l, pushMessagesLine as m, createFlexMessage as n, createTextMessageWithQuickReplies as o, pushMessageLine as p, createImageMessage as r, createVideoMessage as s, createAudioMessage as t, pushFlexMessage as u, sendMessageLine as v, showLoadingAnimation as y };
|
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-W0Dbgu58.js";
|
|
2
2
|
export { lineSetupAdapter, lineSetupWizard };
|
|
@@ -126,7 +126,8 @@ const lineSetupContract = defineChannelSetupContract({
|
|
|
126
126
|
cli: {
|
|
127
127
|
flags: "--use-env",
|
|
128
128
|
description: "Use LINE environment credentials"
|
|
129
|
-
}
|
|
129
|
+
},
|
|
130
|
+
envVars: ["LINE_CHANNEL_ACCESS_TOKEN", "LINE_CHANNEL_SECRET"]
|
|
130
131
|
}
|
|
131
132
|
},
|
|
132
133
|
legacyAdapter: lineSetupAdapter
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "line",
|
|
3
|
+
"doctorContract": {},
|
|
3
4
|
"name": "LINE",
|
|
4
5
|
"description": "OpenClaw LINE channel plugin for LINE Bot API chats.",
|
|
5
6
|
"icon": "https://cdn.simpleicons.org/line",
|
|
@@ -23,6 +24,9 @@
|
|
|
23
24
|
"enabled": {
|
|
24
25
|
"type": "boolean"
|
|
25
26
|
},
|
|
27
|
+
"configWrites": {
|
|
28
|
+
"type": "boolean"
|
|
29
|
+
},
|
|
26
30
|
"channelAccessToken": {
|
|
27
31
|
"type": "string"
|
|
28
32
|
},
|
|
@@ -168,6 +172,9 @@
|
|
|
168
172
|
"enabled": {
|
|
169
173
|
"type": "boolean"
|
|
170
174
|
},
|
|
175
|
+
"configWrites": {
|
|
176
|
+
"type": "boolean"
|
|
177
|
+
},
|
|
171
178
|
"channelAccessToken": {
|
|
172
179
|
"type": "string"
|
|
173
180
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/line",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.8.1-beta.2",
|
|
4
4
|
"description": "OpenClaw LINE channel plugin for LINE Bot API chats.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"zod": "4.4.3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.
|
|
15
|
+
"openclaw": ">=2026.8.1-beta.2"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
|
@@ -96,7 +96,11 @@
|
|
|
96
96
|
"cli": {
|
|
97
97
|
"flags": "--use-env",
|
|
98
98
|
"description": "Use LINE environment credentials"
|
|
99
|
-
}
|
|
99
|
+
},
|
|
100
|
+
"envVars": [
|
|
101
|
+
"LINE_CHANNEL_ACCESS_TOKEN",
|
|
102
|
+
"LINE_CHANNEL_SECRET"
|
|
103
|
+
]
|
|
100
104
|
}
|
|
101
105
|
]
|
|
102
106
|
}
|
|
@@ -107,10 +111,10 @@
|
|
|
107
111
|
"minHostVersion": ">=2026.4.10"
|
|
108
112
|
},
|
|
109
113
|
"compat": {
|
|
110
|
-
"pluginApi": ">=2026.
|
|
114
|
+
"pluginApi": ">=2026.8.1-beta.2"
|
|
111
115
|
},
|
|
112
116
|
"build": {
|
|
113
|
-
"openclawVersion": "2026.
|
|
117
|
+
"openclawVersion": "2026.8.1-beta.2"
|
|
114
118
|
},
|
|
115
119
|
"release": {
|
|
116
120
|
"publishToClawHub": true,
|