@zhin.js/adapter-line 4.0.3 → 4.0.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,86 @@
1
1
  # @zhin.js/adapter-line
2
2
 
3
+ ## 4.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [2d0a622]
8
+ - @zhin.js/command@1.0.10
9
+ - @zhin.js/adapter@1.1.7
10
+ - @zhin.js/core@1.5.5
11
+ - @zhin.js/agent@1.1.6
12
+ - zhin.js@6.0.5
13
+
14
+ ## 4.0.5
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [6f9c366]
19
+ - Updated dependencies [373a56b]
20
+ - Updated dependencies [0de46a8]
21
+ - Updated dependencies [c106ecc]
22
+ - Updated dependencies [ca92e03]
23
+ - Updated dependencies [b0f37ae]
24
+ - Updated dependencies [ba08a2f]
25
+ - Updated dependencies [b08f7fe]
26
+ - Updated dependencies [daffd4c]
27
+ - Updated dependencies [36c7400]
28
+ - Updated dependencies [a9fa72e]
29
+ - Updated dependencies [c8de3ef]
30
+ - Updated dependencies [60f0fc8]
31
+ - Updated dependencies [574c990]
32
+ - Updated dependencies [d096f16]
33
+ - Updated dependencies [3f29623]
34
+ - Updated dependencies [2916852]
35
+ - Updated dependencies [d047869]
36
+ - Updated dependencies [162fa34]
37
+ - Updated dependencies [e62561e]
38
+ - Updated dependencies [3eeeb46]
39
+ - Updated dependencies [85d0f82]
40
+ - Updated dependencies [61bfc1c]
41
+ - Updated dependencies [04bad47]
42
+ - Updated dependencies [e40b048]
43
+ - Updated dependencies [5a5b1bb]
44
+ - Updated dependencies [f1708c3]
45
+ - Updated dependencies [d254a81]
46
+ - Updated dependencies [7123c47]
47
+ - Updated dependencies [05befc1]
48
+ - Updated dependencies [0663b6a]
49
+ - Updated dependencies [f28f9b3]
50
+ - Updated dependencies [9f340f7]
51
+ - Updated dependencies [e53444f]
52
+ - Updated dependencies [5eedd26]
53
+ - Updated dependencies [92b0dd7]
54
+ - Updated dependencies [f919b6f]
55
+ - Updated dependencies [098e411]
56
+ - Updated dependencies [e1b7c01]
57
+ - Updated dependencies [9b94f87]
58
+ - Updated dependencies [a7df753]
59
+ - @zhin.js/agent@1.1.5
60
+ - @zhin.js/host-http@1.0.8
61
+ - @zhin.js/im-contract@1.0.3
62
+ - @zhin.js/adapter@1.1.7
63
+ - @zhin.js/plugin-runtime@1.1.5
64
+ - @zhin.js/command@1.0.9
65
+ - @zhin.js/core@1.5.4
66
+ - zhin.js@6.0.4
67
+
68
+ ## 4.0.4
69
+
70
+ ### Patch Changes
71
+
72
+ - f8c7a54: fix: im
73
+ - Updated dependencies [f8c7a54]
74
+ - @zhin.js/logger@1.0.76
75
+ - @zhin.js/host-http@1.0.7
76
+ - @zhin.js/adapter@1.1.6
77
+ - @zhin.js/agent@1.1.4
78
+ - @zhin.js/command@1.0.8
79
+ - @zhin.js/core@1.5.3
80
+ - @zhin.js/im-contract@1.0.2
81
+ - @zhin.js/plugin-runtime@1.1.4
82
+ - zhin.js@6.0.3
83
+
3
84
  ## 4.0.3
4
85
 
5
86
  ### Patch Changes
