@kodelyth/line 2026.5.42 → 2026.6.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 (90) hide show
  1. package/klaw.plugin.json +329 -2
  2. package/package.json +18 -6
  3. package/api.ts +0 -11
  4. package/channel-plugin-api.ts +0 -1
  5. package/contract-api.ts +0 -5
  6. package/index.ts +0 -53
  7. package/runtime-api.ts +0 -179
  8. package/secret-contract-api.ts +0 -4
  9. package/setup-api.ts +0 -2
  10. package/setup-entry.ts +0 -9
  11. package/src/account-helpers.ts +0 -16
  12. package/src/accounts.test.ts +0 -288
  13. package/src/accounts.ts +0 -187
  14. package/src/actions.ts +0 -61
  15. package/src/auto-reply-delivery.test.ts +0 -253
  16. package/src/auto-reply-delivery.ts +0 -200
  17. package/src/bindings.ts +0 -65
  18. package/src/bot-access.ts +0 -30
  19. package/src/bot-handlers.test.ts +0 -1094
  20. package/src/bot-handlers.ts +0 -620
  21. package/src/bot-message-context.test.ts +0 -420
  22. package/src/bot-message-context.ts +0 -586
  23. package/src/bot.ts +0 -66
  24. package/src/card-command.ts +0 -347
  25. package/src/channel-access-token.ts +0 -14
  26. package/src/channel-api.ts +0 -17
  27. package/src/channel-setup-status.contract.test.ts +0 -70
  28. package/src/channel-shared.ts +0 -48
  29. package/src/channel.logout.test.ts +0 -145
  30. package/src/channel.runtime.ts +0 -3
  31. package/src/channel.sendPayload.test.ts +0 -659
  32. package/src/channel.setup.ts +0 -11
  33. package/src/channel.status.test.ts +0 -63
  34. package/src/channel.ts +0 -155
  35. package/src/config-adapter.ts +0 -29
  36. package/src/config-schema.test.ts +0 -53
  37. package/src/config-schema.ts +0 -81
  38. package/src/download.test.ts +0 -164
  39. package/src/download.ts +0 -34
  40. package/src/flex-templates/basic-cards.ts +0 -395
  41. package/src/flex-templates/common.ts +0 -20
  42. package/src/flex-templates/media-control-cards.ts +0 -555
  43. package/src/flex-templates/message.ts +0 -13
  44. package/src/flex-templates/schedule-cards.ts +0 -467
  45. package/src/flex-templates/types.ts +0 -22
  46. package/src/flex-templates.ts +0 -32
  47. package/src/gateway.ts +0 -129
  48. package/src/group-keys.test.ts +0 -123
  49. package/src/group-keys.ts +0 -65
  50. package/src/group-policy.ts +0 -22
  51. package/src/markdown-to-line.test.ts +0 -348
  52. package/src/markdown-to-line.ts +0 -416
  53. package/src/message-cards.test.ts +0 -204
  54. package/src/monitor-durable.test.ts +0 -57
  55. package/src/monitor-durable.ts +0 -37
  56. package/src/monitor.lifecycle.test.ts +0 -499
  57. package/src/monitor.runtime.ts +0 -1
  58. package/src/monitor.ts +0 -507
  59. package/src/outbound-media.test.ts +0 -194
  60. package/src/outbound-media.ts +0 -120
  61. package/src/outbound.runtime.ts +0 -12
  62. package/src/outbound.ts +0 -427
  63. package/src/probe.contract.test.ts +0 -9
  64. package/src/probe.runtime.ts +0 -1
  65. package/src/probe.ts +0 -34
  66. package/src/quick-reply-fallback.ts +0 -10
  67. package/src/reply-chunks.test.ts +0 -180
  68. package/src/reply-chunks.ts +0 -110
  69. package/src/reply-payload-transform.test.ts +0 -392
  70. package/src/reply-payload-transform.ts +0 -317
  71. package/src/rich-menu.test.ts +0 -315
  72. package/src/rich-menu.ts +0 -326
  73. package/src/runtime.ts +0 -32
  74. package/src/send-receipt.ts +0 -32
  75. package/src/send.test.ts +0 -453
  76. package/src/send.ts +0 -531
  77. package/src/setup-core.ts +0 -149
  78. package/src/setup-runtime-api.ts +0 -9
  79. package/src/setup-surface.test.ts +0 -481
  80. package/src/setup-surface.ts +0 -229
  81. package/src/signature.test.ts +0 -34
  82. package/src/signature.ts +0 -24
  83. package/src/status.ts +0 -37
  84. package/src/template-messages.ts +0 -333
  85. package/src/types.ts +0 -130
  86. package/src/webhook-node.test.ts +0 -598
  87. package/src/webhook-node.ts +0 -155
  88. package/src/webhook-utils.ts +0 -10
  89. package/src/webhook.ts +0 -135
  90. package/tsconfig.json +0 -16
