@openclaw/line 2026.7.2-beta.5 → 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.
Files changed (146) hide show
  1. package/dist/{accounts-CSH5sk8U.js → accounts-BqEVsDoB.js} +24 -88
  2. package/dist/api.js +2 -3
  3. package/dist/{card-command-BEMIm8D8.js → card-command-DALdUSnc.js} +14 -22
  4. package/dist/{channel-CTaWrzfl.js → channel-CAdQJRw7.js} +75 -77
  5. package/dist/channel-plugin-api.js +1 -1
  6. package/dist/channel.runtime-CuKoy9xw.js +4 -0
  7. package/dist/contract-api.js +1 -1
  8. package/dist/{flex-templates-DVy_wog4.js → flex-templates-BBBlNqpV.js} +108 -83
  9. package/dist/index.js +1 -1
  10. package/dist/markdown-to-line-D4I-6lm6.js +499 -0
  11. package/dist/{monitor-DzFU5UPV.js → monitor-QEh_ZqyR.js} +114 -94
  12. package/dist/monitor.runtime-72isajCp.js +2 -0
  13. package/dist/outbound.runtime-CWQMIE7N.js +3 -0
  14. package/dist/{reply-payload-transform-BRM2fRvK.js → reply-payload-transform-BOPGHVPo.js} +4 -3
  15. package/dist/runtime-api.js +9 -7
  16. package/dist/send-CFFr0-rZ.js +366 -0
  17. package/dist/setup-api.js +1 -1
  18. package/dist/{setup-surface-BHQOSD8R.js → setup-surface-W0Dbgu58.js} +51 -68
  19. package/openclaw.plugin.json +7 -0
  20. package/package.json +9 -5
  21. package/dist/channel.runtime-D4Paci2y.js +0 -4
  22. package/dist/markdown-to-line-Dn00k1bq.js +0 -799
  23. package/dist/monitor.runtime-B8xjVqev.js +0 -2
  24. package/dist/outbound.runtime-eHl7NNHu.js +0 -2
  25. package/dist/send-receipt-CY2ey8XH.js +0 -107
  26. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/LICENSE +0 -0
  27. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/README.md +0 -0
  28. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/assert/strict.d.ts +0 -0
  29. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/assert.d.ts +0 -0
  30. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/async_hooks.d.ts +0 -0
  31. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/buffer.buffer.d.ts +0 -0
  32. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/buffer.d.ts +0 -0
  33. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/child_process.d.ts +0 -0
  34. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/cluster.d.ts +0 -0
  35. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/compatibility/iterators.d.ts +0 -0
  36. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/console.d.ts +0 -0
  37. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/constants.d.ts +0 -0
  38. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/crypto.d.ts +0 -0
  39. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/dgram.d.ts +0 -0
  40. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/diagnostics_channel.d.ts +0 -0
  41. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/dns/promises.d.ts +0 -0
  42. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/dns.d.ts +0 -0
  43. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/domain.d.ts +0 -0
  44. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/events.d.ts +0 -0
  45. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/fs/promises.d.ts +0 -0
  46. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/fs.d.ts +0 -0
  47. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/globals.d.ts +0 -0
  48. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/globals.typedarray.d.ts +0 -0
  49. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/http.d.ts +0 -0
  50. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/http2.d.ts +0 -0
  51. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/https.d.ts +0 -0
  52. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/index.d.ts +0 -0
  53. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/inspector.d.ts +0 -0
  54. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/inspector.generated.d.ts +0 -0
  55. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/module.d.ts +0 -0
  56. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/net.d.ts +0 -0
  57. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/os.d.ts +0 -0
  58. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/package.json +0 -0
  59. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/path.d.ts +0 -0
  60. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/perf_hooks.d.ts +0 -0
  61. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/process.d.ts +0 -0
  62. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/punycode.d.ts +0 -0
  63. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/querystring.d.ts +0 -0
  64. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/readline/promises.d.ts +0 -0
  65. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/readline.d.ts +0 -0
  66. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/repl.d.ts +0 -0
  67. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/sea.d.ts +0 -0
  68. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/sqlite.d.ts +0 -0
  69. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/stream/consumers.d.ts +0 -0
  70. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/stream/promises.d.ts +0 -0
  71. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/stream/web.d.ts +0 -0
  72. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/stream.d.ts +0 -0
  73. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/string_decoder.d.ts +0 -0
  74. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/test.d.ts +0 -0
  75. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/timers/promises.d.ts +0 -0
  76. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/timers.d.ts +0 -0
  77. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/tls.d.ts +0 -0
  78. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/trace_events.d.ts +0 -0
  79. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.6/buffer.buffer.d.ts +0 -0
  80. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.6/compatibility/float16array.d.ts +0 -0
  81. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.6/globals.typedarray.d.ts +0 -0
  82. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.6/index.d.ts +0 -0
  83. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.7/compatibility/float16array.d.ts +0 -0
  84. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/ts5.7/index.d.ts +0 -0
  85. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/tty.d.ts +0 -0
  86. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/url.d.ts +0 -0
  87. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/util.d.ts +0 -0
  88. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/v8.d.ts +0 -0
  89. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/vm.d.ts +0 -0
  90. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/wasi.d.ts +0 -0
  91. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/abortcontroller.d.ts +0 -0
  92. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/crypto.d.ts +0 -0
  93. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/domexception.d.ts +0 -0
  94. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/events.d.ts +0 -0
  95. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/fetch.d.ts +0 -0
  96. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/navigator.d.ts +0 -0
  97. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/storage.d.ts +0 -0
  98. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/web-globals/streams.d.ts +0 -0
  99. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/worker_threads.d.ts +0 -0
  100. /package/node_modules/{@types → @line/bot-sdk/node_modules/@types}/node/zlib.d.ts +0 -0
  101. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/LICENSE +0 -0
  102. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/README.md +0 -0
  103. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/agent.d.ts +0 -0
  104. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/api.d.ts +0 -0
  105. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/balanced-pool.d.ts +0 -0
  106. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/cache-interceptor.d.ts +0 -0
  107. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/cache.d.ts +0 -0
  108. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/client-stats.d.ts +0 -0
  109. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/client.d.ts +0 -0
  110. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/connector.d.ts +0 -0
  111. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/content-type.d.ts +0 -0
  112. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/cookies.d.ts +0 -0
  113. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/diagnostics-channel.d.ts +0 -0
  114. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/dispatcher.d.ts +0 -0
  115. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/env-http-proxy-agent.d.ts +0 -0
  116. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/errors.d.ts +0 -0
  117. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/eventsource.d.ts +0 -0
  118. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/fetch.d.ts +0 -0
  119. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/formdata.d.ts +0 -0
  120. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/global-dispatcher.d.ts +0 -0
  121. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/global-origin.d.ts +0 -0
  122. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/h2c-client.d.ts +0 -0
  123. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/handlers.d.ts +0 -0
  124. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/header.d.ts +0 -0
  125. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/index.d.ts +0 -0
  126. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/interceptors.d.ts +0 -0
  127. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-agent.d.ts +0 -0
  128. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-call-history.d.ts +0 -0
  129. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-client.d.ts +0 -0
  130. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-errors.d.ts +0 -0
  131. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-interceptor.d.ts +0 -0
  132. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/mock-pool.d.ts +0 -0
  133. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/package.json +0 -0
  134. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/patch.d.ts +0 -0
  135. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/pool-stats.d.ts +0 -0
  136. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/pool.d.ts +0 -0
  137. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/proxy-agent.d.ts +0 -0
  138. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/readable.d.ts +0 -0
  139. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/retry-agent.d.ts +0 -0
  140. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/retry-handler.d.ts +0 -0
  141. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/round-robin-pool.d.ts +0 -0
  142. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/snapshot-agent.d.ts +0 -0
  143. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/util.d.ts +0 -0
  144. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/utility.d.ts +0 -0
  145. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/webidl.d.ts +0 -0
  146. /package/node_modules/{undici-types → @line/bot-sdk/node_modules/undici-types}/websocket.d.ts +0 -0