package/adapters/line.js CHANGED
@@ -19,8 +19,8 @@ export default defineAdapter({
19
19
  create(context) {
20
20
  const config = resolveLineConfig(context.config);
21
21
  // 注册到插件运行时状态(line.endpoint list 的"运行中"数据源)
22
- context.use(lineRuntimeStateToken).endpoints.set(config.name, {
23
- name: config.name,
22
+ context.use(lineRuntimeStateToken).endpoints.set(config.id, {
23
+ id: config.id,
24
24
  mode: 'webhook',
25
25
  });
26
26
  return new LineEndpoint({
package/adapters/line.ts CHANGED
@@ -24,8 +24,8 @@ export default defineAdapter<LineAdapterConfig>({
24
24
  create(context) {
25
25
  const config = resolveLineConfig(context.config);
26
26
  // 注册到插件运行时状态(line.endpoint list 的"运行中"数据源)
27
- context.use(lineRuntimeStateToken).endpoints.set(config.name, {
28
- name: config.name,
27
+ context.use(lineRuntimeStateToken).endpoints.set(config.id, {
28
+ id: config.id,
29
29
  mode: 'webhook',
30
30
  });
31
31
  return new LineEndpoint({
package/lib/endpoint.js CHANGED
@@ -1,13 +1,13 @@
1
- import { formatCompact, getLogger } from '@zhin.js/logger';
1
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
2
2
  import { registerLineAgentEndpoint } from './line-agent-deps.js';
3
3
  import { formatInboundContent, formatOutboundMessages, generateMessageId, isMessageEvent, isValidLineRecipientId, lineInboundConversation, } from './protocol.js';
4
4
  import { registerLineWebhookRoutes } from './webhook.js';
5
- const logger = getLogger('line');
6
5
  /** LINE replyToken 有效期短,过期后 reply 必 400;缓存带时间戳,超时弃用改走 push。 */
7
6
  const REPLY_TOKEN_TTL_MS = 60_000;
8
7
  /** 出站 HTTP 调用统一 30s 超时。 */
9
8
  const OUTBOUND_TIMEOUT_MS = 30_000;
10
9
  export class LineEndpoint {
10
+ #logger;
11
11
  #options;
12
12
  #fetch;
13
13
  #routeReleases = [];
@@ -17,6 +17,7 @@ export class LineEndpoint {
17
17
  #unregisterAgent;
18
18
  management = createLineEndpointManagement(this);
19
19
  constructor(options) {
20
+ this.#logger = getAdapterLogger('line', options.config.id);
20
21
  this.#options = options;
21
22
  this.#fetch = options.fetch ?? globalThis.fetch;
22
23
  }
@@ -38,17 +39,17 @@ export class LineEndpoint {
38
39
  return;
39
40
  this.#started = true;
40
41
  try {
41
- this.#unregisterAgent = registerLineAgentEndpoint(this.#options.config.name, this);
42
+ this.#unregisterAgent = registerLineAgentEndpoint(this.#options.config.id, this);
42
43
  this.#routeReleases.push(...registerLineWebhookRoutes(this.#options.http, this));
43
- logger.debug(formatCompact({
44
- endpoint: this.#options.config.name,
44
+ this.#logger.debug(formatCompact({
45
+ endpoint: this.#options.config.id,
45
46
  op: 'webhook',
46
47
  path: this.#options.config.webhookPath,
47
48
  }));
48
49
  }
49
50
  catch (error) {
50
51
  await this.stop();
51
- logger.error('Failed to connect LINE endpoint:', error);
52
+ this.#logger.error('Failed to connect LINE endpoint:', error);
52
53
  throw error;
53
54
  }
54
55
  }
@@ -66,7 +67,7 @@ export class LineEndpoint {
66
67
  this.#unregisterAgent?.();
67
68
  this.#unregisterAgent = undefined;
68
69
  this.#started = false;
69
- logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
70
+ this.#logger.debug(formatCompact({ op: 'disconnect' }));
70
71
  }
71
72
  async send({ conversation, payload }) {
72
73
  const messages = formatOutboundMessages(payload);
@@ -86,9 +87,9 @@ export class LineEndpoint {
86
87
  // replyToken 过期/失效时 LINE 返回 400,回退 push 保证消息不丢
87
88
  if (error.status !== 400)
88
89
  throw error;
89
- logger.warn(formatCompact({
90
+ this.#logger.warn(formatCompact({
90
91
  op: 'line_reply_fallback_push',
91
- endpoint: this.#options.config.name,
92
+ endpoint: this.#options.config.id,
92
93
  target,
93
94
  }));
94
95
  }
@@ -111,16 +112,16 @@ export class LineEndpoint {
111
112
  conversation,
112
113
  message: { conversation, id: generateMessageId(event) },
113
114
  content: formatInboundContent(event),
114
- sender: event.source.userId || conversation.id,
115
+ sender: { id: event.source.userId || conversation.id },
116
+ endpointId: this.#options.config.id,
115
117
  metadata: Object.freeze({
116
118
  eventType: event.type,
117
119
  sourceType: event.source.type,
118
- endpoint: this.#options.config.name,
119
120
  timestamp: event.timestamp,
120
121
  ...(isMessageEvent(event) ? { messageType: event.message.type } : {}),
121
122
  }),
122
123
  }).catch((err) => {
123
- logger.warn(formatCompact({
124
+ this.#logger.warn(formatCompact({
124
125
  op: 'line_gateway_receive_failed',
125
126
  target: `${conversation.kind}:${conversation.id}`,
126
127
  error: err instanceof Error ? err.message : String(err),
@@ -14,7 +14,7 @@ export interface LineAgentDeps {
14
14
  apiBaseUrl: string;
15
15
  };
16
16
  }
17
- export declare function registerLineAgentEndpoint(endpointId: string, endpoint: LineAgentEndpoint): () => void;
17
+ export declare function registerLineAgentEndpoint(endpointKey: string, endpoint: LineAgentEndpoint): () => void;
18
18
  /** Optional override used by tests / transitional callers. Pass `null` to clear. */
19
19
  export declare function setLineAgentDeps(deps: LineAgentDeps | null): void;
20
20
  export declare function getLineAgentDeps(): LineAgentDeps;
@@ -4,11 +4,11 @@
4
4
  */
5
5
  const endpoints = new Map();
6
6
  let override = null;
7
- export function registerLineAgentEndpoint(endpointId, endpoint) {
8
- endpoints.set(endpointId, endpoint);
7
+ export function registerLineAgentEndpoint(endpointKey, endpoint) {
8
+ endpoints.set(endpointKey, endpoint);
9
9
  return () => {
10
- if (endpoints.get(endpointId) === endpoint) {
11
- endpoints.delete(endpointId);
10
+ if (endpoints.get(endpointKey) === endpoint) {
11
+ endpoints.delete(endpointKey);
12
12
  }
13
13
  };
14
14
  }
package/lib/protocol.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { IncomingMessage } from 'node:http';
6
6
  import type { ConversationRef } from '@zhin.js/im-contract';
7
7
  /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
8
8
  export interface LineAdapterConfig {
9
- readonly name?: string;
9
+ readonly id?: string;
10
10
  readonly channelSecret?: string;
11
11
  readonly channelAccessToken?: string;
12
12
  readonly webhookPath?: string;
@@ -18,7 +18,7 @@ export interface LineAdapterConfig {
18
18
  }
19
19
  export interface ResolvedLineConfig {
20
20
  readonly context: 'line';
21
- readonly name: string;
21
+ readonly id: string;
22
22
  readonly channelSecret: string;
23
23
  readonly channelAccessToken: string;
24
24
  readonly webhookPath: string;
@@ -141,7 +141,7 @@ export declare function resolveChannel(source: LineSource): LineChannel;
141
141
  * 入站归一化 → ConversationRef:LINE user → private、group → group、room → channel。
142
142
  * LINE 没有 guild/频道容器概念,无 parent;recipient id 前缀(U/G/R)自带场景信息。
143
143
  */
144
- export declare function lineInboundConversation(endpointId: string, source: LineSource): ConversationRef;
144
+ export declare function lineInboundConversation(endpointKey: string, source: LineSource): ConversationRef;
145
145
  export declare function generateMessageId(event: LineEvent): string;
146
146
  /** Build inbound text for MessageGateway.receive. */
147
147
  export declare function formatInboundContent(event: LineEvent): string;
package/lib/protocol.js CHANGED
@@ -17,15 +17,15 @@ export function resolveLineConfig(config = {}) {
17
17
  if (!channelSecret || !channelAccessToken) {
18
18
  throw new TypeError('LINE adapter requires channelSecret + channelAccessToken (plugins.<key> or endpoints with context: line)');
19
19
  }
20
- const name = (typeof config.name === 'string' && config.name)
21
- || (typeof entry?.name === 'string' && entry.name)
20
+ const id = (typeof config.id === 'string' && config.id)
21
+ || (typeof entry?.id === 'string' && entry.id)
22
22
  || process.env.LINE_BOT_NAME
23
23
  || 'line-bot';
24
24
  const webhookPath = normalizeWebhookPath(config.webhookPath ?? entry?.webhookPath ?? '/line/webhook');
25
25
  const apiBaseUrl = (config.apiBaseUrl ?? entry?.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
26
26
  return {
27
27
  context: 'line',
28
- name,
28
+ id,
29
29
  channelSecret,
30
30
  channelAccessToken,
31
31
  webhookPath,
@@ -58,10 +58,10 @@ export function resolveChannel(source) {
58
58
  * 入站归一化 → ConversationRef:LINE user → private、group → group、room → channel。
59
59
  * LINE 没有 guild/频道容器概念,无 parent;recipient id 前缀(U/G/R)自带场景信息。
60
60
  */
61
- export function lineInboundConversation(endpointId, source) {
61
+ export function lineInboundConversation(endpointKey, source) {
62
62
  const channel = resolveChannel(source);
63
63
  return {
64
- endpoint: { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
64
+ endpoint: { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey },
65
65
  kind: channel.channelType,
66
66
  id: channel.channelId,
67
67
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-line",
3
- "version": "4.0.3",
3
+ "version": "4.0.6",
4
4
  "description": "Zhin.js LINE Messaging API adapter for Plugin Runtime (HTTP webhook)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -32,22 +32,22 @@
32
32
  "directory": "plugins/adapters/line"
33
33
  },
34
34
  "dependencies": {
35
- "@zhin.js/adapter": "1.1.5",
36
- "@zhin.js/command": "1.0.7",
37
- "@zhin.js/core": "1.5.2",
38
- "@zhin.js/host-http": "1.0.6",
39
- "@zhin.js/im-contract": "1.0.1",
40
- "@zhin.js/logger": "1.0.75",
41
- "@zhin.js/plugin-runtime": "1.1.3"
35
+ "@zhin.js/adapter": "1.1.7",
36
+ "@zhin.js/command": "1.0.10",
37
+ "@zhin.js/core": "1.5.5",
38
+ "@zhin.js/host-http": "1.0.8",
39
+ "@zhin.js/im-contract": "1.0.3",
40
+ "@zhin.js/logger": "1.0.76",
41
+ "@zhin.js/plugin-runtime": "1.1.5"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "zod": "^4.0.0",
45
- "@zhin.js/adapter": "1.1.5",
46
- "@zhin.js/agent": "1.1.3",
47
- "@zhin.js/core": "1.5.2",
48
- "@zhin.js/host-http": "1.0.6",
49
- "@zhin.js/plugin-runtime": "1.1.3",
50
- "zhin.js": "6.0.2"
45
+ "@zhin.js/adapter": "1.1.7",
46
+ "@zhin.js/agent": "1.1.6",
47
+ "@zhin.js/core": "1.5.5",
48
+ "@zhin.js/host-http": "1.0.8",
49
+ "@zhin.js/plugin-runtime": "1.1.5",
50
+ "zhin.js": "6.0.5"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "zhin.js": {
@@ -65,7 +65,7 @@
65
65
  "typescript": "^6.0.3",
66
66
  "vitest": "^4.1.10",
67
67
  "zod": "^4.4.3",
68
- "@zhin.js/agent": "1.1.3"
68
+ "@zhin.js/agent": "1.1.6"
69
69
  },
70
70
  "files": [
71
71
  "adapters",
package/schema.json CHANGED
@@ -11,16 +11,48 @@
11
11
  "type": "string",
12
12
  "default": "https://api.line.me"
13
13
  },
14
+ "master": {
15
+ "type": [
16
+ "string",
17
+ "number"
18
+ ],
19
+ "description": "框架 master(LINE user id;AI/工具权限、endpoint 管理)。endpoints[i].master 可逐项覆盖"
20
+ },
21
+ "trusted": {
22
+ "type": "array",
23
+ "items": {
24
+ "type": [
25
+ "string",
26
+ "number"
27
+ ],
28
+ "description": "Trusted LINE user id"
29
+ },
30
+ "description": "框架 trusted 用户列表(弱于 master)。endpoints[i].trusted 可逐项追加"
31
+ },
14
32
  "endpoints": {
15
33
  "type": "array",
16
- "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(name 必填,其余覆盖顶层)",
34
+ "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
17
35
  "items": {
18
36
  "type": "object",
19
37
  "additionalProperties": true,
20
38
  "properties": {
21
- "name": {
22
- "type": "string",
23
- "description": "LINE bot name"
39
+ "master": {
40
+ "type": [
41
+ "string",
42
+ "number"
43
+ ],
44
+ "description": "本 endpoint 的框架 master(LINE user id);覆盖顶层 master"
45
+ },
46
+ "trusted": {
47
+ "type": "array",
48
+ "items": {
49
+ "type": [
50
+ "string",
51
+ "number"
52
+ ],
53
+ "description": "Trusted LINE user id"
54
+ },
55
+ "description": "本 endpoint 的 trusted 列表"
24
56
  },
25
57
  "channelSecret": {
26
58
  "type": "string",
@@ -29,10 +61,14 @@
29
61
  "channelAccessToken": {
30
62
  "type": "string",
31
63
  "description": "LINE channel access token"
64
+ },
65
+ "id": {
66
+ "type": "string",
67
+ "description": "LINE bot name"
32
68
  }
33
69
  },
34
70
  "required": [
35
- "name",
71
+ "id",
36
72
  "channelSecret",
37
73
  "channelAccessToken"
38
74
  ]
package/src/endpoint.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  import type { EndpointInstance, EndpointManagement, EndpointSendRequest } from '@zhin.js/adapter';
5
5
  import type { MessageGateway } from '@zhin.js/core/runtime';
6
6
  import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
7
- import { formatCompact, getLogger } from '@zhin.js/logger';
7
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
8
8
  import type { CapabilityId } from '@zhin.js/plugin-runtime';
9
9
  import { registerLineAgentEndpoint } from './line-agent-deps.js';
10
10
  import {
@@ -20,8 +20,6 @@ import {
20
20
  } from './protocol.js';
21
21
  import { registerLineWebhookRoutes } from './webhook.js';
22
22
 
23
- const logger = getLogger('line');
24
-
25
23
  /** LINE replyToken 有效期短,过期后 reply 必 400;缓存带时间戳,超时弃用改走 push。 */
26
24
  const REPLY_TOKEN_TTL_MS = 60_000;
27
25
  /** 出站 HTTP 调用统一 30s 超时。 */
@@ -51,6 +49,8 @@ export interface LineEndpointOptions {
51
49
  }
52
50
 
53
51
  export class LineEndpoint implements EndpointInstance {
52
+ readonly #logger!: ReturnType<typeof getAdapterLogger>;
53
+
54
54
  readonly #options: LineEndpointOptions;
55
55
  readonly #fetch: LineFetch;
56
56
  #routeReleases: HttpRouteRegistration[] = [];
@@ -61,6 +61,7 @@ export class LineEndpoint implements EndpointInstance {
61
61
  readonly management: EndpointManagement = createLineEndpointManagement(this);
62
62
 
63
63
  constructor(options: LineEndpointOptions) {
64
+ this.#logger = getAdapterLogger('line', options.config.id);
64
65
  this.#options = options;
65
66
  this.#fetch = options.fetch ?? globalThis.fetch;
66
67
  }
@@ -85,16 +86,16 @@ export class LineEndpoint implements EndpointInstance {
85
86
  if (this.#started) return;
86
87
  this.#started = true;
87
88
  try {
88
- this.#unregisterAgent = registerLineAgentEndpoint(this.#options.config.name, this);
89
+ this.#unregisterAgent = registerLineAgentEndpoint(this.#options.config.id, this);
89
90
  this.#routeReleases.push(...registerLineWebhookRoutes(this.#options.http, this));
90
- logger.debug(formatCompact({
91
- endpoint: this.#options.config.name,
91
+ this.#logger.debug(formatCompact({
92
+ endpoint: this.#options.config.id,
92
93
  op: 'webhook',
93
94
  path: this.#options.config.webhookPath,
94
95
  }));
95
96
  } catch (error) {
96
97
  await this.stop();
97
- logger.error('Failed to connect LINE endpoint:', error);
98
+ this.#logger.error('Failed to connect LINE endpoint:', error);
98
99
  throw error;
99
100
  }
100
101
  }
@@ -114,7 +115,7 @@ export class LineEndpoint implements EndpointInstance {
114
115
  this.#unregisterAgent?.();
115
116
  this.#unregisterAgent = undefined;
116
117
  this.#started = false;
117
- logger.debug(formatCompact({ op: 'disconnect', endpoint: this.#options.config.name }));
118
+ this.#logger.debug(formatCompact({ op: 'disconnect' }));
118
119
  }
119
120
 
120
121
  async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
@@ -134,9 +135,9 @@ export class LineEndpoint implements EndpointInstance {
134
135
  } catch (error) {
135
136
  // replyToken 过期/失效时 LINE 返回 400,回退 push 保证消息不丢
136
137
  if ((error as { status?: number }).status !== 400) throw error;
137
- logger.warn(formatCompact({
138
+ this.#logger.warn(formatCompact({
138
139
  op: 'line_reply_fallback_push',
139
- endpoint: this.#options.config.name,
140
+ endpoint: this.#options.config.id,
140
141
  target,
141
142
  }));
142
143
  }
@@ -162,16 +163,16 @@ export class LineEndpoint implements EndpointInstance {
162
163
  conversation,
163
164
  message: { conversation, id: generateMessageId(event) },
164
165
  content: formatInboundContent(event),
165
- sender: event.source.userId || conversation.id,
166
+ sender: { id: event.source.userId || conversation.id },
167
+ endpointId: this.#options.config.id,
166
168
  metadata: Object.freeze({
167
169
  eventType: event.type,
168
170
  sourceType: event.source.type,
169
- endpoint: this.#options.config.name,
170
171
  timestamp: event.timestamp,
171
172
  ...(isMessageEvent(event) ? { messageType: event.message.type } : {}),
172
173
  }),
173
174
  }).catch((err) => {
174
- logger.warn(formatCompact({
175
+ this.#logger.warn(formatCompact({
175
176
  op: 'line_gateway_receive_failed',
176
177
  target: `${conversation.kind}:${conversation.id}`,
177
178
  error: err instanceof Error ? err.message : String(err),
@@ -15,13 +15,13 @@ const endpoints = new Map<string, LineAgentEndpoint>();
15
15
  let override: LineAgentDeps | null = null;
16
16
 
17
17
  export function registerLineAgentEndpoint(
18
- endpointId: string,
18
+ endpointKey: string,
19
19
  endpoint: LineAgentEndpoint,
20
20
  ): () => void {
21
- endpoints.set(endpointId, endpoint);
21
+ endpoints.set(endpointKey, endpoint);
22
22
  return () => {
23
- if (endpoints.get(endpointId) === endpoint) {
24
- endpoints.delete(endpointId);
23
+ if (endpoints.get(endpointKey) === endpoint) {
24
+ endpoints.delete(endpointKey);
25
25
  }
26
26
  };
27
27
  }
package/src/protocol.ts CHANGED
@@ -13,7 +13,7 @@ const logger = getLogger('line');
13
13
 
14
14
  /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
15
15
  export interface LineAdapterConfig {
16
- readonly name?: string;
16
+ readonly id?: string;
17
17
  readonly channelSecret?: string;
18
18
  readonly channelAccessToken?: string;
19
19
  readonly webhookPath?: string;
@@ -26,7 +26,7 @@ export interface LineAdapterConfig {
26
26
 
27
27
  export interface ResolvedLineConfig {
28
28
  readonly context: 'line';
29
- readonly name: string;
29
+ readonly id: string;
30
30
  readonly channelSecret: string;
31
31
  readonly channelAccessToken: string;
32
32
  readonly webhookPath: string;
@@ -174,8 +174,8 @@ export function resolveLineConfig(config: LineAdapterConfig = {}): ResolvedLineC
174
174
  'LINE adapter requires channelSecret + channelAccessToken (plugins.<key> or endpoints with context: line)',
175
175
  );
176
176
  }
177
- const name = (typeof config.name === 'string' && config.name)
178
- || (typeof entry?.name === 'string' && entry.name)
177
+ const id = (typeof config.id === 'string' && config.id)
178
+ || (typeof entry?.id === 'string' && entry.id)
179
179
  || process.env.LINE_BOT_NAME
180
180
  || 'line-bot';
181
181
  const webhookPath = normalizeWebhookPath(
@@ -184,7 +184,7 @@ export function resolveLineConfig(config: LineAdapterConfig = {}): ResolvedLineC
184
184
  const apiBaseUrl = (config.apiBaseUrl ?? entry?.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
185
185
  return {
186
186
  context: 'line',
187
- name,
187
+ id,
188
188
  channelSecret,
189
189
  channelAccessToken,
190
190
  webhookPath,
@@ -222,10 +222,10 @@ export function resolveChannel(source: LineSource): LineChannel {
222
222
  * 入站归一化 → ConversationRef:LINE user → private、group → group、room → channel。
223
223
  * LINE 没有 guild/频道容器概念,无 parent;recipient id 前缀(U/G/R)自带场景信息。
224
224
  */
225
- export function lineInboundConversation(endpointId: string, source: LineSource): ConversationRef {
225
+ export function lineInboundConversation(endpointKey: string, source: LineSource): ConversationRef {
226
226
  const channel = resolveChannel(source);
227
227
  return {
228
- endpoint: { id: endpointId, adapter: endpointId.split('\0')[0] ?? endpointId },
228
+ endpoint: { id: endpointKey, adapter: endpointKey.split('\0')[0] ?? endpointKey },
229
229
  kind: channel.channelType,
230
230
  id: channel.channelId,
231
231
  };
File without changes
File without changes
File without changes
File without changes