package/src/rich-menu.ts DELETED
@@ -1,326 +0,0 @@
1
- import { messagingApi } from "@line/bot-sdk";
2
- import { getAgentScopedMediaLocalRoots } from "klaw/plugin-sdk/agent-media-payload";
3
- import type { KlawConfig } from "klaw/plugin-sdk/config-contracts";
4
- import { mimeTypeFromFilePath } from "klaw/plugin-sdk/media-mime";
5
- import { logVerbose } from "klaw/plugin-sdk/runtime-env";
6
- import { loadWebMediaRaw } from "klaw/plugin-sdk/web-media";
7
- import { resolveLineAccount } from "./accounts.js";
8
- import { datetimePickerAction, messageAction, postbackAction, uriAction } from "./actions.js";
9
- import { resolveLineChannelAccessToken } from "./channel-access-token.js";
10
-
11
- type RichMenuRequest = messagingApi.RichMenuRequest;
12
- type RichMenuResponse = messagingApi.RichMenuResponse;
13
- type RichMenuArea = messagingApi.RichMenuArea;
14
- type Action = messagingApi.Action;
15
- const USER_BATCH_SIZE = 500;
16
-
17
- export interface RichMenuSize {
18
- width: 2500;
19
- height: 1686 | 843;
20
- }
21
-
22
- export interface RichMenuAreaRequest {
23
- bounds: {
24
- x: number;
25
- y: number;
26
- width: number;
27
- height: number;
28
- };
29
- action: Action;
30
- }
31
-
32
- export interface CreateRichMenuParams {
33
- size: RichMenuSize;
34
- selected?: boolean;
35
- name: string;
36
- chatBarText: string;
37
- areas: RichMenuAreaRequest[];
38
- }
39
-
40
- interface RichMenuOpts {
41
- cfg: KlawConfig;
42
- channelAccessToken?: string;
43
- accountId?: string;
44
- verbose?: boolean;
45
- mediaLocalRoots?: readonly string[];
46
- }
47
-
48
- function getClient(opts: RichMenuOpts): messagingApi.MessagingApiClient {
49
- const account = resolveLineAccount({
50
- cfg: opts.cfg,
51
- accountId: opts.accountId,
52
- });
53
- const token = resolveLineChannelAccessToken(opts.channelAccessToken, account);
54
-
55
- return new messagingApi.MessagingApiClient({
56
- channelAccessToken: token,
57
- });
58
- }
59
-
60
- function getBlobClient(opts: RichMenuOpts): messagingApi.MessagingApiBlobClient {
61
- const account = resolveLineAccount({
62
- cfg: opts.cfg,
63
- accountId: opts.accountId,
64
- });
65
- const token = resolveLineChannelAccessToken(opts.channelAccessToken, account);
66
-
67
- return new messagingApi.MessagingApiBlobClient({
68
- channelAccessToken: token,
69
- });
70
- }
71
-
72
- function chunkUserIds(userIds: string[]): string[][] {
73
- const batches: string[][] = [];
74
- for (let i = 0; i < userIds.length; i += USER_BATCH_SIZE) {
75
- batches.push(userIds.slice(i, i + USER_BATCH_SIZE));
76
- }
77
- return batches;
78
- }
79
-
80
- export async function createRichMenu(
81
- menu: CreateRichMenuParams,
82
- opts: RichMenuOpts,
83
- ): Promise<string> {
84
- const client = getClient(opts);
85
-
86
- const richMenuRequest: RichMenuRequest = {
87
- size: menu.size,
88
- selected: menu.selected ?? false,
89
- name: menu.name.slice(0, 300),
90
- chatBarText: menu.chatBarText.slice(0, 14),
91
- areas: menu.areas as RichMenuArea[],
92
- };
93
-
94
- const response = await client.createRichMenu(richMenuRequest);
95
-
96
- if (opts.verbose) {
97
- logVerbose(`line: created rich menu ${response.richMenuId}`);
98
- }
99
-
100
- return response.richMenuId;
101
- }
102
-
103
- export async function uploadRichMenuImage(
104
- richMenuId: string,
105
- imagePath: string,
106
- opts: RichMenuOpts,
107
- ): Promise<void> {
108
- const blobClient = getBlobClient(opts);
109
-
110
- const media = await loadWebMediaRaw(imagePath, {
111
- localRoots: opts.mediaLocalRoots ?? getAgentScopedMediaLocalRoots(opts.cfg),
112
- });
113
- const contentType =
114
- media.contentType === "image/png" || media.contentType === "image/jpeg"
115
- ? media.contentType
116
- : mimeTypeFromFilePath(imagePath) === "image/png"
117
- ? "image/png"
118
- : "image/jpeg";
119
-
120
- const imageBytes = new ArrayBuffer(media.buffer.byteLength);
121
- new Uint8Array(imageBytes).set(media.buffer);
122
- await blobClient.setRichMenuImage(richMenuId, new Blob([imageBytes], { type: contentType }));
123
-
124
- if (opts.verbose) {
125
- logVerbose(`line: uploaded image to rich menu ${richMenuId}`);
126
- }
127
- }
128
-
129
- export async function setDefaultRichMenu(richMenuId: string, opts: RichMenuOpts): Promise<void> {
130
- const client = getClient(opts);
131
- await client.setDefaultRichMenu(richMenuId);
132
-
133
- if (opts.verbose) {
134
- logVerbose(`line: set default rich menu to ${richMenuId}`);
135
- }
136
- }
137
-
138
- export async function cancelDefaultRichMenu(opts: RichMenuOpts): Promise<void> {
139
- const client = getClient(opts);
140
- await client.cancelDefaultRichMenu();
141
-
142
- if (opts.verbose) {
143
- logVerbose("line: cancelled default rich menu");
144
- }
145
- }
146
-
147
- export async function getDefaultRichMenuId(opts: RichMenuOpts): Promise<string | null> {
148
- const client = getClient(opts);
149
-
150
- try {
151
- const response = await client.getDefaultRichMenuId();
152
- return response.richMenuId ?? null;
153
- } catch {
154
- return null;
155
- }
156
- }
157
-
158
- export async function linkRichMenuToUser(
159
- userId: string,
160
- richMenuId: string,
161
- opts: RichMenuOpts,
162
- ): Promise<void> {
163
- const client = getClient(opts);
164
- await client.linkRichMenuIdToUser(userId, richMenuId);
165
-
166
- if (opts.verbose) {
167
- logVerbose(`line: linked rich menu ${richMenuId} to user ${userId}`);
168
- }
169
- }
170
-
171
- export async function linkRichMenuToUsers(
172
- userIds: string[],
173
- richMenuId: string,
174
- opts: RichMenuOpts,
175
- ): Promise<void> {
176
- const client = getClient(opts);
177
-
178
- for (const batch of chunkUserIds(userIds)) {
179
- await client.linkRichMenuIdToUsers({
180
- richMenuId,
181
- userIds: batch,
182
- });
183
- }
184
-
185
- if (opts.verbose) {
186
- logVerbose(`line: linked rich menu ${richMenuId} to ${userIds.length} users`);
187
- }
188
- }
189
-
190
- export async function unlinkRichMenuFromUser(userId: string, opts: RichMenuOpts): Promise<void> {
191
- const client = getClient(opts);
192
- await client.unlinkRichMenuIdFromUser(userId);
193
-
194
- if (opts.verbose) {
195
- logVerbose(`line: unlinked rich menu from user ${userId}`);
196
- }
197
- }
198
-
199
- export async function unlinkRichMenuFromUsers(
200
- userIds: string[],
201
- opts: RichMenuOpts,
202
- ): Promise<void> {
203
- const client = getClient(opts);
204
-
205
- for (const batch of chunkUserIds(userIds)) {
206
- await client.unlinkRichMenuIdFromUsers({
207
- userIds: batch,
208
- });
209
- }
210
-
211
- if (opts.verbose) {
212
- logVerbose(`line: unlinked rich menu from ${userIds.length} users`);
213
- }
214
- }
215
-
216
- export async function getRichMenuIdOfUser(
217
- userId: string,
218
- opts: RichMenuOpts,
219
- ): Promise<string | null> {
220
- const client = getClient(opts);
221
-
222
- try {
223
- const response = await client.getRichMenuIdOfUser(userId);
224
- return response.richMenuId ?? null;
225
- } catch {
226
- return null;
227
- }
228
- }
229
-
230
- export async function getRichMenuList(opts: RichMenuOpts): Promise<RichMenuResponse[]> {
231
- const client = getClient(opts);
232
- const response = await client.getRichMenuList();
233
- return response.richmenus ?? [];
234
- }
235
-
236
- export async function getRichMenu(
237
- richMenuId: string,
238
- opts: RichMenuOpts,
239
- ): Promise<RichMenuResponse | null> {
240
- const client = getClient(opts);
241
-
242
- try {
243
- return await client.getRichMenu(richMenuId);
244
- } catch {
245
- return null;
246
- }
247
- }
248
-
249
- export async function deleteRichMenu(richMenuId: string, opts: RichMenuOpts): Promise<void> {
250
- const client = getClient(opts);
251
- await client.deleteRichMenu(richMenuId);
252
-
253
- if (opts.verbose) {
254
- logVerbose(`line: deleted rich menu ${richMenuId}`);
255
- }
256
- }
257
-
258
- export async function createRichMenuAlias(
259
- richMenuId: string,
260
- aliasId: string,
261
- opts: RichMenuOpts,
262
- ): Promise<void> {
263
- const client = getClient(opts);
264
-
265
- await client.createRichMenuAlias({
266
- richMenuId,
267
- richMenuAliasId: aliasId,
268
- });
269
-
270
- if (opts.verbose) {
271
- logVerbose(`line: created alias ${aliasId} for rich menu ${richMenuId}`);
272
- }
273
- }
274
-
275
- export async function deleteRichMenuAlias(aliasId: string, opts: RichMenuOpts): Promise<void> {
276
- const client = getClient(opts);
277
- await client.deleteRichMenuAlias(aliasId);
278
-
279
- if (opts.verbose) {
280
- logVerbose(`line: deleted alias ${aliasId}`);
281
- }
282
- }
283
-
284
- export function createGridLayout(
285
- height: 1686 | 843,
286
- actions: [Action, Action, Action, Action, Action, Action],
287
- ): RichMenuAreaRequest[] {
288
- const colWidth = Math.floor(2500 / 3);
289
- const rowHeight = Math.floor(height / 2);
290
-
291
- return [
292
- { bounds: { x: 0, y: 0, width: colWidth, height: rowHeight }, action: actions[0] },
293
- { bounds: { x: colWidth, y: 0, width: colWidth, height: rowHeight }, action: actions[1] },
294
- { bounds: { x: colWidth * 2, y: 0, width: colWidth, height: rowHeight }, action: actions[2] },
295
- { bounds: { x: 0, y: rowHeight, width: colWidth, height: rowHeight }, action: actions[3] },
296
- {
297
- bounds: { x: colWidth, y: rowHeight, width: colWidth, height: rowHeight },
298
- action: actions[4],
299
- },
300
- {
301
- bounds: { x: colWidth * 2, y: rowHeight, width: colWidth, height: rowHeight },
302
- action: actions[5],
303
- },
304
- ];
305
- }
306
-
307
- export { datetimePickerAction, messageAction, postbackAction, uriAction };
308
-
309
- export function createDefaultMenuConfig(): CreateRichMenuParams {
310
- return {
311
- size: { width: 2500, height: 843 },
312
- selected: false,
313
- name: "Default Menu",
314
- chatBarText: "Menu",
315
- areas: createGridLayout(843, [
316
- messageAction("Help", "/help"),
317
- messageAction("Status", "/status"),
318
- messageAction("Settings", "/settings"),
319
- messageAction("About", "/about"),
320
- messageAction("Feedback", "/feedback"),
321
- messageAction("Contact", "/contact"),
322
- ]),
323
- };
324
- }
325
-
326
- export type { RichMenuRequest, RichMenuResponse, RichMenuArea };
package/src/runtime.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { PluginRuntime } from "klaw/plugin-sdk/core";
2
- import { createPluginRuntimeStore } from "klaw/plugin-sdk/runtime-store";
3
-
4
- type LineChannelRuntime = {
5
- buildTemplateMessageFromPayload?: typeof import("./template-messages.js").buildTemplateMessageFromPayload;
6
- createQuickReplyItems?: typeof import("./send.js").createQuickReplyItems;
7
- monitorLineProvider?: typeof import("./monitor.js").monitorLineProvider;
8
- pushFlexMessage?: typeof import("./send.js").pushFlexMessage;
9
- pushLocationMessage?: typeof import("./send.js").pushLocationMessage;
10
- pushMessageLine?: typeof import("./send.js").pushMessageLine;
11
- pushMessagesLine?: typeof import("./send.js").pushMessagesLine;
12
- pushTemplateMessage?: typeof import("./send.js").pushTemplateMessage;
13
- pushTextMessageWithQuickReplies?: typeof import("./send.js").pushTextMessageWithQuickReplies;
14
- resolveLineAccount?: typeof import("./accounts.js").resolveLineAccount;
15
- sendMessageLine?: typeof import("./send.js").sendMessageLine;
16
- };
17
-
18
- type LineRuntime = PluginRuntime & {
19
- channel: PluginRuntime["channel"] & {
20
- line?: LineChannelRuntime;
21
- };
22
- };
23
-
24
- const {
25
- setRuntime: setLineRuntime,
26
- clearRuntime: clearLineRuntime,
27
- getRuntime: getLineRuntime,
28
- } = createPluginRuntimeStore<LineRuntime>({
29
- pluginId: "line",
30
- errorMessage: "LINE runtime not initialized - plugin not registered",
31
- });
32
- export { clearLineRuntime, getLineRuntime, setLineRuntime };
@@ -1,32 +0,0 @@
1
- import {
2
- createMessageReceiptFromOutboundResults,
3
- type MessageReceipt,
4
- type MessageReceiptPartKind,
5
- } from "klaw/plugin-sdk/channel-message";
6
-
7
- export function createLineSendReceipt(params: {
8
- messageId: string;
9
- chatId: string;
10
- kind?: MessageReceiptPartKind;
11
- messageCount?: number;
12
- }): MessageReceipt {
13
- const messageId = params.messageId.trim();
14
- const chatId = params.chatId.trim();
15
- return createMessageReceiptFromOutboundResults({
16
- results: messageId
17
- ? [
18
- {
19
- channel: "line",
20
- messageId,
21
- chatId,
22
- conversationId: chatId,
23
- meta: {
24
- messageCount: params.messageCount ?? 1,
25
- },
26
- },
27
- ]
28
- : [],
29
- ...(chatId ? { threadId: chatId } : {}),
30
- kind: params.kind ?? "unknown",
31
- });
32
- }