agent-messenger 2.19.1 → 2.19.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 (32) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/src/platforms/line/client.d.ts +27 -0
  4. package/dist/src/platforms/line/client.d.ts.map +1 -1
  5. package/dist/src/platforms/line/client.js +85 -7
  6. package/dist/src/platforms/line/client.js.map +1 -1
  7. package/dist/src/platforms/line/listener.d.ts +3 -0
  8. package/dist/src/platforms/line/listener.d.ts.map +1 -1
  9. package/dist/src/platforms/line/listener.js +57 -47
  10. package/dist/src/platforms/line/listener.js.map +1 -1
  11. package/docs/content/docs/cli/line.mdx +10 -9
  12. package/package.json +1 -1
  13. package/skills/agent-channeltalk/SKILL.md +1 -1
  14. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  15. package/skills/agent-discord/SKILL.md +1 -1
  16. package/skills/agent-discordbot/SKILL.md +1 -1
  17. package/skills/agent-instagram/SKILL.md +1 -1
  18. package/skills/agent-kakaotalk/SKILL.md +1 -1
  19. package/skills/agent-line/SKILL.md +2 -1
  20. package/skills/agent-slack/SKILL.md +1 -1
  21. package/skills/agent-slackbot/SKILL.md +1 -1
  22. package/skills/agent-teams/SKILL.md +1 -1
  23. package/skills/agent-telegram/SKILL.md +1 -1
  24. package/skills/agent-telegrambot/SKILL.md +1 -1
  25. package/skills/agent-webex/SKILL.md +1 -1
  26. package/skills/agent-wechatbot/SKILL.md +1 -1
  27. package/skills/agent-whatsapp/SKILL.md +1 -1
  28. package/skills/agent-whatsappbot/SKILL.md +1 -1
  29. package/src/platforms/line/client.test.ts +174 -1
  30. package/src/platforms/line/client.ts +105 -7
  31. package/src/platforms/line/listener.test.ts +106 -31
  32. package/src/platforms/line/listener.ts +56 -51
@@ -2,7 +2,6 @@ import { EventEmitter } from 'events'
2
2
 
3
3
  import type { LineClient } from './client'
4
4
  import type { LineListenerEventMap, LinePushGenericEvent, LinePushMessageEvent } from './types'
5
- import { LineError } from './types'
6
5
 
7
6
  const RECONNECT_BASE_DELAY = 1_000
8
7
  const RECONNECT_MAX_DELAY = 30_000