@@ -1,16 +1,18 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-CSH5sk8U.js";
1
+ import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BqEVsDoB.js";
2
2
  import { a as resolveLineGroupConfigEntry, i as resolveExactLineGroupConfigKey, o as resolveLineGroupLookupIds, r as setLineRuntime, s as resolveLineGroupsConfig } from "./quick-reply-fallback-D86FwAfr.js";
3
- import { i as LineConfigSchema, n as parseLineDirectives, r as LineChannelConfigSchema, t as hasLineDirectives } from "./reply-payload-transform-BRM2fRvK.js";
4
- import { _ as postbackAction, a as createEventCard, c as createCarousel, d as createListCard, f as createNotificationBubble, i as createAgendaCard, l as createImageCard, m as messageAction, n as createDeviceControlCard, o as createReceiptCard, p as datetimePickerAction, r as createMediaPlayerCard, s as createActionCard, t as createAppleTvRemoteCard, u as createInfoCard, v as uriAction } from "./flex-templates-DVy_wog4.js";
5
- import { A as createConfirmTemplate, C as sendMessageLine, D as createButtonMenu, E as buildTemplateMessageFromPayload, F as createTemplateCarousel, I as createYesNoConfirm, L as toFlexMessage, M as createImageCarouselColumn, N as createLinkMenu, O as createButtonTemplate, P as createProductCarousel, S as replyMessageLine, T as resolveLineChannelAccessToken, _ as pushLocationMessage, a as stripMarkdown, b as pushTemplateMessage, c as createImageMessage, d as createTextMessageWithQuickReplies, f as createVideoMessage, g as pushImageMessage, h as pushFlexMessage, i as processLineMessage, j as createImageCarousel, k as createCarouselColumn, l as createLocationMessage, m as getUserProfile, n as convertTableToFlexBubble, o as createAudioMessage, p as getUserDisplayName, r as hasMarkdownToConvert, s as createFlexMessage, t as convertCodeBlockToFlexBubble, u as createQuickReplyItems, v as pushMessageLine, w as showLoadingAnimation, x as pushTextMessageWithQuickReplies, y as pushMessagesLine } from "./markdown-to-line-Dn00k1bq.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-DzFU5UPV.js";
3
+ import { i as LineConfigSchema, n as parseLineDirectives, r as LineChannelConfigSchema, t as hasLineDirectives } from "./reply-payload-transform-BOPGHVPo.js";
4
+ import { a as createEventCard, c as createImageCard, d as datetimePickerAction, f as messageAction, g as uriAction, h as postbackAction, i as createAgendaCard, l as createInfoCard, n as createDeviceControlCard, o as createReceiptCard, r as createMediaPlayerCard, s as createActionCard, t as createAppleTvRemoteCard, u as createListCard } from "./flex-templates-BBBlNqpV.js";
5
+ import { a as stripMarkdown, c as createCarouselColumn, d as toFlexMessage, i as processLineMessage, l as createConfirmTemplate, n as convertTableToFlexBubble, o as buildTemplateMessageFromPayload, r as hasMarkdownToConvert, s as createButtonTemplate, t as convertCodeBlockToFlexBubble, u as createTemplateCarousel } from "./markdown-to-line-D4I-6lm6.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-QEh_ZqyR.js";
7
7
  import { t as probeLineBot } from "./probe-CM03wo6r.js";
