@openclaw/line 2026.6.8 → 2026.6.9

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-BGjcdz8g.js";
1
+ import { n as lineChannelPluginCommon, t as linePlugin } from "./channel-DnBQa9Fv.js";
2
2
  import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-CvTRDCEq.js";
3
3
  //#region extensions/line/src/channel.setup.ts
4
4
  const lineSetupPlugin = {
@@ -107,7 +107,7 @@ const lineChannelPluginCommon = {
107
107
  //#endregion
108
108
  //#region extensions/line/src/gateway.ts
109
109
  const loadLineProbeRuntime$1 = createLazyRuntimeModule(() => import("./probe.runtime-DH_jgr7u.js"));
110
- const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-Clh5l7po.js"));
110
+ const loadLineMonitorRuntime = createLazyRuntimeModule(() => import("./monitor.runtime-CGCy-kYV.js"));
111
111
  const lineGatewayAdapter = {
112
112
  startAccount: async (ctx) => {
113
113
  const account = ctx.account;
@@ -211,7 +211,7 @@ function resolveLineGroupRequireMention(params) {
211
211
  }
212
212
  //#endregion
213
213
  //#region extensions/line/src/outbound.ts
214
- const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-Cek6jqnb.js"));
214
+ const loadLineOutboundRuntime = createLazyRuntimeModule(() => import("./outbound.runtime-Cx3rgMAH.js"));
215
215
  function isLineUserTarget(target) {
216
216
  const normalized = target.trim().replace(/^line:(group|room|user):/i, "").replace(/^line:/i, "");
217
217
  return /^U/i.test(normalized);
@@ -532,7 +532,7 @@ const lineStatusAdapter = createComputedAccountStatusAdapter({
532
532
  });
533
533
  //#endregion
534
534
  //#region extensions/line/src/channel.ts
535
- const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-DUau3ksl.js"));
535
+ const loadLineChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-C-kKPoMb.js"));
536
536
  const lineSecurityAdapter = createRestrictSendersChannelSecurity({
537
537
  channelKey: "line",
538
538
  resolveDmPolicy: (account) => account.config.dmPolicy,
@@ -1,2 +1,2 @@
1
- import { t as linePlugin } from "./channel-BGjcdz8g.js";
1
+ import { t as linePlugin } from "./channel-DnBQa9Fv.js";
2
2
  export { linePlugin };
@@ -0,0 +1,4 @@
1
+ import { S as pushMessageLine } from "./markdown-to-line-juqp-iiY.js";
2
+ import { t as monitorLineProvider } from "./monitor-CULIHcvR.js";
3
+ import { t as probeLineBot } from "./probe-CqTNoMdZ.js";
4
+ export { monitorLineProvider, probeLineBot, pushMessageLine };
@@ -66,11 +66,36 @@ function datetimePickerAction(label, data, mode, options) {
66
66
  }
67
67
  //#endregion
68
68
  //#region extensions/line/src/template-messages.ts
69
+ const COMPACT_TEMPLATE_TEXT_LIMIT = 60;
70
+ const graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
69
71
  function buildTemplatePayloadAction(action) {
70
72
  if (action.type === "uri" && action.uri) return uriAction(action.label, action.uri);
71
73
  if (action.type === "postback" && action.data) return postbackAction(action.label, action.data, action.label);
72
74
  return messageAction(action.label, action.data ?? action.label);
73
75
  }
76
+ function resolveTemplateTextLimit(params) {
77
+ return params.title !== void 0 || params.thumbnailImageUrl !== void 0 ? COMPACT_TEMPLATE_TEXT_LIMIT : params.textOnlyLimit;
78
+ }
79
+ function truncateTemplateText(text, limit) {
80
+ let result = "";
81
+ for (const { segment } of graphemeSegmenter.segment(text)) {
82
+ if (result.length + segment.length > limit) {
83
+ if (!result) for (const codePoint of segment) {
84
+ if (result.length + codePoint.length > limit) break;
85
+ result += codePoint;
86
+ }
87
+ break;
88
+ }
89
+ result += segment;
90
+ }
91
+ return result;
92
+ }
93
+ function formatProductCarouselText(description, price) {
94
+ if (!price) return description;
95
+ const priceText = truncateTemplateText(price, COMPACT_TEMPLATE_TEXT_LIMIT);
96
+ const descriptionText = truncateTemplateText(description, Math.max(0, COMPACT_TEMPLATE_TEXT_LIMIT - priceText.length - 1));
97
+ return descriptionText ? `${descriptionText}\n${priceText}` : priceText;
98
+ }
74
99
  /**
75
100
  * Create a confirm template (yes/no style dialog)
76
101
  */
@@ -90,11 +115,15 @@ function createConfirmTemplate(text, confirmAction, cancelAction, altText) {
90
115
  * Create a button template with title, text, and action buttons
91
116
  */
92
117
  function createButtonTemplate(title, text, actions, options) {
93
- const textLimit = Boolean(options?.thumbnailImageUrl?.trim()) ? 160 : 60;
118
+ const textLimit = resolveTemplateTextLimit({
119
+ title,
120
+ thumbnailImageUrl: options?.thumbnailImageUrl,
121
+ textOnlyLimit: 160
122
+ });
94
123
  const template = {
95
124
  type: "buttons",
96
125
  title: title.slice(0, 40),
97
- text: text.slice(0, textLimit),
126
+ text: truncateTemplateText(text, textLimit),
98
127
  actions: actions.slice(0, 4),
99
128
  thumbnailImageUrl: options?.thumbnailImageUrl,
100
129
  imageAspectRatio: options?.imageAspectRatio ?? "rectangle",
@@ -128,9 +157,13 @@ function createTemplateCarousel(columns, options) {
128
157
  * Create a carousel column for use with createTemplateCarousel
129
158
  */
130
159
  function createCarouselColumn(params) {
160
+ const textLimit = resolveTemplateTextLimit({
161
+ ...params,
162
+ textOnlyLimit: 120
163
+ });
131
164
  return {
132
165
  title: params.title?.slice(0, 40),
133
- text: params.text.slice(0, 120),
166
+ text: truncateTemplateText(params.text, textLimit),
134
167
  actions: params.actions.slice(0, 3),
135
168
  thumbnailImageUrl: params.thumbnailImageUrl,
136
169
  imageBackgroundColor: params.imageBackgroundColor,
@@ -195,7 +228,7 @@ function createProductCarousel(products, altText) {
195
228
  else actions.push(messageAction(product.actionLabel ?? "Select", product.title));
196
229
  return createCarouselColumn({
197
230
  title: product.title,
198
- text: product.price ? `${product.description}\n${product.price}`.slice(0, 120) : product.description,
231
+ text: formatProductCarouselText(product.description, product.price),
199
232
  thumbnailImageUrl: product.imageUrl,
200
233
  actions
201
234
  });
@@ -1,6 +1,6 @@
1
1
  import { i as resolveLineAccount, r as resolveDefaultLineAccountId } from "./accounts-B-K3yrdP.js";
2
2
  import { h as resolveLineGroupConfigEntry, s as buildLineQuickReplyFallbackText, u as getLineRuntime } from "./reply-payload-transform-DZ8-37Ot.js";
3
- import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, E as replyMessageLine, O as showLoadingAnimation, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, c as processLineMessage, d as createFlexMessage, f as createImageMessage, h as createTextMessageWithQuickReplies, m as createQuickReplyItems, p as createLocationMessage } from "./markdown-to-line-D-1nDsie.js";
3
+ import { A as buildTemplateMessageFromPayload, C as pushMessagesLine, E as replyMessageLine, O as showLoadingAnimation, S as pushMessageLine, T as pushTextMessageWithQuickReplies, _ as getUserDisplayName, c as processLineMessage, d as createFlexMessage, f as createImageMessage, h as createTextMessageWithQuickReplies, m as createQuickReplyItems, p as createLocationMessage } from "./markdown-to-line-juqp-iiY.js";
4
4
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
5
5
  import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { createMessageReceiveContext } from "openclaw/plugin-sdk/channel-outbound";
@@ -1218,14 +1218,6 @@ async function monitorLineProvider(opts) {
1218
1218
  const secret = channelSecret.trim();
1219
1219
  if (!token) throw new Error("LINE webhook mode requires a non-empty channel access token.");
1220
1220
  if (!secret) throw new Error("LINE webhook mode requires a non-empty channel secret.");
1221
- recordChannelRuntimeState({
1222
- channel: "line",
1223
- accountId: resolvedAccountId,
1224
- state: {
1225
- running: true,
1226
- lastStartAt: Date.now()
1227
- }
1228
- });
1229
1221
  const bot = createLineBot({
1230
1222
  channelAccessToken: token,
1231
1223
  channelSecret: secret,
@@ -1458,6 +1450,14 @@ async function monitorLineProvider(opts) {
1458
1450
  }
1459
1451
  }
1460
1452
  });
1453
+ recordChannelRuntimeState({
1454
+ channel: "line",
1455
+ accountId: resolvedAccountId,
1456
+ state: {
1457
+ running: true,
1458
+ lastStartAt: Date.now()
1459
+ }
1460
+ });
1461
1461
  logVerbose(`line: registered webhook handler at ${normalizedPath}`);
1462
1462
  let stopped = false;
1463
1463
  const stopHandler = () => {
@@ -0,0 +1,2 @@
1
+ import { t as monitorLineProvider } from "./monitor-CULIHcvR.js";
2
+ export { monitorLineProvider };
@@ -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-D-1nDsie.js";
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-juqp-iiY.js";
2
2
  export { buildTemplateMessageFromPayload, createQuickReplyItems, processLineMessage, pushFlexMessage, pushLocationMessage, pushMessageLine, pushMessagesLine, pushTemplateMessage, pushTextMessageWithQuickReplies, sendMessageLine };
@@ -2,8 +2,8 @@ import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLi
2
2
  import { _ as resolveLineGroupsConfig, a as createMediaPlayerCard, d as setLineRuntime, f as LineChannelConfigSchema, g as resolveLineGroupLookupIds, h as resolveLineGroupConfigEntry, i as createDeviceControlCard, m as resolveExactLineGroupConfigKey, n as parseLineDirectives, p as LineConfigSchema, r as createAppleTvRemoteCard, t as hasLineDirectives } from "./reply-payload-transform-DZ8-37Ot.js";
3
3
  import { n as createEventCard, r as createReceiptCard, t as createAgendaCard } from "./schedule-cards-Bq74H30B.js";
4
4
  import { a as createListCard, i as createInfoCard, n as createCarousel, o as createNotificationBubble, r as createImageCard, t as createActionCard } from "./basic-cards-B1eTkw-f.js";
5
- import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, G as toFlexMessage, H as messageAction, 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, U as postbackAction, V as datetimePickerAction, W as uriAction, _ 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-D-1nDsie.js";
6
- 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-qY3gstaZ.js";
5
+ import { A as buildTemplateMessageFromPayload, B as createYesNoConfirm, C as pushMessagesLine, D as sendMessageLine, E as replyMessageLine, F as createImageCarousel, G as toFlexMessage, H as messageAction, 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, U as postbackAction, V as datetimePickerAction, W as uriAction, _ 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-juqp-iiY.js";
6
+ 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-CULIHcvR.js";
7
7
  import { t as probeLineBot } from "./probe-CqTNoMdZ.js";
8
8
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
9
9
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@openclaw/line",
3
- "version": "2026.6.8",
3
+ "version": "2026.6.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/line",
9
- "version": "2026.6.8",
9
+ "version": "2026.6.9",
10
10
  "dependencies": {
11
11
  "@line/bot-sdk": "11.0.1",
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.6.8"
15
+ "openclaw": ">=2026.6.9"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/line",
3
- "version": "2026.6.8",
3
+ "version": "2026.6.9",
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.6.8"
15
+ "openclaw": ">=2026.6.9"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -42,10 +42,10 @@
42
42
  "minHostVersion": ">=2026.4.10"
43
43
  },
44
44
  "compat": {
45
- "pluginApi": ">=2026.6.8"
45
+ "pluginApi": ">=2026.6.9"
46
46
  },
47
47
  "build": {
48
- "openclawVersion": "2026.6.8"
48
+ "openclawVersion": "2026.6.9"
49
49
  },
50
50
  "release": {
51
51
  "publishToClawHub": true,
@@ -1,4 +0,0 @@
1
- import { S as pushMessageLine } from "./markdown-to-line-D-1nDsie.js";
2
- import { t as monitorLineProvider } from "./monitor-qY3gstaZ.js";
3
- import { t as probeLineBot } from "./probe-CqTNoMdZ.js";
4
- export { monitorLineProvider, probeLineBot, pushMessageLine };
@@ -1,2 +0,0 @@
1
- import { t as monitorLineProvider } from "./monitor-qY3gstaZ.js";
2
- export { monitorLineProvider };