agent-messenger 2.10.0 → 2.10.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/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +15 -2
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/shared/chromium/decryptor.d.ts +6 -0
- package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
- package/dist/src/shared/chromium/decryptor.js +26 -6
- package/dist/src/shared/chromium/decryptor.js.map +1 -1
- package/e2e/channeltalk.e2e.test.ts +13 -13
- package/e2e/channeltalkbot.e2e.test.ts +13 -13
- package/e2e/discord.e2e.test.ts +24 -24
- package/e2e/discordbot.e2e.test.ts +16 -16
- package/e2e/instagram.e2e.test.ts +10 -10
- package/e2e/kakaotalk.e2e.test.ts +7 -7
- package/e2e/line.e2e.test.ts +8 -8
- package/e2e/slack.e2e.test.ts +34 -34
- package/e2e/slackbot.e2e.test.ts +14 -14
- package/e2e/teams.e2e.test.ts +23 -23
- package/e2e/telegram.e2e.test.ts +8 -8
- package/e2e/webex.e2e.test.ts +14 -14
- package/e2e/whatsapp.e2e.test.ts +8 -8
- package/e2e/whatsappbot.e2e.test.ts +6 -6
- 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-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/channeltalk/client.test.ts +26 -26
- package/src/platforms/channeltalk/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
- package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
- package/src/platforms/channeltalk/commands/group.test.ts +4 -4
- package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
- package/src/platforms/channeltalk/commands/message.test.ts +17 -17
- package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
- package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
- package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
- package/src/platforms/channeltalk/index.test.ts +23 -23
- package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
- package/src/platforms/channeltalk/types.test.ts +12 -12
- package/src/platforms/channeltalkbot/client.test.ts +14 -14
- package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
- package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
- package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalkbot/commands/whoami.test.ts +4 -4
- package/src/platforms/channeltalkbot/credential-manager.test.ts +27 -27
- package/src/platforms/channeltalkbot/index.test.ts +15 -15
- package/src/platforms/discord/client.test.ts +28 -28
- package/src/platforms/discord/commands/auth.test.ts +7 -7
- package/src/platforms/discord/commands/channel.test.ts +7 -7
- package/src/platforms/discord/commands/dm.test.ts +4 -4
- package/src/platforms/discord/commands/file.test.ts +4 -4
- package/src/platforms/discord/commands/friend.test.ts +6 -6
- package/src/platforms/discord/commands/member.test.ts +5 -5
- package/src/platforms/discord/commands/mention.test.ts +5 -5
- package/src/platforms/discord/commands/message.test.ts +9 -9
- package/src/platforms/discord/commands/note.test.ts +6 -6
- package/src/platforms/discord/commands/profile.test.ts +4 -4
- package/src/platforms/discord/commands/reaction.test.ts +5 -5
- package/src/platforms/discord/commands/server.test.ts +7 -7
- package/src/platforms/discord/commands/snapshot.test.ts +6 -6
- package/src/platforms/discord/commands/thread.test.ts +6 -6
- package/src/platforms/discord/commands/user.test.ts +5 -5
- package/src/platforms/discord/commands/whoami.test.ts +6 -6
- package/src/platforms/discord/credential-manager.test.ts +16 -16
- package/src/platforms/discord/ensure-auth.test.ts +8 -8
- package/src/platforms/discord/index.test.ts +17 -17
- package/src/platforms/discord/listener.test.ts +33 -33
- package/src/platforms/discord/token-extractor.test.ts +53 -53
- package/src/platforms/discord/types.test.ts +26 -26
- package/src/platforms/discordbot/client.test.ts +31 -31
- package/src/platforms/discordbot/commands/auth.test.ts +18 -18
- package/src/platforms/discordbot/commands/channel.test.ts +11 -11
- package/src/platforms/discordbot/commands/file.test.ts +7 -7
- package/src/platforms/discordbot/commands/message.test.ts +25 -25
- package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
- package/src/platforms/discordbot/commands/server.test.ts +12 -12
- package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
- package/src/platforms/discordbot/commands/thread.test.ts +10 -10
- package/src/platforms/discordbot/commands/user.test.ts +9 -9
- package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
- package/src/platforms/discordbot/credential-manager.test.ts +28 -28
- package/src/platforms/instagram/client.test.ts +18 -18
- package/src/platforms/instagram/commands/auth.test.ts +11 -11
- package/src/platforms/instagram/commands/chat.test.ts +6 -6
- package/src/platforms/instagram/commands/message.test.ts +11 -11
- package/src/platforms/instagram/commands/shared.test.ts +12 -12
- package/src/platforms/instagram/commands/whoami.test.ts +3 -3
- package/src/platforms/instagram/credential-manager.test.ts +21 -21
- package/src/platforms/instagram/ensure-auth.test.ts +4 -4
- package/src/platforms/instagram/index.test.ts +9 -9
- package/src/platforms/instagram/listener.test.ts +8 -8
- package/src/platforms/instagram/token-extractor.test.ts +35 -35
- package/src/platforms/kakaotalk/client.test.ts +33 -33
- package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
- package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
- package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
- package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
- package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
- package/src/platforms/kakaotalk/index.test.ts +15 -15
- package/src/platforms/kakaotalk/listener.test.ts +17 -17
- package/src/platforms/line/client.test.ts +17 -17
- package/src/platforms/line/commands/auth.test.ts +8 -8
- package/src/platforms/line/commands/chat.test.ts +7 -7
- package/src/platforms/line/commands/friend.test.ts +6 -6
- package/src/platforms/line/commands/message.test.ts +7 -7
- package/src/platforms/line/commands/whoami.test.ts +6 -6
- package/src/platforms/line/credential-manager.test.ts +17 -17
- package/src/platforms/line/index.test.ts +10 -10
- package/src/platforms/line/listener.test.ts +15 -15
- package/src/platforms/line/types.test.ts +14 -14
- package/src/platforms/slack/cli.test.ts +8 -8
- package/src/platforms/slack/client.test.ts +151 -151
- package/src/platforms/slack/commands/activity.test.ts +13 -13
- package/src/platforms/slack/commands/auth.test.ts +34 -34
- package/src/platforms/slack/commands/bookmark.test.ts +9 -9
- package/src/platforms/slack/commands/channel.test.ts +17 -17
- package/src/platforms/slack/commands/drafts.test.ts +7 -7
- package/src/platforms/slack/commands/emoji.test.ts +3 -3
- package/src/platforms/slack/commands/file.test.ts +12 -12
- package/src/platforms/slack/commands/message.test.ts +19 -19
- package/src/platforms/slack/commands/pin.test.ts +7 -7
- package/src/platforms/slack/commands/reaction.test.ts +10 -10
- package/src/platforms/slack/commands/reminder.test.ts +9 -9
- package/src/platforms/slack/commands/saved.test.ts +7 -7
- package/src/platforms/slack/commands/sections.test.ts +5 -5
- package/src/platforms/slack/commands/snapshot.test.ts +13 -13
- package/src/platforms/slack/commands/unread.test.ts +6 -6
- package/src/platforms/slack/commands/user.test.ts +10 -10
- package/src/platforms/slack/commands/usergroup.test.ts +15 -15
- package/src/platforms/slack/commands/whoami.test.ts +6 -6
- package/src/platforms/slack/commands/workspace.test.ts +26 -26
- package/src/platforms/slack/credential-manager.test.ts +14 -14
- package/src/platforms/slack/ensure-auth.test.ts +21 -21
- package/src/platforms/slack/index.test.ts +12 -12
- package/src/platforms/slack/listener.test.ts +17 -17
- package/src/platforms/slack/token-extractor-node.test.ts +2 -2
- package/src/platforms/slack/token-extractor.test.ts +37 -37
- package/src/platforms/slack/types.test.ts +21 -21
- package/src/platforms/slackbot/client.test.ts +22 -22
- package/src/platforms/slackbot/commands/auth.test.ts +14 -14
- package/src/platforms/slackbot/commands/channel.test.ts +7 -7
- package/src/platforms/slackbot/commands/message.test.ts +13 -13
- package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
- package/src/platforms/slackbot/commands/user.test.ts +7 -7
- package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
- package/src/platforms/slackbot/credential-manager.test.ts +22 -22
- package/src/platforms/slackbot/types.test.ts +7 -7
- package/src/platforms/teams/client.test.ts +30 -30
- package/src/platforms/teams/commands/auth.test.ts +8 -8
- package/src/platforms/teams/commands/channel.test.ts +7 -7
- package/src/platforms/teams/commands/file.test.ts +4 -4
- package/src/platforms/teams/commands/message.test.ts +5 -5
- package/src/platforms/teams/commands/reaction.test.ts +4 -4
- package/src/platforms/teams/commands/snapshot.test.ts +7 -7
- package/src/platforms/teams/commands/team.test.ts +8 -8
- package/src/platforms/teams/commands/user.test.ts +4 -4
- package/src/platforms/teams/commands/whoami.test.ts +6 -6
- package/src/platforms/teams/credential-manager.test.ts +17 -17
- package/src/platforms/teams/ensure-auth.test.ts +13 -13
- package/src/platforms/teams/index.test.ts +15 -15
- package/src/platforms/teams/token-extractor.test.ts +219 -145
- package/src/platforms/teams/token-extractor.ts +13 -2
- package/src/platforms/teams/types.test.ts +26 -26
- package/src/platforms/telegram/app-config.test.ts +4 -4
- package/src/platforms/telegram/chat-utils.test.ts +12 -12
- package/src/platforms/telegram/client.test.ts +4 -4
- package/src/platforms/telegram/commands/auth.test.ts +16 -16
- package/src/platforms/telegram/commands/chat.test.ts +9 -9
- package/src/platforms/telegram/commands/message.test.ts +6 -6
- package/src/platforms/telegram/commands/shared.test.ts +3 -3
- package/src/platforms/telegram/commands/whoami.test.ts +3 -3
- package/src/platforms/telegram/credential-manager.test.ts +10 -10
- package/src/platforms/telegram/types.test.ts +6 -6
- package/src/platforms/webex/app-config.test.ts +8 -8
- package/src/platforms/webex/cli.test.ts +5 -5
- package/src/platforms/webex/client.test.ts +65 -65
- package/src/platforms/webex/commands/auth.test.ts +18 -18
- package/src/platforms/webex/commands/member.test.ts +5 -5
- package/src/platforms/webex/commands/message.test.ts +12 -12
- package/src/platforms/webex/commands/snapshot.test.ts +5 -5
- package/src/platforms/webex/commands/space.test.ts +10 -10
- package/src/platforms/webex/commands/whoami.test.ts +6 -6
- package/src/platforms/webex/credential-manager.test.ts +22 -22
- package/src/platforms/webex/encryption.test.ts +4 -4
- package/src/platforms/webex/ensure-auth.test.ts +5 -5
- package/src/platforms/webex/index.test.ts +5 -5
- package/src/platforms/webex/markdown-to-html.test.ts +33 -33
- package/src/platforms/webex/token-extractor.test.ts +23 -23
- package/src/platforms/webex/types.test.ts +27 -27
- package/src/platforms/wechatbot/client.test.ts +27 -27
- package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
- package/src/platforms/wechatbot/commands/message.test.ts +8 -8
- package/src/platforms/wechatbot/commands/template.test.ts +9 -9
- package/src/platforms/wechatbot/commands/user.test.ts +7 -7
- package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
- package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
- package/src/platforms/wechatbot/index.test.ts +10 -10
- package/src/platforms/wechatbot/types.test.ts +25 -25
- package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
- package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
- package/src/platforms/whatsapp/commands/message.test.ts +10 -10
- package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
- package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
- package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
- package/src/platforms/whatsapp/index.test.ts +8 -8
- package/src/platforms/whatsapp/types.test.ts +42 -42
- package/src/platforms/whatsappbot/client.test.ts +27 -27
- package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
- package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
- package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
- package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
- package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
- package/src/platforms/whatsappbot/index.test.ts +7 -7
- package/src/platforms/whatsappbot/types.test.ts +18 -18
- package/src/shared/chromium/browsers.test.ts +22 -22
- package/src/shared/chromium/cookie-reader.test.ts +13 -13
- package/src/shared/chromium/decryptor.test.ts +97 -32
- package/src/shared/chromium/decryptor.ts +27 -6
- package/src/shared/utils/concurrency.test.ts +6 -6
- package/src/shared/utils/derived-key-cache.test.ts +11 -11
- package/src/tui/utils.test.ts +31 -31
package/e2e/webex.e2e.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, beforeAll, describe, expect,
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { WEBEX_TEST_SPACE_ID, WEBEX_TEST_DM_EMAIL, validateWebexEnvironment } from './config'
|
|
4
4
|
import { generateTestId, parseJSON, runCLI, waitForRateLimit } from './helpers'
|
|
@@ -31,7 +31,7 @@ describe('Webex E2E Tests', () => {
|
|
|
31
31
|
})
|
|
32
32
|
|
|
33
33
|
describe('auth', () => {
|
|
34
|
-
|
|
34
|
+
it('auth status returns authenticated', async () => {
|
|
35
35
|
if (!webexAvailable) return
|
|
36
36
|
|
|
37
37
|
const result = await runCLI('webex', ['auth', 'status'])
|
|
@@ -43,7 +43,7 @@ describe('Webex E2E Tests', () => {
|
|
|
43
43
|
})
|
|
44
44
|
|
|
45
45
|
describe('message', () => {
|
|
46
|
-
|
|
46
|
+
it('message send creates a message', async () => {
|
|
47
47
|
if (!webexAvailable) return
|
|
48
48
|
|
|
49
49
|
const testId = generateTestId()
|
|
@@ -56,7 +56,7 @@ describe('Webex E2E Tests', () => {
|
|
|
56
56
|
if (data?.id) testMessages.push(data.id)
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
it('message list returns messages array', async () => {
|
|
60
60
|
if (!webexAvailable) return
|
|
61
61
|
|
|
62
62
|
const result = await runCLI('webex', ['message', 'list', WEBEX_TEST_SPACE_ID, '--limit', '5'])
|
|
@@ -66,7 +66,7 @@ describe('Webex E2E Tests', () => {
|
|
|
66
66
|
expect(Array.isArray(data)).toBe(true)
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
it('message get retrieves specific message', async () => {
|
|
70
70
|
if (!webexAvailable) return
|
|
71
71
|
|
|
72
72
|
const testId = generateTestId()
|
|
@@ -86,7 +86,7 @@ describe('Webex E2E Tests', () => {
|
|
|
86
86
|
expect(data?.text).toContain(testId)
|
|
87
87
|
}, 30000)
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
it('message delete removes message', async () => {
|
|
90
90
|
if (!webexAvailable) return
|
|
91
91
|
|
|
92
92
|
const testId = generateTestId()
|
|
@@ -102,7 +102,7 @@ describe('Webex E2E Tests', () => {
|
|
|
102
102
|
expect(result.exitCode).toBe(0)
|
|
103
103
|
}, 30000)
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
it('message edit updates message content', async () => {
|
|
106
106
|
if (!webexAvailable) return
|
|
107
107
|
|
|
108
108
|
const testId = generateTestId()
|
|
@@ -139,7 +139,7 @@ describe('Webex E2E Tests', () => {
|
|
|
139
139
|
return runCLI('webex', args)
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
it('message edit survives second edit and markdown edit (regression for silent failure)', async () => {
|
|
143
143
|
if (!webexAvailable) return
|
|
144
144
|
|
|
145
145
|
const testId = generateTestId()
|
|
@@ -178,7 +178,7 @@ describe('Webex E2E Tests', () => {
|
|
|
178
178
|
})
|
|
179
179
|
|
|
180
180
|
describe('space', () => {
|
|
181
|
-
|
|
181
|
+
it('space list returns spaces array', async () => {
|
|
182
182
|
if (!webexAvailable) return
|
|
183
183
|
|
|
184
184
|
const result = await runCLI('webex', ['space', 'list', '--limit', '5'])
|
|
@@ -188,7 +188,7 @@ describe('Webex E2E Tests', () => {
|
|
|
188
188
|
expect(Array.isArray(data)).toBe(true)
|
|
189
189
|
})
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
it('space info returns space details', async () => {
|
|
192
192
|
if (!webexAvailable) return
|
|
193
193
|
|
|
194
194
|
const result = await runCLI('webex', ['space', 'info', WEBEX_TEST_SPACE_ID])
|
|
@@ -200,7 +200,7 @@ describe('Webex E2E Tests', () => {
|
|
|
200
200
|
})
|
|
201
201
|
|
|
202
202
|
describe('member', () => {
|
|
203
|
-
|
|
203
|
+
it('member list returns members array', async () => {
|
|
204
204
|
if (!webexAvailable) return
|
|
205
205
|
|
|
206
206
|
const result = await runCLI('webex', ['member', 'list', WEBEX_TEST_SPACE_ID, '--limit', '5'])
|
|
@@ -212,7 +212,7 @@ describe('Webex E2E Tests', () => {
|
|
|
212
212
|
})
|
|
213
213
|
|
|
214
214
|
describe('snapshot', () => {
|
|
215
|
-
|
|
215
|
+
it('snapshot returns spaces and members', async () => {
|
|
216
216
|
if (!webexAvailable) return
|
|
217
217
|
|
|
218
218
|
const result = await runCLI('webex', ['snapshot', '--limit', '2'])
|
|
@@ -224,7 +224,7 @@ describe('Webex E2E Tests', () => {
|
|
|
224
224
|
expect(data?.recent_messages).toBeDefined()
|
|
225
225
|
}, 30000)
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
it('snapshot --spaces-only returns only spaces', async () => {
|
|
228
228
|
if (!webexAvailable) return
|
|
229
229
|
|
|
230
230
|
const result = await runCLI('webex', ['snapshot', '--spaces-only'])
|
|
@@ -234,7 +234,7 @@ describe('Webex E2E Tests', () => {
|
|
|
234
234
|
expect(data?.spaces).toBeDefined()
|
|
235
235
|
})
|
|
236
236
|
|
|
237
|
-
|
|
237
|
+
it('snapshot --members-only returns only members', async () => {
|
|
238
238
|
if (!webexAvailable) return
|
|
239
239
|
|
|
240
240
|
const result = await runCLI('webex', ['snapshot', '--members-only'])
|
package/e2e/whatsapp.e2e.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, beforeAll, describe, expect,
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { WHATSAPP_TEST_CHAT_ID, validateWhatsAppEnvironment } from './config'
|
|
4
4
|
import { generateTestId, parseJSON, runCLI, waitForRateLimit } from './helpers'
|
|
@@ -15,14 +15,14 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
describe('auth', () => {
|
|
18
|
-
|
|
18
|
+
it('auth status returns exit code 0', async () => {
|
|
19
19
|
if (!whatsappAvailable) return
|
|
20
20
|
|
|
21
21
|
const result = await runCLI('whatsapp', ['auth', 'status'])
|
|
22
22
|
expect(result.exitCode).toBe(0)
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
it('auth list returns accounts array', async () => {
|
|
26
26
|
if (!whatsappAvailable) return
|
|
27
27
|
|
|
28
28
|
const result = await runCLI('whatsapp', ['auth', 'list'])
|
|
@@ -34,7 +34,7 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
describe('chat', () => {
|
|
37
|
-
|
|
37
|
+
it('chat list returns chats', async () => {
|
|
38
38
|
if (!whatsappAvailable) return
|
|
39
39
|
|
|
40
40
|
const result = await runCLI('whatsapp', ['chat', 'list', '--limit', '5'])
|
|
@@ -44,7 +44,7 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
44
44
|
expect(data).toBeTruthy()
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
it('chat search returns results', async () => {
|
|
48
48
|
if (!whatsappAvailable) return
|
|
49
49
|
|
|
50
50
|
const result = await runCLI('whatsapp', ['chat', 'search', 'test', '--limit', '5'])
|
|
@@ -53,7 +53,7 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
53
53
|
})
|
|
54
54
|
|
|
55
55
|
describe('message', () => {
|
|
56
|
-
|
|
56
|
+
it('message send delivers message to chat', async () => {
|
|
57
57
|
if (!whatsappAvailable) return
|
|
58
58
|
|
|
59
59
|
const testId = generateTestId()
|
|
@@ -61,7 +61,7 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
61
61
|
expect(result.exitCode).toBe(0)
|
|
62
62
|
})
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
it('message list returns messages', async () => {
|
|
65
65
|
if (!whatsappAvailable) return
|
|
66
66
|
|
|
67
67
|
const result = await runCLI('whatsapp', ['message', 'list', WHATSAPP_TEST_CHAT_ID, '--limit', '5'])
|
|
@@ -71,7 +71,7 @@ describe('WhatsApp E2E Tests', () => {
|
|
|
71
71
|
expect(data).toBeTruthy()
|
|
72
72
|
})
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
it('message react adds reaction to message', async () => {
|
|
75
75
|
if (!whatsappAvailable) return
|
|
76
76
|
|
|
77
77
|
const testId = generateTestId()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, beforeAll, describe, expect,
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { WHATSAPPBOT_TEST_PHONE_NUMBER, validateWhatsAppBotEnvironment } from './config'
|
|
4
4
|
import { generateTestId, parseJSON, runCLI, waitForRateLimit } from './helpers'
|
|
@@ -15,7 +15,7 @@ describe('WhatsApp Bot E2E Tests', () => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
describe('auth', () => {
|
|
18
|
-
|
|
18
|
+
it('auth status returns valid credentials', async () => {
|
|
19
19
|
if (!whatsappbotAvailable) return
|
|
20
20
|
|
|
21
21
|
const result = await runCLI('whatsappbot', ['auth', 'status'])
|
|
@@ -25,7 +25,7 @@ describe('WhatsApp Bot E2E Tests', () => {
|
|
|
25
25
|
expect(data?.valid).toBe(true)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
it('auth list returns accounts array', async () => {
|
|
29
29
|
if (!whatsappbotAvailable) return
|
|
30
30
|
|
|
31
31
|
const result = await runCLI('whatsappbot', ['auth', 'list'])
|
|
@@ -37,7 +37,7 @@ describe('WhatsApp Bot E2E Tests', () => {
|
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
describe('message', () => {
|
|
40
|
-
|
|
40
|
+
it('message send delivers to test phone number', async () => {
|
|
41
41
|
if (!whatsappbotAvailable) return
|
|
42
42
|
|
|
43
43
|
const testId = generateTestId()
|
|
@@ -47,7 +47,7 @@ describe('WhatsApp Bot E2E Tests', () => {
|
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
describe('template', () => {
|
|
50
|
-
|
|
50
|
+
it('template list returns templates', async () => {
|
|
51
51
|
if (!whatsappbotAvailable) return
|
|
52
52
|
|
|
53
53
|
const result = await runCLI('whatsappbot', ['template', 'list', '--limit', '5'])
|
|
@@ -57,7 +57,7 @@ describe('WhatsApp Bot E2E Tests', () => {
|
|
|
57
57
|
expect(data).toBeDefined()
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
it('template get returns template details', async () => {
|
|
61
61
|
if (!whatsappbotAvailable) return
|
|
62
62
|
|
|
63
63
|
const listResult = await runCLI('whatsappbot', ['template', 'list', '--limit', '1'])
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-channeltalk
|
|
3
3
|
description: Interact with Channel Talk using extracted desktop app or browser credentials - read chats, send messages, search messages, manage groups
|
|
4
|
-
version: 2.10.
|
|
4
|
+
version: 2.10.2
|
|
5
5
|
allowed-tools: Bash(agent-channeltalk:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect,
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import { ChannelClient } from './client'
|
|
4
4
|
import { ChannelError } from './types'
|
|
@@ -51,7 +51,7 @@ describe('ChannelClient', () => {
|
|
|
51
51
|
const getJsonBody = (callIndex = 0) =>
|
|
52
52
|
JSON.parse(String(fetchCalls[callIndex]?.options?.body)) as Record<string, unknown>
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
it('login() requires account cookie', async () => {
|
|
55
55
|
await expect(new ChannelClient().login({ accountCookie: '' })).rejects.toThrow(ChannelError)
|
|
56
56
|
await expect(new ChannelClient().login({ accountCookie: '', sessionCookie: 'session-cookie' })).rejects.toThrow(
|
|
57
57
|
ChannelError,
|
|
@@ -62,7 +62,7 @@ describe('ChannelClient', () => {
|
|
|
62
62
|
expect(client2).toBeInstanceOf(ChannelClient)
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
it('successful GET request returns unwrapped JSON', async () => {
|
|
66
66
|
mockResponse({
|
|
67
67
|
account: {
|
|
68
68
|
id: 'acc-1',
|
|
@@ -82,7 +82,7 @@ describe('ChannelClient', () => {
|
|
|
82
82
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/account')
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
it('cookie auth headers are set on every request', async () => {
|
|
86
86
|
mockResponse({
|
|
87
87
|
account: {
|
|
88
88
|
id: 'acc-1',
|
|
@@ -108,7 +108,7 @@ describe('ChannelClient', () => {
|
|
|
108
108
|
}
|
|
109
109
|
})
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
it('429 response triggers retry with Retry-After wait', async () => {
|
|
112
112
|
mockResponse({ errors: [{ message: 'Rate limited' }] }, 429, { 'Retry-After': '0.05' })
|
|
113
113
|
mockResponse({
|
|
114
114
|
account: {
|
|
@@ -132,7 +132,7 @@ describe('ChannelClient', () => {
|
|
|
132
132
|
expect(elapsed).toBeGreaterThanOrEqual(40)
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
it('500 response triggers retry with exponential backoff for GET requests', async () => {
|
|
136
136
|
mockResponse({ errors: [{ message: 'Server error' }] }, 500)
|
|
137
137
|
mockResponse({ errors: [{ message: 'Server error' }] }, 500)
|
|
138
138
|
mockResponse({
|
|
@@ -157,7 +157,7 @@ describe('ChannelClient', () => {
|
|
|
157
157
|
expect(elapsed).toBeGreaterThanOrEqual(280)
|
|
158
158
|
})
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
it('4xx non-429 throws immediately without retry', async () => {
|
|
161
161
|
mockResponse({ type: 'forbidden', errors: [{ message: 'Forbidden' }] }, 403)
|
|
162
162
|
|
|
163
163
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -165,7 +165,7 @@ describe('ChannelClient', () => {
|
|
|
165
165
|
expect(fetchCalls).toHaveLength(1)
|
|
166
166
|
})
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
it('network error retries then throws ChannelError with code network_error', async () => {
|
|
169
169
|
;(globalThis as Record<string, unknown>).fetch = async (
|
|
170
170
|
url: string | URL | Request,
|
|
171
171
|
options?: RequestInit,
|
|
@@ -186,7 +186,7 @@ describe('ChannelClient', () => {
|
|
|
186
186
|
}
|
|
187
187
|
})
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
it('204 response returns undefined', async () => {
|
|
190
190
|
mockResponse(null, 204)
|
|
191
191
|
|
|
192
192
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -197,7 +197,7 @@ describe('ChannelClient', () => {
|
|
|
197
197
|
expect(result).toBeUndefined()
|
|
198
198
|
})
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
it('wrapTextInBlocks returns a single text block and extractText joins block and plain text', () => {
|
|
201
201
|
expect(ChannelClient.wrapTextInBlocks('Hello world')).toEqual([{ type: 'text', value: 'Hello world' }])
|
|
202
202
|
|
|
203
203
|
expect(
|
|
@@ -212,7 +212,7 @@ describe('ChannelClient', () => {
|
|
|
212
212
|
).toBe('hello\nworld\nfallback')
|
|
213
213
|
})
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
it('listChannels includes query params', async () => {
|
|
216
216
|
mockResponse({ channels: [{ id: 'ch-1', name: 'Support' }] })
|
|
217
217
|
|
|
218
218
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -222,7 +222,7 @@ describe('ChannelClient', () => {
|
|
|
222
222
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels?limit=500')
|
|
223
223
|
})
|
|
224
224
|
|
|
225
|
-
|
|
225
|
+
it('getChannel uses the channel detail endpoint', async () => {
|
|
226
226
|
mockResponse({ channel: { id: 'ch-1', name: 'Support' } })
|
|
227
227
|
|
|
228
228
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -231,7 +231,7 @@ describe('ChannelClient', () => {
|
|
|
231
231
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1')
|
|
232
232
|
})
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
it('listManagers uses the managers endpoint', async () => {
|
|
235
235
|
mockResponse({ managers: [{ id: 'mgr-1', channelId: 'ch-1', accountId: 'acc-1', name: 'Alex' }] })
|
|
236
236
|
|
|
237
237
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -241,7 +241,7 @@ describe('ChannelClient', () => {
|
|
|
241
241
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/managers?limit=200')
|
|
242
242
|
})
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
it('getManagerRole unwraps the role response', async () => {
|
|
245
245
|
mockResponse({ role: { permissions: ['read'] } })
|
|
246
246
|
|
|
247
247
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -251,7 +251,7 @@ describe('ChannelClient', () => {
|
|
|
251
251
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/managers/me/role')
|
|
252
252
|
})
|
|
253
253
|
|
|
254
|
-
|
|
254
|
+
it('group endpoints build the expected URLs', async () => {
|
|
255
255
|
mockResponse({ groups: [{ id: 'grp-1', channelId: 'ch-1', name: 'ops' }] })
|
|
256
256
|
mockResponse({ group: { id: 'grp-1', channelId: 'ch-1', name: 'ops' } })
|
|
257
257
|
mockResponse({ messages: [{ id: 'msg-1' }] })
|
|
@@ -273,7 +273,7 @@ describe('ChannelClient', () => {
|
|
|
273
273
|
expect(messagesUrl.searchParams.get('since')).toBe('cursor-1')
|
|
274
274
|
})
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
it('sendGroupMessage includes requestId in the body', async () => {
|
|
277
277
|
mockResponse({ message: { id: 'msg-1', requestId: 'req-123' } })
|
|
278
278
|
|
|
279
279
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -285,7 +285,7 @@ describe('ChannelClient', () => {
|
|
|
285
285
|
expect(getJsonBody()).toEqual({ blocks, requestId: 'req-123' })
|
|
286
286
|
})
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
it('direct chat endpoints build the expected URLs', async () => {
|
|
289
289
|
mockResponse({ directChats: [{ id: 'dm-1', channelId: 'ch-1' }] })
|
|
290
290
|
mockResponse({ messages: [{ id: 'msg-1' }] })
|
|
291
291
|
mockResponse({ message: { id: 'msg-2', requestId: 'req-234' } })
|
|
@@ -305,7 +305,7 @@ describe('ChannelClient', () => {
|
|
|
305
305
|
expect(getJsonBody(2)).toEqual({ blocks, requestId: 'req-234' })
|
|
306
306
|
})
|
|
307
307
|
|
|
308
|
-
|
|
308
|
+
it('user chat endpoints build the expected URLs', async () => {
|
|
309
309
|
mockResponse({ userChats: [{ id: 'uc-1', channelId: 'ch-1', state: 'opened' }] })
|
|
310
310
|
mockResponse({ userChat: { id: 'uc-1', channelId: 'ch-1', state: 'opened' } })
|
|
311
311
|
mockResponse({ messages: [{ id: 'msg-1' }] })
|
|
@@ -330,7 +330,7 @@ describe('ChannelClient', () => {
|
|
|
330
330
|
expect(getJsonBody(3)).toEqual({ blocks, requestId: 'req-345' })
|
|
331
331
|
})
|
|
332
332
|
|
|
333
|
-
|
|
333
|
+
it('listBots uses the bots endpoint', async () => {
|
|
334
334
|
mockResponse({ bots: [{ id: 'bot-1', channelId: 'ch-1', name: 'DeskBot' }] })
|
|
335
335
|
|
|
336
336
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -340,7 +340,7 @@ describe('ChannelClient', () => {
|
|
|
340
340
|
expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/bots?limit=1000')
|
|
341
341
|
})
|
|
342
342
|
|
|
343
|
-
|
|
343
|
+
it('5xx on POST does not retry', async () => {
|
|
344
344
|
mockResponse({ type: 'server_error', errors: [{ message: 'Server error' }] }, 500)
|
|
345
345
|
|
|
346
346
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -350,7 +350,7 @@ describe('ChannelClient', () => {
|
|
|
350
350
|
expect(fetchCalls).toHaveLength(1)
|
|
351
351
|
})
|
|
352
352
|
|
|
353
|
-
|
|
353
|
+
it('error responses use desk API error fields', async () => {
|
|
354
354
|
mockResponse({ type: 'not_found', status: 404, errors: [{ message: 'Missing resource' }], language: 'en' }, 404)
|
|
355
355
|
|
|
356
356
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -365,7 +365,7 @@ describe('ChannelClient', () => {
|
|
|
365
365
|
}
|
|
366
366
|
})
|
|
367
367
|
|
|
368
|
-
|
|
368
|
+
it('rate limit headers delay the next request when remaining is zero', async () => {
|
|
369
369
|
mockResponse(
|
|
370
370
|
{
|
|
371
371
|
account: {
|
|
@@ -407,7 +407,7 @@ describe('ChannelClient', () => {
|
|
|
407
407
|
expect(fetchCalls).toHaveLength(2)
|
|
408
408
|
})
|
|
409
409
|
|
|
410
|
-
|
|
410
|
+
it('generated requests still include the cookie header on post endpoints', async () => {
|
|
411
411
|
mockResponse({ message: { id: 'msg-1' } })
|
|
412
412
|
|
|
413
413
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|
|
@@ -416,7 +416,7 @@ describe('ChannelClient', () => {
|
|
|
416
416
|
expect(getHeaders().Cookie).toBe('x-account=account-cookie; ch-session-1=session-cookie')
|
|
417
417
|
})
|
|
418
418
|
|
|
419
|
-
|
|
419
|
+
it('searchTeamChatMessages builds correct URL with query and limit', async () => {
|
|
420
420
|
const searchResponse = {
|
|
421
421
|
hits: [
|
|
422
422
|
{
|
|
@@ -443,7 +443,7 @@ describe('ChannelClient', () => {
|
|
|
443
443
|
expect(result.hits).toHaveLength(1)
|
|
444
444
|
})
|
|
445
445
|
|
|
446
|
-
|
|
446
|
+
it('searchUserChatMessages builds correct URL with query', async () => {
|
|
447
447
|
const searchResponse = {
|
|
448
448
|
hits: [],
|
|
449
449
|
bots: [],
|
|
@@ -461,7 +461,7 @@ describe('ChannelClient', () => {
|
|
|
461
461
|
expect(result.hits).toHaveLength(0)
|
|
462
462
|
})
|
|
463
463
|
|
|
464
|
-
|
|
464
|
+
it('searchTeamChatMessages works without limit parameter', async () => {
|
|
465
465
|
mockResponse({ hits: [], bots: [], sessions: [] })
|
|
466
466
|
|
|
467
467
|
const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
|