8
+ import { _ as replyMessageLine, a as createQuickReplyItems, b as resolveLineChannelAccessToken, c as getUserDisplayName, d as pushImageMessage, f as pushLocationMessage, g as pushTextMessageWithQuickReplies, h as pushTemplateMessage, i as createLocationMessage, l as getUserProfile, m as pushMessagesLine, n as createFlexMessage, o as createTextMessageWithQuickReplies, p as pushMessageLine, r as createImageMessage, s as createVideoMessage, t as createAudioMessage, u as pushFlexMessage, v as sendMessageLine, y as showLoadingAnimation } from "./send-CFFr0-rZ.js";
8
9
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
9
10
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
10
11
  import { DEFAULT_ACCOUNT_ID, formatDocsLink, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
11
12
  import { buildComputedAccountStatusSnapshot, buildTokenChannelStatusSummary } from "openclaw/plugin-sdk/status-helpers";
12
13
  import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
13
14
  import { messagingApi } from "@line/bot-sdk";
15
+ import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
14
16
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
15
17
  import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
16
18
  import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
@@ -59,7 +61,7 @@ function createLineWebhookMiddleware(options) {
59
61
  }
60
62
  res.status(200).json({ status: "ok" });
61
63
  } catch (err) {
62
- runtime?.error?.(danger(`line webhook error: ${String(err)}`));
64
+ runtime?.error?.(danger(`line webhook error: ${formatErrorMessage(err)}`));
63
65
  if (!res.headersSent) res.status(500).json({ error: "Internal server error" });
64
66
  }
