@openclaw/line 2026.5.2-beta.1

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 (86) hide show
  1. package/api.ts +11 -0
  2. package/channel-plugin-api.ts +1 -0
  3. package/contract-api.ts +5 -0
  4. package/index.ts +54 -0
  5. package/openclaw.plugin.json +342 -0
  6. package/package.json +58 -0
  7. package/runtime-api.ts +187 -0
  8. package/secret-contract-api.ts +4 -0
  9. package/setup-api.ts +2 -0
  10. package/setup-entry.ts +9 -0
  11. package/src/account-helpers.ts +16 -0
  12. package/src/accounts.test.ts +290 -0
  13. package/src/accounts.ts +187 -0
  14. package/src/actions.ts +61 -0
  15. package/src/auto-reply-delivery.test.ts +248 -0
  16. package/src/auto-reply-delivery.ts +200 -0
  17. package/src/bindings.ts +65 -0
  18. package/src/bot-access.ts +48 -0
  19. package/src/bot-handlers.test.ts +1089 -0
  20. package/src/bot-handlers.ts +642 -0
  21. package/src/bot-message-context.test.ts +405 -0
  22. package/src/bot-message-context.ts +581 -0
  23. package/src/bot.ts +70 -0
  24. package/src/card-command.ts +347 -0
  25. package/src/channel-access-token.ts +14 -0
  26. package/src/channel-api.ts +17 -0
  27. package/src/channel-setup-status.contract.test.ts +70 -0
  28. package/src/channel-shared.ts +48 -0
  29. package/src/channel.logout.test.ts +145 -0
  30. package/src/channel.runtime.ts +3 -0
  31. package/src/channel.sendPayload.test.ts +514 -0
  32. package/src/channel.setup.ts +11 -0
  33. package/src/channel.status.test.ts +63 -0
  34. package/src/channel.ts +154 -0
  35. package/src/config-adapter.ts +29 -0
  36. package/src/config-schema.ts +57 -0
  37. package/src/download.test.ts +133 -0
  38. package/src/download.ts +87 -0
  39. package/src/flex-templates/basic-cards.ts +395 -0
  40. package/src/flex-templates/common.ts +20 -0
  41. package/src/flex-templates/media-control-cards.ts +555 -0
  42. package/src/flex-templates/message.ts +13 -0
  43. package/src/flex-templates/schedule-cards.ts +467 -0
  44. package/src/flex-templates/types.ts +22 -0
  45. package/src/flex-templates.ts +32 -0
  46. package/src/gateway.ts +129 -0
  47. package/src/group-keys.test.ts +123 -0
  48. package/src/group-keys.ts +65 -0
  49. package/src/group-policy.ts +22 -0
  50. package/src/markdown-to-line.test.ts +348 -0
  51. package/src/markdown-to-line.ts +416 -0
  52. package/src/message-cards.test.ts +204 -0
  53. package/src/monitor.lifecycle.test.ts +421 -0
  54. package/src/monitor.runtime.ts +1 -0
  55. package/src/monitor.ts +506 -0
  56. package/src/outbound-media.test.ts +189 -0
  57. package/src/outbound-media.ts +120 -0
  58. package/src/outbound.runtime.ts +12 -0
  59. package/src/outbound.ts +356 -0
  60. package/src/probe.contract.test.ts +9 -0
  61. package/src/probe.runtime.ts +1 -0
  62. package/src/probe.ts +34 -0
  63. package/src/quick-reply-fallback.ts +10 -0
  64. package/src/reply-chunks.test.ts +179 -0
  65. package/src/reply-chunks.ts +110 -0
  66. package/src/reply-payload-transform.test.ts +387 -0
  67. package/src/reply-payload-transform.ts +317 -0
  68. package/src/rich-menu.test.ts +310 -0
  69. package/src/rich-menu.ts +326 -0
  70. package/src/runtime.ts +32 -0
  71. package/src/send.test.ts +346 -0
  72. package/src/send.ts +489 -0
  73. package/src/setup-core.ts +149 -0
  74. package/src/setup-runtime-api.ts +9 -0
  75. package/src/setup-surface.test.ts +474 -0
  76. package/src/setup-surface.ts +227 -0
  77. package/src/signature.test.ts +34 -0
  78. package/src/signature.ts +24 -0
  79. package/src/status.ts +37 -0
  80. package/src/template-messages.ts +333 -0
  81. package/src/types.ts +128 -0
  82. package/src/webhook-node.test.ts +513 -0
  83. package/src/webhook-node.ts +131 -0
  84. package/src/webhook-utils.ts +10 -0
  85. package/src/webhook.ts +111 -0
  86. package/tsconfig.json +16 -0
