agent-messenger 2.12.1 → 2.12.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.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/package.json +1 -1
- package/dist/src/platforms/kakaotalk/client.d.ts +22 -0
- package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/client.js +93 -7
- package/dist/src/platforms/kakaotalk/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/listener.d.ts +4 -7
- package/dist/src/platforms/kakaotalk/listener.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/listener.js +43 -72
- package/dist/src/platforms/kakaotalk/listener.js.map +1 -1
- package/package.json +1 -1
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +1 -1
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/kakaotalk/client-listener-integration.test.ts +411 -0
- package/src/platforms/kakaotalk/client.test.ts +3 -0
- package/src/platforms/kakaotalk/client.ts +108 -9
- package/src/platforms/kakaotalk/listener.test.ts +155 -149
- package/src/platforms/kakaotalk/listener.ts +46 -80
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'events'
|
|
2
2
|
|
|
3
|
-
import type { KakaoTalkClient } from './client'
|
|
4
|
-
import { LocoSession } from './protocol/session'
|
|
3
|
+
import type { KakaoSessionEvent, KakaoTalkClient } from './client'
|
|
5
4
|
import type { LocoPacket } from './protocol/types'
|
|
6
5
|
import type {
|
|
7
6
|
KakaoTalkListenerEventMap,
|
|
@@ -11,9 +10,6 @@ import type {
|
|
|
11
10
|
KakaoTalkPushReadEvent,
|
|
12
11
|
} from './types'
|
|
13
12
|
|
|
14
|
-
const RECONNECT_BASE_DELAY = 1_000
|
|
15
|
-
const RECONNECT_MAX_DELAY = 30_000
|
|
16
|
-
|
|
17
13
|
type EventKey = keyof KakaoTalkListenerEventMap
|
|
18
14
|
|
|
19
15
|
function longToString(v: unknown): string {
|
|
@@ -27,11 +23,9 @@ function longToString(v: unknown): string {
|
|
|
27
23
|
export class KakaoTalkListener {
|
|
28
24
|
private client: KakaoTalkClient
|
|
29
25
|
private running = false
|
|
30
|
-
private session: LocoSession | null = null
|
|
31
26
|
private emitter = new EventEmitter()
|
|
32
|
-
private
|
|
33
|
-
private
|
|
34
|
-
private userId: string | null = null
|
|
27
|
+
private unsubscribePush: (() => void) | null = null
|
|
28
|
+
private unsubscribeSession: (() => void) | null = null
|
|
35
29
|
|
|
36
30
|
constructor(client: KakaoTalkClient) {
|
|
37
31
|
this.client = client
|
|
@@ -40,17 +34,33 @@ export class KakaoTalkListener {
|
|
|
40
34
|
async start(): Promise<void> {
|
|
41
35
|
if (this.running) return
|
|
42
36
|
this.running = true
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
|
|
38
|
+
this.unsubscribePush = this.client.onPush((packet) => this.handlePush(packet))
|
|
39
|
+
this.unsubscribeSession = this.client.onSessionEvent((event) => this.handleSessionEvent(event))
|
|
40
|
+
|
|
41
|
+
const alreadyConnected = this.client.isConnected()
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await this.client.acquireSession()
|
|
45
|
+
if (!this.running) return
|
|
46
|
+
if (alreadyConnected) {
|
|
47
|
+
const { userId } = this.client.getCredentials()
|
|
48
|
+
this.emitter.emit('connected', { userId })
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
this.emitter.emit('error', error instanceof Error ? error : new Error(String(error)))
|
|
52
|
+
this.running = false
|
|
53
|
+
this.teardown()
|
|
54
|
+
}
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
stop(): void {
|
|
48
|
-
this.running
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.session.close()
|
|
52
|
-
this.session = null
|
|
58
|
+
if (!this.running) {
|
|
59
|
+
this.teardown()
|
|
60
|
+
return
|
|
53
61
|
}
|
|
62
|
+
this.running = false
|
|
63
|
+
this.teardown()
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
on<K extends EventKey>(event: K, listener: (...args: KakaoTalkListenerEventMap[K]) => void): this {
|
|
@@ -68,41 +78,28 @@ export class KakaoTalkListener {
|
|
|
68
78
|
return this
|
|
69
79
|
}
|
|
70
80
|
|
|
71
|
-
private
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.userId = userId
|
|
79
|
-
const session = new LocoSession()
|
|
80
|
-
|
|
81
|
-
session.onPush((packet) => this.handlePush(packet))
|
|
82
|
-
session.onClose(() => {
|
|
83
|
-
if (this.session !== session) return
|
|
84
|
-
this.session = null
|
|
85
|
-
if (this.running) {
|
|
86
|
-
this.emitter.emit('disconnected')
|
|
87
|
-
this.scheduleReconnect()
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
await session.login(oauthToken, userId, deviceUuid, undefined, deviceType)
|
|
81
|
+
private teardown(): void {
|
|
82
|
+
this.unsubscribePush?.()
|
|
83
|
+
this.unsubscribePush = null
|
|
84
|
+
this.unsubscribeSession?.()
|
|
85
|
+
this.unsubscribeSession = null
|
|
86
|
+
}
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return
|
|
96
|
-
}
|
|
88
|
+
private handleSessionEvent(event: KakaoSessionEvent): void {
|
|
89
|
+
if (!this.running) return
|
|
97
90
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
91
|
+
switch (event.type) {
|
|
92
|
+
case 'connected':
|
|
93
|
+
this.emitter.emit('connected', { userId: event.userId })
|
|
94
|
+
break
|
|
95
|
+
case 'disconnected':
|
|
96
|
+
this.emitter.emit('disconnected')
|
|
97
|
+
break
|
|
98
|
+
case 'kicked':
|
|
99
|
+
this.emitter.emit('error', new Error(event.reason))
|
|
100
|
+
this.running = false
|
|
101
|
+
this.teardown()
|
|
102
|
+
break
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
@@ -162,23 +159,6 @@ export class KakaoTalkListener {
|
|
|
162
159
|
break
|
|
163
160
|
}
|
|
164
161
|
|
|
165
|
-
case 'CHANGESVR': {
|
|
166
|
-
this.reconnectAttempts = 0
|
|
167
|
-
const prev = this.session
|
|
168
|
-
this.session = null
|
|
169
|
-
prev?.close()
|
|
170
|
-
this.connect()
|
|
171
|
-
break
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
case 'KICKOUT': {
|
|
175
|
-
this.emitter.emit('error', new Error('Session kicked — another device logged in'))
|
|
176
|
-
this.running = false
|
|
177
|
-
this.session?.close()
|
|
178
|
-
this.session = null
|
|
179
|
-
break
|
|
180
|
-
}
|
|
181
|
-
|
|
182
162
|
default: {
|
|
183
163
|
const event: KakaoTalkPushGenericEvent = { type: method, ...body }
|
|
184
164
|
this.emitter.emit('kakaotalk_event', event)
|
|
@@ -186,18 +166,4 @@ export class KakaoTalkListener {
|
|
|
186
166
|
}
|
|
187
167
|
}
|
|
188
168
|
}
|
|
189
|
-
|
|
190
|
-
private scheduleReconnect(): void {
|
|
191
|
-
this.clearTimers()
|
|
192
|
-
const delay = Math.min(RECONNECT_BASE_DELAY * 2 ** this.reconnectAttempts, RECONNECT_MAX_DELAY)
|
|
193
|
-
this.reconnectAttempts++
|
|
194
|
-
this.reconnectTimer = setTimeout(() => this.connect(), delay)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private clearTimers(): void {
|
|
198
|
-
if (this.reconnectTimer) {
|
|
199
|
-
clearTimeout(this.reconnectTimer)
|
|
200
|
-
this.reconnectTimer = null
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
169
|
}
|