65
67
  };
@@ -257,4 +259,4 @@ function createDefaultMenuConfig() {
257
259
  };
258
260
  }
259
261
  //#endregion
260
- export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, 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, 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 };
262
+ export { DEFAULT_ACCOUNT_ID, LineChannelConfigSchema, LineConfigSchema, buildChannelConfigSchema, buildComputedAccountStatusSnapshot, buildTemplateMessageFromPayload, buildTokenChannelStatusSummary, cancelDefaultRichMenu, clearAccountEntryFields, convertCodeBlockToFlexBubble, convertTableToFlexBubble, createActionCard, createAgendaCard, createAppleTvRemoteCard, createAudioMessage, createButtonTemplate, createCarouselColumn, createConfirmTemplate, createDefaultMenuConfig, createDeviceControlCard, createEventCard, createFlexMessage, createGridLayout, createImageCard, createImageMessage, createInfoCard, createLineNodeWebhookHandler, createLineWebhookMiddleware, createListCard, createLocationMessage, createMediaPlayerCard, createQuickReplyItems, createReceiptCard, createRichMenu, createRichMenuAlias, createTemplateCarousel, createTextMessageWithQuickReplies, createVideoMessage, datetimePickerAction, deleteRichMenu, deleteRichMenuAlias, downloadLineMedia, 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 };
@@ -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-BHQOSD8R.js";
1
+ import { n as lineSetupAdapter, t as lineSetupWizard } from "./setup-surface-W0Dbgu58.js";
2
2
  export { lineSetupAdapter, lineSetupWizard };