package/api.ts ADDED
@@ -0,0 +1,11 @@
1
+ export type {
2
+ ChannelAccountSnapshot,
3
+ ChannelPlugin,
4
+ OpenClawConfig,
5
+ OpenClawPluginApi,
6
+ PluginRuntime,
7
+ } from "openclaw/plugin-sdk/core";
8
+ export type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
9
+ export type { ResolvedLineAccount } from "./runtime-api.js";
10
+ export { linePlugin } from "./src/channel.js";
11
+ export { lineSetupPlugin } from "./src/channel.setup.js";
@@ -0,0 +1 @@
1
+ export { linePlugin } from "./src/channel.js";
@@ -0,0 +1,5 @@
1
+ export {
2
+ listLineAccountIds,
3
+ resolveDefaultLineAccountId,
4
+ resolveLineAccount,
5
+ } from "./src/accounts.js";
package/index.ts ADDED
@@ -0,0 +1,54 @@
1
+ import {
2
+ defineBundledChannelEntry,
3
+ type OpenClawPluginCommandDefinition,
4
+ type OpenClawPluginApi,
5
+ } from "openclaw/plugin-sdk/channel-entry-contract";
6
+
7
+ type RegisteredLineCardCommand = OpenClawPluginCommandDefinition;
8
+
9
+ let lineCardCommandPromise: Promise<RegisteredLineCardCommand> | null = null;
10
+
11
+ async function loadLineCardCommand(api: OpenClawPluginApi): Promise<RegisteredLineCardCommand> {
12
+ lineCardCommandPromise ??= (async () => {
13
+ let registered: RegisteredLineCardCommand | null = null;
14
+ const { registerLineCardCommand } = await import("./src/card-command.js");
15
+ registerLineCardCommand({
16
+ ...api,
17
+ registerCommand(command: RegisteredLineCardCommand) {
18
+ registered = command;
19
+ },
20
+ });
21
+ if (!registered) {
22
+ throw new Error("LINE card command registration unavailable");
23
+ }
24
+ return registered;
25
+ })();
26
+ return await lineCardCommandPromise;
27
+ }
28
+
29
+ export default defineBundledChannelEntry({
30
+ id: "line",
31
+ name: "LINE",
32
+ description: "LINE Messaging API channel plugin",
33
+ importMetaUrl: import.meta.url,
34
+ plugin: {
35
+ specifier: "./channel-plugin-api.js",
36
+ exportName: "linePlugin",
37
+ },
38
+ runtime: {
39
+ specifier: "./runtime-api.js",
40
+ exportName: "setLineRuntime",
41
+ },
42
+ registerFull(api) {
43
+ api.registerCommand({
44
+ name: "card",
45
+ description: "Send a rich card message (LINE).",
46
+ acceptsArgs: true,
47
+ requireAuth: false,
48
+ async handler(ctx) {
49
+ const command = await loadLineCardCommand(api);
50
+ return await command.handler(ctx);
51
+ },
52
+ });
53
+ },
54
+ });
@@ -0,0 +1,342 @@
1
+ {
2
+ "id": "line",
3
+ "activation": {
4
+ "onStartup": false
5
+ },
6
+ "channels": [
7
+ "line"
8
+ ],
9
+ "channelEnvVars": {
10
+ "line": [
11
+ "LINE_CHANNEL_ACCESS_TOKEN",
12
+ "LINE_CHANNEL_SECRET"
13
+ ]
14
+ },
15
+ "configSchema": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "properties": {}
19
+ },
20
+ "channelConfigs": {
21
+ "line": {
22
+ "schema": {
23
+ "$schema": "http://json-schema.org/draft-07/schema#",
24
+ "type": "object",
25
+ "properties": {
26
+ "enabled": {
27
+ "type": "boolean"
28
+ },
29
+ "channelAccessToken": {
30
+ "type": "string"
31
+ },
32
+ "channelSecret": {
33
+ "type": "string"
34
+ },
35
+ "tokenFile": {
36
+ "type": "string"
37
+ },
38
+ "secretFile": {
39
+ "type": "string"
40
+ },
41
+ "name": {
42
+ "type": "string"
43
+ },
44
+ "allowFrom": {
45
+ "type": "array",
46
+ "items": {
47
+ "anyOf": [
48
+ {
49
+ "type": "string"
50
+ },
51
+ {
52
+ "type": "number"
53
+ }
54
+ ]
55
+ }
56
+ },
57
+ "groupAllowFrom": {
58
+ "type": "array",
59
+ "items": {
60
+ "anyOf": [
61
+ {
62
+ "type": "string"
63
+ },
64
+ {
65
+ "type": "number"
66
+ }
67
+ ]
68
+ }
69
+ },
70
+ "dmPolicy": {
71
+ "default": "pairing",
72
+ "type": "string",
73
+ "enum": [
74
+ "open",
75
+ "allowlist",
76
+ "pairing",
77
+ "disabled"
78
+ ]
79
+ },
80
+ "groupPolicy": {
81
+ "default": "allowlist",
82
+ "type": "string",
83
+ "enum": [
84
+ "open",
85
+ "allowlist",
86
+ "disabled"
87
+ ]
88
+ },
89
+ "responsePrefix": {
90
+ "type": "string"
91
+ },
92
+ "mediaMaxMb": {
93
+ "type": "number"
94
+ },
95
+ "webhookPath": {
96
+ "type": "string"
97
+ },
98
+ "threadBindings": {
99
+ "type": "object",
100
+ "properties": {
101
+ "enabled": {
102
+ "type": "boolean"
103
+ },
104
+ "idleHours": {
105
+ "type": "number"
106
+ },
107
+ "maxAgeHours": {
108
+ "type": "number"
109
+ },
110
+ "spawnSessions": {
111
+ "type": "boolean"
112
+ },
113
+ "defaultSpawnContext": {
114
+ "type": "string",
115
+ "enum": [
116
+ "isolated",
117
+ "fork"
118
+ ]
119
+ },
120
+ "spawnSubagentSessions": {
121
+ "type": "boolean"
122
+ },
123
+ "spawnAcpSessions": {
124
+ "type": "boolean"
125
+ }
126
+ },
127
+ "additionalProperties": false
128
+ },
129
+ "accounts": {
130
+ "type": "object",
131
+ "propertyNames": {
132
+ "type": "string"
133
+ },
134
+ "additionalProperties": {
135
+ "type": "object",
136
+ "properties": {
137
+ "enabled": {
138
+ "type": "boolean"
139
+ },
140
+ "channelAccessToken": {
141
+ "type": "string"
142
+ },
143
+ "channelSecret": {
144
+ "type": "string"
145
+ },
146
+ "tokenFile": {
147
+ "type": "string"
148
+ },
149
+ "secretFile": {
150
+ "type": "string"
151
+ },
152
+ "name": {
153
+ "type": "string"
154
+ },
155
+ "allowFrom": {
156
+ "type": "array",
157
+ "items": {
158
+ "anyOf": [
159
+ {
160
+ "type": "string"
161
+ },
162
+ {
163
+ "type": "number"
164
+ }
165
+ ]
166
+ }
167
+ },
168
+ "groupAllowFrom": {
169
+ "type": "array",
170
+ "items": {
171
+ "anyOf": [
172
+ {
173
+ "type": "string"
174
+ },
175
+ {
176
+ "type": "number"
177
+ }
178
+ ]
179
+ }
180
+ },
181
+ "dmPolicy": {
182
+ "default": "pairing",
183
+ "type": "string",
184
+ "enum": [
185
+ "open",
186
+ "allowlist",
187
+ "pairing",
188
+ "disabled"
189
+ ]
190
+ },
191
+ "groupPolicy": {
192
+ "default": "allowlist",
193
+ "type": "string",
194
+ "enum": [
195
+ "open",
196
+ "allowlist",
197
+ "disabled"
198
+ ]
199
+ },
200
+ "responsePrefix": {
201
+ "type": "string"
202
+ },
203
+ "mediaMaxMb": {
204
+ "type": "number"
205
+ },
206
+ "webhookPath": {
207
+ "type": "string"
208
+ },
209
+ "threadBindings": {
210
+ "type": "object",
211
+ "properties": {
212
+ "enabled": {
213
+ "type": "boolean"
214
+ },
215
+ "idleHours": {
216
+ "type": "number"
217
+ },
218
+ "maxAgeHours": {
219
+ "type": "number"
220
+ },
221
+ "spawnSessions": {
222
+ "type": "boolean"
223
+ },
224
+ "defaultSpawnContext": {
225
+ "type": "string",
226
+ "enum": [
227
+ "isolated",
228
+ "fork"
229
+ ]
230
+ },
231
+ "spawnSubagentSessions": {
232
+ "type": "boolean"
233
+ },
234
+ "spawnAcpSessions": {
235
+ "type": "boolean"
236
+ }
237
+ },
238
+ "additionalProperties": false
239
+ },
240
+ "groups": {
241
+ "type": "object",
242
+ "propertyNames": {
243
+ "type": "string"
244
+ },
245
+ "additionalProperties": {
246
+ "type": "object",
247
+ "properties": {
248
+ "enabled": {
249
+ "type": "boolean"
250
+ },
251
+ "allowFrom": {
252
+ "type": "array",
253
+ "items": {
254
+ "anyOf": [
255
+ {
256
+ "type": "string"
257
+ },
258
+ {
259
+ "type": "number"
260
+ }
261
+ ]
262
+ }
263
+ },
264
+ "requireMention": {
265
+ "type": "boolean"
266
+ },
267
+ "systemPrompt": {
268
+ "type": "string"
269
+ },
270
+ "skills": {
271
+ "type": "array",
272
+ "items": {
273
+ "type": "string"
274
+ }
275
+ }
276
+ },
277
+ "additionalProperties": false
278
+ }
279
+ }
280
+ },
281
+ "required": [
282
+ "dmPolicy",
283
+ "groupPolicy"
284
+ ],
285
+ "additionalProperties": false
286
+ }
287
+ },
288
+ "defaultAccount": {
289
+ "type": "string"
290
+ },
291
+ "groups": {
292
+ "type": "object",
293
+ "propertyNames": {
294
+ "type": "string"
295
+ },
296
+ "additionalProperties": {
297
+ "type": "object",
298
+ "properties": {
299
+ "enabled": {
300
+ "type": "boolean"
301
+ },
302
+ "allowFrom": {
303
+ "type": "array",
304
+ "items": {
305
+ "anyOf": [
306
+ {
307
+ "type": "string"
308
+ },
309
+ {
310
+ "type": "number"
311
+ }
312
+ ]
313
+ }
314
+ },
315
+ "requireMention": {
316
+ "type": "boolean"
317
+ },
318
+ "systemPrompt": {
319
+ "type": "string"
320
+ },
321
+ "skills": {
322
+ "type": "array",
323
+ "items": {
324
+ "type": "string"
325
+ }
326
+ }
327
+ },
328
+ "additionalProperties": false
329
+ }
330
+ }
331
+ },
332
+ "required": [
333
+ "dmPolicy",
334
+ "groupPolicy"
335
+ ],
336
+ "additionalProperties": false
337
+ },
338
+ "label": "LINE",
339
+ "description": "LINE Messaging API webhook bot."
340
+ }
341
+ }
342
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@openclaw/line",
3
+ "version": "2026.5.2-beta.1",
4
+ "description": "OpenClaw LINE channel plugin",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/openclaw/openclaw"
8
+ },
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@line/bot-sdk": "^11.0.0"
12
+ },
13
+ "devDependencies": {
14
+ "@openclaw/plugin-sdk": "workspace:*",
15
+ "openclaw": "workspace:*"
16
+ },
17
+ "peerDependencies": {
18
+ "openclaw": ">=2026.5.2-beta.1"
19
+ },
20
+ "peerDependenciesMeta": {
21
+ "openclaw": {
22
+ "optional": true
23
+ }
24
+ },
25
+ "openclaw": {
26
+ "extensions": [
27
+ "./index.ts"
28
+ ],
29
+ "setupEntry": "./setup-entry.ts",
30
+ "channel": {
31
+ "id": "line",
32
+ "label": "LINE",
33
+ "selectionLabel": "LINE (Messaging API)",
34
+ "detailLabel": "LINE Bot",
35
+ "docsPath": "/channels/line",
36
+ "docsLabel": "line",
37
+ "blurb": "LINE Messaging API webhook bot.",
38
+ "systemImage": "message",
39
+ "order": 75,
40
+ "quickstartAllowFrom": true
41
+ },
42
+ "install": {
43
+ "npmSpec": "@openclaw/line",
44
+ "defaultChoice": "npm",
45
+ "minHostVersion": ">=2026.4.10"
46
+ },
47
+ "compat": {
48
+ "pluginApi": ">=2026.5.2-beta.1"
49
+ },
50
+ "build": {
51
+ "openclawVersion": "2026.5.2-beta.1"
52
+ },
53
+ "release": {
54
+ "publishToClawHub": true,
55
+ "publishToNpm": true
56
+ }
57
+ }
58
+ }
package/runtime-api.ts ADDED
@@ -0,0 +1,187 @@
1
+ // Private runtime barrel for the bundled LINE extension.
2
+ // Keep this barrel thin and aligned with the local extension surface.
3
+
4
+ export type {
5
+ ChannelAccountSnapshot,
6
+ ChannelPlugin,
7
+ OpenClawConfig,
8
+ OpenClawPluginApi,
9
+ PluginRuntime,
10
+ } from "openclaw/plugin-sdk/core";
11
+ export type {
12
+ ChannelGatewayContext,
13
+ ChannelStatusIssue,
14
+ } from "openclaw/plugin-sdk/channel-contract";
15
+ export { clearAccountEntryFields } from "openclaw/plugin-sdk/core";
16
+ export { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
17
+ export type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
18
+ export type { ChannelSetupDmPolicy, ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
19
+ export {
20
+ buildComputedAccountStatusSnapshot,
21
+ buildTokenChannelStatusSummary,
22
+ } from "openclaw/plugin-sdk/status-helpers";
23
+ export {
24
+ DEFAULT_ACCOUNT_ID,
25
+ formatDocsLink,
26
+ setSetupChannelEnabled,
27
+ splitSetupEntries,
28
+ } from "openclaw/plugin-sdk/setup";
29
+ export { setLineRuntime } from "./src/runtime.js";
30
+ export {
31
+ firstDefined,
32
+ isSenderAllowed,
33
+ normalizeAllowFrom,
34
+ normalizeDmAllowFromWithStore,
35
+ } from "./src/bot-access.js";
36
+ export { downloadLineMedia } from "./src/download.js";
37
+ export { probeLineBot } from "./src/probe.js";
38
+ export { buildTemplateMessageFromPayload } from "./src/template-messages.js";
39
+ export {
40
+ createQuickReplyItems,
41
+ pushFlexMessage,
42
+ pushLocationMessage,
43
+ pushMessageLine,
44
+ pushMessagesLine,
45
+ pushTemplateMessage,
46
+ pushTextMessageWithQuickReplies,
47
+ sendMessageLine,
48
+ } from "./src/send.js";
49
+ export { monitorLineProvider } from "./src/monitor.js";
50
+ export { hasLineDirectives, parseLineDirectives } from "./src/reply-payload-transform.js";
51
+ export {
52
+ listLineAccountIds,
53
+ normalizeAccountId,
54
+ resolveDefaultLineAccountId,
55
+ resolveLineAccount,
56
+ } from "./src/accounts.js";
57
+ export { type NormalizedAllowFrom } from "./src/bot-access.js";
58
+ export { resolveLineChannelAccessToken } from "./src/channel-access-token.js";
59
+ export {
60
+ LineChannelConfigSchema,
61
+ LineConfigSchema,
62
+ type LineConfigSchemaType,
63
+ } from "./src/config-schema.js";
64
+ export {
65
+ resolveExactLineGroupConfigKey,
66
+ resolveLineGroupConfigEntry,
67
+ resolveLineGroupLookupIds,
68
+ resolveLineGroupsConfig,
69
+ } from "./src/group-keys.js";
70
+ export {
71
+ type CodeBlock,
72
+ convertCodeBlockToFlexBubble,
73
+ convertLinksToFlexBubble,
74
+ convertTableToFlexBubble,
75
+ extractCodeBlocks,
76
+ extractLinks,
77
+ extractMarkdownTables,
78
+ hasMarkdownToConvert,
79
+ type MarkdownLink,
80
+ type MarkdownTable,
81
+ type ProcessedLineMessage,
82
+ processLineMessage,
83
+ stripMarkdown,
84
+ } from "./src/markdown-to-line.js";
85
+ export {
86
+ createAudioMessage,
87
+ createFlexMessage,
88
+ createImageMessage,
89
+ createLocationMessage,
90
+ createTextMessageWithQuickReplies,
91
+ createVideoMessage,
92
+ getUserDisplayName,
93
+ getUserProfile,
94
+ pushImageMessage,
95
+ replyMessageLine,
96
+ showLoadingAnimation,
97
+ } from "./src/send.js";
98
+ export { validateLineSignature } from "./src/signature.js";
99
+ export {
100
+ type ButtonsTemplate,
101
+ type CarouselColumn,
102
+ type CarouselTemplate,
103
+ type ConfirmTemplate,
104
+ createButtonMenu,
105
+ createButtonTemplate,
106
+ createCarouselColumn,
107
+ createConfirmTemplate,
108
+ createImageCarousel,
109
+ createImageCarouselColumn,
110
+ createLinkMenu,
111
+ createProductCarousel,
112
+ createTemplateCarousel,
113
+ createYesNoConfirm,
114
+ type ImageCarouselColumn,
115
+ type ImageCarouselTemplate,
116
+ type TemplateMessage,
117
+ } from "./src/template-messages.js";
118
+ export type {
119
+ LineChannelData,
120
+ LineConfig,
121
+ LineProbeResult,
122
+ ResolvedLineAccount,
123
+ } from "./src/types.js";
124
+ export { createLineNodeWebhookHandler, readLineWebhookRequestBody } from "./src/webhook-node.js";
125
+ export {
126
+ createLineWebhookMiddleware,
127
+ type LineWebhookOptions,
128
+ startLineWebhook,
129
+ type StartLineWebhookOptions,
130
+ } from "./src/webhook.js";
131
+ export { parseLineWebhookBody } from "./src/webhook-utils.js";
132
+ export { datetimePickerAction, messageAction, postbackAction, uriAction } from "./src/actions.js";
133
+ export type { Action } from "./src/actions.js";
134
+ export {
135
+ createActionCard,
136
+ createAgendaCard,
137
+ createAppleTvRemoteCard,
138
+ createCarousel,
139
+ createDeviceControlCard,
140
+ createEventCard,
141
+ createImageCard,
142
+ createInfoCard,
143
+ createListCard,
144
+ createMediaPlayerCard,
145
+ createNotificationBubble,
146
+ createReceiptCard,
147
+ toFlexMessage,
148
+ } from "./src/flex-templates.js";
149
+ export type {
150
+ CardAction,
151
+ FlexBox,
152
+ FlexBubble,
153
+ FlexButton,
154
+ FlexCarousel,
155
+ FlexComponent,
156
+ FlexContainer,
157
+ FlexImage,
158
+ FlexText,
159
+ ListItem,
160
+ } from "./src/flex-templates.js";
161
+ export {
162
+ cancelDefaultRichMenu,
163
+ createDefaultMenuConfig,
164
+ createGridLayout,
165
+ createRichMenu,
166
+ createRichMenuAlias,
167
+ deleteRichMenu,
168
+ deleteRichMenuAlias,
169
+ getDefaultRichMenuId,
170
+ getRichMenu,
171
+ getRichMenuIdOfUser,
172
+ getRichMenuList,
173
+ linkRichMenuToUser,
174
+ linkRichMenuToUsers,
175
+ setDefaultRichMenu,
176
+ unlinkRichMenuFromUser,
177
+ unlinkRichMenuFromUsers,
178
+ uploadRichMenuImage,
179
+ } from "./src/rich-menu.js";
180
+ export type {
181
+ CreateRichMenuParams,
182
+ RichMenuArea,
183
+ RichMenuAreaRequest,
184
+ RichMenuRequest,
185
+ RichMenuResponse,
186
+ RichMenuSize,
187
+ } from "./src/rich-menu.js";
@@ -0,0 +1,4 @@
1
+ // Line does not expose secret-contract surfaces.
2
+ export const secretTargetRegistryEntries: readonly [] = [];
3
+
4
+ export function collectRuntimeConfigAssignments(): void {}
package/setup-api.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { lineSetupAdapter } from "./src/setup-core.js";
2
+ export { lineSetupWizard } from "./src/setup-surface.js";
package/setup-entry.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
+
3
+ export default defineBundledChannelSetupEntry({
4
+ importMetaUrl: import.meta.url,
5
+ plugin: {
6
+ specifier: "./api.js",
7
+ exportName: "lineSetupPlugin",
8
+ },
9
+ });
@@ -0,0 +1,16 @@
1
+ type LineCredentialAccount = {
2
+ channelAccessToken?: string;
3
+ channelSecret?: string;
4
+ };
5
+
6
+ export function hasLineCredentials(account: LineCredentialAccount): boolean {
7
+ return Boolean(account.channelAccessToken?.trim() && account.channelSecret?.trim());
8
+ }
9
+
10
+ export function parseLineAllowFromId(raw: string): string | null {
11
+ const trimmed = raw.trim().replace(/^line:(?:user:)?/i, "");
12
+ if (!/^U[a-f0-9]{32}$/i.test(trimmed)) {
13
+ return null;
14
+ }
15
+ return trimmed;
16
+ }