@@ -61,59 +60,13 @@ export class LineListener {
61
60
  await this.lineClient.login()
62
61
  if (!this.running) return
63
62
 
64
- const internalClient = (this.lineClient as any).client
65
- if (!internalClient) {
66
- throw new LineError('not_connected', 'Failed to get internal LINE client')
67
- }
68
-
63
+ const profile = await this.lineClient.getProfile()
64
+ if (!this.running) return
69
65
  this.abortController = new AbortController()
70
-
71
- internalClient.on('message', (msg: any) => {
72
- try {
73
- const toType = msg.raw.toType
74
- const isGroupOrRoom = toType === 'GROUP' || toType === 'ROOM' || toType === 0 || toType === 1
75
- const chatId = isGroupOrRoom ? msg.to.id : msg.isMyMessage ? msg.to.id : msg.from.id
76
-
77
- const event: LinePushMessageEvent = {
78
- type: 'message',
79
- chat_id: chatId,
80
- message_id: String(msg.raw.id),
81
- author_id: msg.from.id,
82
- text: msg.text ?? null,
83
- content_type: String(msg.raw.contentType ?? 'NONE'),
84
- sent_at: new Date(Number(msg.raw.createdTime)).toISOString(),
85
- }
86
- this.emitter.emit('message', event)
87
- this.emitter.emit('line_event', { ...event })
88
- } catch (error) {
89
- this.emitter.emit('error', error instanceof Error ? error : new Error(String(error)))
90
- }
91
- })
92
-
93
- internalClient.on('event', (op: any) => {
94
- const event: LinePushGenericEvent = {
95
- type: String(op.type ?? 'unknown'),
96
- ...(op.revision !== undefined && { revision: String(op.revision) }),
97
- ...(op.createdTime !== undefined && {
98
- created_time: new Date(Number(op.createdTime)).toISOString(),
99
- }),
100
- }
101
- this.emitter.emit('line_event', event)
102
- })
103
-
104
- internalClient.listen({ signal: this.abortController.signal })?.catch((error: unknown) => {
105
- if (!this.running) return
106
- const err = error instanceof Error ? error : new Error(String(error))
107
- if (err.name === 'AbortError') return
108
- this.emitter.emit('error', err)
109
- this.emitter.emit('disconnected')
110
- this.scheduleReconnect()
111
- })
112
-
113
66
  this.reconnectAttempts = 0
114
-
115
- const profile = await internalClient.base.talk.getProfile()
116
67
  this.emitter.emit('connected', { account_id: profile.mid })
68
+
69
+ void this.pump(this.abortController.signal)
117
70
  } catch (error) {
118
71
  this.emitter.emit('error', error instanceof Error ? error : new Error(String(error)))
119
72
  if (this.running) {
@@ -122,6 +75,58 @@ export class LineListener {
122
75
  }
123
76
  }
124
77
 
78
+ private async pump(signal: AbortSignal): Promise<void> {
79
+ try {
80
+ for await (const event of this.lineClient.streamEvents(signal)) {
81
+ if (event.kind === 'message') {
82
+ this.emitMessage(event.message)
83
+ } else {
84
+ this.emitOperation(event.op)
85
+ }
86
+ }
87
+ } catch (error) {
88
+ if (!this.running || signal.aborted) return
89
+ const err = error instanceof Error ? error : new Error(String(error))
90
+ if (err.name === 'AbortError') return
91
+ this.emitter.emit('error', err)
92
+ this.emitter.emit('disconnected')
93
+ this.scheduleReconnect()
94
+ }
95
+ }
96
+
97
+ private emitMessage(msg: any): void {
98
+ try {
99
+ const toType = msg.raw.toType
100
+ const isGroupOrRoom = toType === 'GROUP' || toType === 'ROOM' || toType === 0 || toType === 1
101
+ const chatId = isGroupOrRoom ? msg.to.id : msg.isMyMessage ? msg.to.id : msg.from.id
102
+
103
+ const event: LinePushMessageEvent = {
104
+ type: 'message',
105
+ chat_id: chatId,
106
+ message_id: String(msg.raw.id),
107
+ author_id: msg.from.id,
108
+ text: msg.text ?? null,
109
+ content_type: String(msg.raw.contentType ?? 'NONE'),
110
+ sent_at: new Date(Number(msg.raw.createdTime)).toISOString(),
111
+ }
112
+ this.emitter.emit('message', event)
113
+ this.emitter.emit('line_event', { ...event })
114
+ } catch (error) {
115
+ this.emitter.emit('error', error instanceof Error ? error : new Error(String(error)))
116
+ }
117
+ }
118
+
119
+ private emitOperation(op: any): void {
120
+ const event: LinePushGenericEvent = {
121
+ type: String(op.type ?? 'unknown'),
122
+ ...(op.revision !== undefined && { revision: String(op.revision) }),
123
+ ...(op.createdTime !== undefined && {
124
+ created_time: new Date(Number(op.createdTime)).toISOString(),
125
+ }),
126
+ }
127
+ this.emitter.emit('line_event', event)
128
+ }
129
+
125
130
  private scheduleReconnect(): void {
126
131
  this.clearTimers()
127
132
  const delay = Math.min(RECONNECT_BASE_DELAY * 2 ** this.reconnectAttempts, RECONNECT_MAX_DELAY)