@@ -1,4 +1,4 @@
1
- import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-CSH5sk8U.js";
1
+ import { i as resolveLineAccount, n as normalizeAccountId, r as resolveDefaultLineAccountId, t as listLineAccountIds } from "./accounts-BqEVsDoB.js";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
4
4
  import { DEFAULT_ACCOUNT_ID, createAllowFromSection, createPromptParsedAllowFromForAccount, createSetupInputPresenceValidator, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, parseSetupEntriesWithParser, patchScopedAccountConfig, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
@@ -61,26 +61,18 @@ const lineSetupAdapter = {
61
61
  const typedInput = input;
62
62
  const accessToken = typedInput.channelAccessToken ?? typedInput.token;
63
63
  const normalizedAccountId = normalizeAccountId(accountId);
64
- if (normalizedAccountId === DEFAULT_ACCOUNT_ID) return patchLineAccountConfig({
64
+ const useEnv = normalizedAccountId === DEFAULT_ACCOUNT_ID && Boolean(typedInput.useEnv);
65
+ return patchLineAccountConfig({
65
66
  cfg,
66
67
  accountId: normalizedAccountId,
67
68
  enabled: true,
68
- clearFields: typedInput.useEnv ? [
69
+ clearFields: useEnv ? [
69
70
  "channelAccessToken",
70
71
  "channelSecret",
71
72
  "tokenFile",
72
73
  "secretFile"
73
74
  ] : void 0,
74
- patch: typedInput.useEnv ? {} : {
75
- ...typedInput.tokenFile ? { tokenFile: typedInput.tokenFile } : accessToken ? { channelAccessToken: accessToken } : {},
76
- ...typedInput.secretFile ? { secretFile: typedInput.secretFile } : typedInput.channelSecret ? { channelSecret: typedInput.channelSecret } : {}
77
- }
78
- });
79
- return patchLineAccountConfig({
80
- cfg,
81
- accountId: normalizedAccountId,
82
- enabled: true,
83
- patch: {
75
+ patch: useEnv ? {} : {
84
76
  ...typedInput.tokenFile ? { tokenFile: typedInput.tokenFile } : accessToken ? { channelAccessToken: accessToken } : {},
85
77
  ...typedInput.secretFile ? { secretFile: typedInput.secretFile } : typedInput.channelSecret ? { channelSecret: typedInput.channelSecret } : {}
86
78
  }
@@ -134,7 +126,8 @@ const lineSetupContract = defineChannelSetupContract({
134
126
  cli: {
135
127
  flags: "--use-env",
136
128
  description: "Use LINE environment credentials"
137
- }
129
+ },
130
+ envVars: ["LINE_CHANNEL_ACCESS_TOKEN", "LINE_CHANNEL_SECRET"]
138
131
  }
139
132
  },
140
133
  legacyAdapter: lineSetupAdapter
@@ -195,6 +188,42 @@ const lineDmPolicy = createChannelDmPolicy({
195
188
  })
196
189
  })
197
190
  });
191
+ function createLineTokenCredential(params) {
192
+ return defineTokenCredential({
193
+ inputKey: params.inputKey,
194
+ configKey: params.configKey,
195
+ configuredFields: [params.configKey, params.fileKey],
196
+ providerHint: params.providerHint,
197
+ credentialLabel: params.credentialLabel,
198
+ preferredEnvVar: params.envVar,
199
+ helpTitle: t("wizard.line.messagingApiTitle"),
200
+ helpLines: LINE_SETUP_HELP_LINES,
201
+ envPrompt: params.envPrompt,
202
+ keepPrompt: params.keepPrompt,
203
+ inputPrompt: params.inputPrompt,
204
+ allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
205
+ resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
206
+ cfg,
207
+ accountId
208
+ }),
209
+ accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
210
+ hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config[params.configKey]) ?? normalizeOptionalString(account.config[params.fileKey])),
211
+ resolvedValue: (account) => normalizeOptionalString(account[params.configKey]),
212
+ envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env[params.envVar]) : void 0,
213
+ patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
214
+ cfg,
215
+ accountId,
216
+ enabled: true,
217
+ clearFields,
218
+ patch
219
+ }),
220
+ useEnv: { clearFields: [params.configKey, params.fileKey] },
221
+ set: {
222
+ clearFields: [params.fileKey],
223
+ value: "resolved"
224
+ }
225
+ });
226
+ }
198
227
  const lineSetupWizard = {
199
228
  channel,
200
229
  status: createStandardChannelSetupStatus({
@@ -214,72 +243,26 @@ const lineSetupWizard = {
214
243
  lines: LINE_SETUP_HELP_LINES,
215
244
  shouldShow: ({ cfg, accountId }) => !isLineConfigured(cfg, accountId ?? resolveDefaultLineAccountId(cfg))
216
245
  },
217
- credentials: [defineTokenCredential({
246
+ credentials: [createLineTokenCredential({
218
247
  inputKey: "token",
219
248
  configKey: "channelAccessToken",
220
- configuredFields: ["channelAccessToken", "tokenFile"],
249
+ fileKey: "tokenFile",
221
250
  providerHint: channel,
222
251
  credentialLabel: t("wizard.line.channelAccessToken"),
223
- preferredEnvVar: "LINE_CHANNEL_ACCESS_TOKEN",
224
- helpTitle: t("wizard.line.messagingApiTitle"),
225
- helpLines: LINE_SETUP_HELP_LINES,
252
+ envVar: "LINE_CHANNEL_ACCESS_TOKEN",
226
253
  envPrompt: t("wizard.line.tokenEnvPrompt"),
227
254
  keepPrompt: t("wizard.line.tokenKeepPrompt"),
228
- inputPrompt: t("wizard.line.tokenInputPrompt"),
229
- allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
230
- resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
231
- cfg,
232
- accountId
233
- }),
234
- accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
235
- hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelAccessToken) ?? normalizeOptionalString(account.config.tokenFile)),
236
- resolvedValue: (account) => normalizeOptionalString(account.channelAccessToken),
237
- envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_ACCESS_TOKEN) : void 0,
238
- patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
239
- cfg,
240
- accountId,
241
- enabled: true,
242
- clearFields,
243
- patch
244
- }),
245
- useEnv: { clearFields: ["channelAccessToken", "tokenFile"] },
246
- set: {
247
- clearFields: ["tokenFile"],
248
- value: "resolved"
249
- }
250
- }), defineTokenCredential({
255
+ inputPrompt: t("wizard.line.tokenInputPrompt")
256
+ }), createLineTokenCredential({
251
257
  inputKey: "password",
252
258
  configKey: "channelSecret",
253
- configuredFields: ["channelSecret", "secretFile"],
259
+ fileKey: "secretFile",
254
260
  providerHint: "line-secret",
255
261
  credentialLabel: t("wizard.line.channelSecret"),
256
- preferredEnvVar: "LINE_CHANNEL_SECRET",
257
- helpTitle: t("wizard.line.messagingApiTitle"),
258
- helpLines: LINE_SETUP_HELP_LINES,
262
+ envVar: "LINE_CHANNEL_SECRET",
259
263
  envPrompt: t("wizard.line.secretEnvPrompt"),
260
264
  keepPrompt: t("wizard.line.secretKeepPrompt"),
261
- inputPrompt: t("wizard.line.secretInputPrompt"),
262
- allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
263
- resolveAccount: ({ cfg, accountId }) => resolveLineAccount({
264
- cfg,
265
- accountId
266
- }),
267
- accountConfigured: (account) => Boolean(normalizeOptionalString(account.channelAccessToken) && normalizeOptionalString(account.channelSecret)),
268
- hasConfiguredValue: (account) => Boolean(normalizeOptionalString(account.config.channelSecret) ?? normalizeOptionalString(account.config.secretFile)),
269
- resolvedValue: (account) => normalizeOptionalString(account.channelSecret),
270
- envValue: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env.LINE_CHANNEL_SECRET) : void 0,
271
- patchAccount: ({ cfg, accountId, patch, clearFields }) => patchLineAccountConfig({
272
- cfg,
273
- accountId,
274
- enabled: true,
275
- clearFields,
276
- patch
277
- }),
278
- useEnv: { clearFields: ["channelSecret", "secretFile"] },
279
- set: {
280
- clearFields: ["secretFile"],
281
- value: "resolved"
282
- }
265
+ inputPrompt: t("wizard.line.secretInputPrompt")
283
266
  })],
284
267
  allowFrom: createAllowFromSection({
285
268
  helpTitle: t("wizard.line.allowlistTitle"),
@@ -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.7.2-beta.5",
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.7.2-beta.5"
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.7.2-beta.5"
114
+ "pluginApi": ">=2026.8.1-beta.2"
111
115
  },
112
116
  "build": {
113
- "openclawVersion": "2026.7.2-beta.5"
117
+ "openclawVersion": "2026.8.1-beta.2"
114
118
  },
115
119
  "release": {
116
120
  "publishToClawHub": true,
@@ -1,4 +0,0 @@
1
- import { v as pushMessageLine } from "./markdown-to-line-Dn00k1bq.js";
2
- import { t as monitorLineProvider } from "./monitor-DzFU5UPV.js";
3
- import { t as probeLineBot } from "./probe-CM03wo6r.js";
4
- export { monitorLineProvider, probeLineBot, pushMessageLine };