agent-messenger 2.3.0 → 2.4.0
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/README.md +16 -16
- package/.claude-plugin/marketplace.json +29 -29
- package/.claude-plugin/plugin.json +5 -5
- package/CONTRIBUTING.md +1 -1
- package/README.md +8 -5
- package/bun.lock +70 -110
- package/bunfig.toml +3 -0
- package/dist/package.json +11 -3
- package/dist/src/platforms/discordbot/client.js +2 -2
- package/dist/src/platforms/discordbot/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/cli.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/cli.js +2 -1
- package/dist/src/platforms/kakaotalk/cli.js.map +1 -1
- package/dist/src/platforms/kakaotalk/client.d.ts +2 -1
- package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/client.js +52 -2
- package/dist/src/platforms/kakaotalk/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/index.d.ts +1 -0
- package/dist/src/platforms/kakaotalk/commands/index.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/index.js +1 -0
- package/dist/src/platforms/kakaotalk/commands/index.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/profile.d.ts +3 -0
- package/dist/src/platforms/kakaotalk/commands/profile.d.ts.map +1 -0
- package/dist/src/platforms/kakaotalk/commands/profile.js +19 -0
- package/dist/src/platforms/kakaotalk/commands/profile.js.map +1 -0
- package/dist/src/platforms/kakaotalk/index.d.ts +2 -2
- package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/index.js +1 -1
- package/dist/src/platforms/kakaotalk/index.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.js +2 -1
- package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
- package/dist/src/platforms/kakaotalk/types.d.ts +16 -0
- package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/types.js +8 -0
- package/dist/src/platforms/kakaotalk/types.js.map +1 -1
- package/dist/src/platforms/line/client.d.ts.map +1 -1
- package/dist/src/platforms/line/client.js +9 -36
- package/dist/src/platforms/line/client.js.map +1 -1
- package/dist/src/platforms/line/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/line/commands/auth.js +32 -20
- package/dist/src/platforms/line/commands/auth.js.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.js +2 -0
- package/dist/src/platforms/teams/commands/reaction.js.map +1 -1
- package/dist/src/platforms/wechatbot/cli.d.ts +5 -0
- package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/cli.js +18 -0
- package/dist/src/platforms/wechatbot/cli.js.map +1 -0
- package/dist/src/platforms/wechatbot/client.d.ts +36 -0
- package/dist/src/platforms/wechatbot/client.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/client.js +208 -0
- package/dist/src/platforms/wechatbot/client.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/auth.d.ts +28 -0
- package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/auth.js +164 -0
- package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/index.d.ts +5 -0
- package/dist/src/platforms/wechatbot/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/index.js +5 -0
- package/dist/src/platforms/wechatbot/commands/index.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/message.d.ts +18 -0
- package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/message.js +80 -0
- package/dist/src/platforms/wechatbot/commands/message.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/shared.d.ts +9 -0
- package/dist/src/platforms/wechatbot/commands/shared.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/shared.js +13 -0
- package/dist/src/platforms/wechatbot/commands/shared.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/template.d.ts +19 -0
- package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/template.js +76 -0
- package/dist/src/platforms/wechatbot/commands/template.js.map +1 -0
- package/dist/src/platforms/wechatbot/commands/user.d.ts +20 -0
- package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/commands/user.js +53 -0
- package/dist/src/platforms/wechatbot/commands/user.js.map +1 -0
- package/dist/src/platforms/wechatbot/credential-manager.d.ts +17 -0
- package/dist/src/platforms/wechatbot/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/credential-manager.js +121 -0
- package/dist/src/platforms/wechatbot/credential-manager.js.map +1 -0
- package/dist/src/platforms/wechatbot/index.d.ts +5 -0
- package/dist/src/platforms/wechatbot/index.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/index.js +4 -0
- package/dist/src/platforms/wechatbot/index.js.map +1 -0
- package/dist/src/platforms/wechatbot/types.d.ts +94 -0
- package/dist/src/platforms/wechatbot/types.d.ts.map +1 -0
- package/dist/src/platforms/wechatbot/types.js +54 -0
- package/dist/src/platforms/wechatbot/types.js.map +1 -0
- package/dist/src/platforms/whatsapp/client.d.ts +1 -0
- package/dist/src/platforms/whatsapp/client.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/client.js +27 -13
- package/dist/src/platforms/whatsapp/client.js.map +1 -1
- package/dist/src/platforms/whatsapp/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/commands/auth.js +21 -18
- package/dist/src/platforms/whatsapp/commands/auth.js.map +1 -1
- package/dist/src/platforms/whatsapp/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/credential-manager.js +14 -8
- package/dist/src/platforms/whatsapp/credential-manager.js.map +1 -1
- package/docs/content/docs/agent-skills.mdx +4 -4
- package/docs/content/docs/cli/channeltalk.mdx +1 -1
- package/docs/content/docs/cli/channeltalkbot.mdx +1 -1
- package/docs/content/docs/cli/discord.mdx +1 -1
- package/docs/content/docs/cli/discordbot.mdx +1 -1
- package/docs/content/docs/cli/instagram.mdx +1 -1
- package/docs/content/docs/cli/kakaotalk.mdx +1 -1
- package/docs/content/docs/cli/line.mdx +1 -1
- package/docs/content/docs/cli/meta.json +1 -0
- package/docs/content/docs/cli/slack.mdx +1 -1
- package/docs/content/docs/cli/slackbot.mdx +1 -1
- package/docs/content/docs/cli/teams.mdx +1 -1
- package/docs/content/docs/cli/webex.mdx +1 -1
- package/docs/content/docs/cli/wechatbot.mdx +179 -0
- package/docs/content/docs/cli/whatsapp.mdx +1 -1
- package/docs/content/docs/cli/whatsappbot.mdx +1 -1
- package/docs/content/docs/sdk/meta.json +1 -1
- package/docs/content/docs/sdk/wechatbot.mdx +282 -0
- package/docs/content/docs/tui.mdx +1 -1
- package/docs/src/app/page.tsx +5 -5
- package/package.json +11 -3
- 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 +24 -1
- package/skills/agent-line/SKILL.md +7 -11
- package/skills/agent-line/references/authentication.md +13 -4
- 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 +385 -0
- package/skills/agent-whatsapp/SKILL.md +12 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/discord/credential-manager.test.ts +18 -1
- package/src/platforms/discordbot/client.ts +2 -2
- package/src/platforms/instagram/commands/auth.test.ts +216 -0
- package/src/platforms/instagram/commands/chat.test.ts +127 -0
- package/src/platforms/instagram/commands/message.test.ts +178 -0
- package/src/platforms/kakaotalk/cli.ts +2 -1
- package/src/platforms/kakaotalk/client.test.ts +157 -0
- package/src/platforms/kakaotalk/client.ts +57 -3
- package/src/platforms/kakaotalk/commands/auth.test.ts +299 -0
- package/src/platforms/kakaotalk/commands/chat.test.ts +97 -0
- package/src/platforms/kakaotalk/commands/index.ts +1 -0
- package/src/platforms/kakaotalk/commands/message.test.ts +113 -0
- package/src/platforms/kakaotalk/commands/profile.test.ts +84 -0
- package/src/platforms/kakaotalk/commands/profile.ts +21 -0
- package/src/platforms/kakaotalk/index.test.ts +5 -0
- package/src/platforms/kakaotalk/index.ts +2 -0
- package/src/platforms/kakaotalk/protocol/session.ts +2 -0
- package/src/platforms/kakaotalk/types.ts +18 -0
- package/src/platforms/line/client.ts +14 -39
- package/src/platforms/line/commands/auth.test.ts +141 -0
- package/src/platforms/line/commands/auth.ts +28 -19
- package/src/platforms/line/commands/chat.test.ts +110 -0
- package/src/platforms/line/commands/friend.test.ts +98 -0
- package/src/platforms/line/commands/message.test.ts +119 -0
- package/src/platforms/line/commands/profile.test.ts +85 -0
- package/src/platforms/slackbot/commands/channel.test.ts +139 -0
- package/src/platforms/slackbot/commands/message.test.ts +226 -0
- package/src/platforms/slackbot/commands/reaction.test.ts +90 -0
- package/src/platforms/slackbot/commands/user.test.ts +143 -0
- package/src/platforms/teams/commands/reaction.test.ts +45 -61
- package/src/platforms/teams/commands/reaction.ts +2 -0
- package/src/platforms/telegram/commands/chat.test.ts +125 -0
- package/src/platforms/telegram/commands/message.test.ts +92 -0
- package/src/platforms/webex/commands/member.test.ts +65 -58
- package/src/platforms/webex/commands/message.test.ts +78 -121
- package/src/platforms/webex/commands/snapshot.test.ts +59 -46
- package/src/platforms/webex/commands/space.test.ts +49 -48
- package/src/platforms/wechatbot/cli.ts +24 -0
- package/src/platforms/wechatbot/client.test.ts +497 -0
- package/src/platforms/wechatbot/client.ts +268 -0
- package/src/platforms/wechatbot/commands/auth.test.ts +211 -0
- package/src/platforms/wechatbot/commands/auth.ts +203 -0
- package/src/platforms/wechatbot/commands/index.ts +4 -0
- package/src/platforms/wechatbot/commands/message.test.ts +155 -0
- package/src/platforms/wechatbot/commands/message.ts +104 -0
- package/src/platforms/wechatbot/commands/shared.ts +22 -0
- package/src/platforms/wechatbot/commands/template.test.ts +199 -0
- package/src/platforms/wechatbot/commands/template.ts +102 -0
- package/src/platforms/wechatbot/commands/user.test.ts +165 -0
- package/src/platforms/wechatbot/commands/user.ts +75 -0
- package/src/platforms/wechatbot/credential-manager.test.ts +255 -0
- package/src/platforms/wechatbot/credential-manager.ts +148 -0
- package/src/platforms/wechatbot/index.test.ts +49 -0
- package/src/platforms/wechatbot/index.ts +19 -0
- package/src/platforms/wechatbot/types.test.ts +223 -0
- package/src/platforms/wechatbot/types.ts +107 -0
- package/src/platforms/whatsapp/client.ts +24 -13
- package/src/platforms/whatsapp/commands/auth.test.ts +311 -0
- package/src/platforms/whatsapp/commands/auth.ts +21 -17
- package/src/platforms/whatsapp/commands/chat.test.ts +198 -0
- package/src/platforms/whatsapp/commands/message.test.ts +231 -0
- package/src/platforms/whatsapp/credential-manager.test.ts +20 -0
- package/src/platforms/whatsapp/credential-manager.ts +17 -8
- package/src/platforms/whatsappbot/commands/auth.test.ts +217 -0
- package/src/platforms/whatsappbot/commands/message.test.ts +198 -0
- package/src/platforms/whatsappbot/commands/template.test.ts +112 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { WeChatBotClient } from './client'
|
|
2
|
+
export { WeChatBotCredentialManager } from './credential-manager'
|
|
3
|
+
export type {
|
|
4
|
+
WeChatBotAccountEntry,
|
|
5
|
+
WeChatBotConfig,
|
|
6
|
+
WeChatBotCredentials,
|
|
7
|
+
WeChatBotNewsArticle,
|
|
8
|
+
WeChatBotTemplate,
|
|
9
|
+
WeChatBotUserInfo,
|
|
10
|
+
} from './types'
|
|
11
|
+
export {
|
|
12
|
+
WeChatBotAccountEntrySchema,
|
|
13
|
+
WeChatBotConfigSchema,
|
|
14
|
+
WeChatBotCredentialsSchema,
|
|
15
|
+
WeChatBotError,
|
|
16
|
+
WeChatBotNewsArticleSchema,
|
|
17
|
+
WeChatBotTemplateSchema,
|
|
18
|
+
WeChatBotUserInfoSchema,
|
|
19
|
+
} from './types'
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
WeChatBotAccountEntrySchema,
|
|
5
|
+
WeChatBotConfigSchema,
|
|
6
|
+
WeChatBotCredentialsSchema,
|
|
7
|
+
WeChatBotError,
|
|
8
|
+
WeChatBotNewsArticleSchema,
|
|
9
|
+
WeChatBotTemplateSchema,
|
|
10
|
+
WeChatBotUserInfoSchema,
|
|
11
|
+
} from '@/platforms/wechatbot/types'
|
|
12
|
+
|
|
13
|
+
test('WeChatBotAccountEntrySchema validates correct data', () => {
|
|
14
|
+
const result = WeChatBotAccountEntrySchema.safeParse({
|
|
15
|
+
app_id: 'wx123',
|
|
16
|
+
app_secret: 'secret123',
|
|
17
|
+
account_name: 'My Account',
|
|
18
|
+
})
|
|
19
|
+
expect(result.success).toBe(true)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('WeChatBotAccountEntrySchema rejects missing app_id', () => {
|
|
23
|
+
const result = WeChatBotAccountEntrySchema.safeParse({
|
|
24
|
+
app_secret: 'secret123',
|
|
25
|
+
account_name: 'My Account',
|
|
26
|
+
})
|
|
27
|
+
expect(result.success).toBe(false)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('WeChatBotAccountEntrySchema rejects missing app_secret', () => {
|
|
31
|
+
const result = WeChatBotAccountEntrySchema.safeParse({
|
|
32
|
+
app_id: 'wx123',
|
|
33
|
+
account_name: 'My Account',
|
|
34
|
+
})
|
|
35
|
+
expect(result.success).toBe(false)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('WeChatBotAccountEntrySchema rejects missing account_name', () => {
|
|
39
|
+
const result = WeChatBotAccountEntrySchema.safeParse({
|
|
40
|
+
app_id: 'wx123',
|
|
41
|
+
app_secret: 'secret123',
|
|
42
|
+
})
|
|
43
|
+
expect(result.success).toBe(false)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('WeChatBotConfigSchema validates with current account', () => {
|
|
47
|
+
const result = WeChatBotConfigSchema.safeParse({
|
|
48
|
+
current: { account_id: 'wx123' },
|
|
49
|
+
accounts: {
|
|
50
|
+
wx123: { app_id: 'wx123', app_secret: 'secret123', account_name: 'My Account' },
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
expect(result.success).toBe(true)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('WeChatBotConfigSchema validates with current null and empty accounts', () => {
|
|
57
|
+
const result = WeChatBotConfigSchema.safeParse({
|
|
58
|
+
current: null,
|
|
59
|
+
accounts: {},
|
|
60
|
+
})
|
|
61
|
+
expect(result.success).toBe(true)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('WeChatBotConfigSchema validates with multiple accounts', () => {
|
|
65
|
+
const result = WeChatBotConfigSchema.safeParse({
|
|
66
|
+
current: { account_id: 'wx-a' },
|
|
67
|
+
accounts: {
|
|
68
|
+
'wx-a': { app_id: 'wx-a', app_secret: 'secret-a', account_name: 'Account A' },
|
|
69
|
+
'wx-b': { app_id: 'wx-b', app_secret: 'secret-b', account_name: 'Account B' },
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
expect(result.success).toBe(true)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('WeChatBotConfigSchema rejects missing accounts field', () => {
|
|
76
|
+
const result = WeChatBotConfigSchema.safeParse({ current: null })
|
|
77
|
+
expect(result.success).toBe(false)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('WeChatBotConfigSchema rejects missing current field', () => {
|
|
81
|
+
const result = WeChatBotConfigSchema.safeParse({ accounts: {} })
|
|
82
|
+
expect(result.success).toBe(false)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('WeChatBotCredentialsSchema validates correct data', () => {
|
|
86
|
+
const result = WeChatBotCredentialsSchema.safeParse({
|
|
87
|
+
app_id: 'wx123',
|
|
88
|
+
app_secret: 'secret123',
|
|
89
|
+
account_name: 'My Account',
|
|
90
|
+
})
|
|
91
|
+
expect(result.success).toBe(true)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test('WeChatBotCredentialsSchema rejects missing app_id', () => {
|
|
95
|
+
const result = WeChatBotCredentialsSchema.safeParse({
|
|
96
|
+
app_secret: 'secret123',
|
|
97
|
+
account_name: 'My Account',
|
|
98
|
+
})
|
|
99
|
+
expect(result.success).toBe(false)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('WeChatBotCredentialsSchema rejects missing app_secret', () => {
|
|
103
|
+
const result = WeChatBotCredentialsSchema.safeParse({
|
|
104
|
+
app_id: 'wx123',
|
|
105
|
+
account_name: 'My Account',
|
|
106
|
+
})
|
|
107
|
+
expect(result.success).toBe(false)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
test('WeChatBotCredentialsSchema rejects missing account_name', () => {
|
|
111
|
+
const result = WeChatBotCredentialsSchema.safeParse({
|
|
112
|
+
app_id: 'wx123',
|
|
113
|
+
app_secret: 'secret123',
|
|
114
|
+
})
|
|
115
|
+
expect(result.success).toBe(false)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('WeChatBotNewsArticleSchema validates correct data', () => {
|
|
119
|
+
const result = WeChatBotNewsArticleSchema.safeParse({
|
|
120
|
+
title: 'Test Article',
|
|
121
|
+
description: 'Test description',
|
|
122
|
+
url: 'https://example.com',
|
|
123
|
+
picurl: 'https://example.com/pic.jpg',
|
|
124
|
+
})
|
|
125
|
+
expect(result.success).toBe(true)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('WeChatBotNewsArticleSchema rejects missing title', () => {
|
|
129
|
+
const result = WeChatBotNewsArticleSchema.safeParse({
|
|
130
|
+
description: 'Test description',
|
|
131
|
+
url: 'https://example.com',
|
|
132
|
+
picurl: 'https://example.com/pic.jpg',
|
|
133
|
+
})
|
|
134
|
+
expect(result.success).toBe(false)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
test('WeChatBotTemplateSchema validates correct data', () => {
|
|
138
|
+
const result = WeChatBotTemplateSchema.safeParse({
|
|
139
|
+
template_id: 'tmpl-001',
|
|
140
|
+
title: 'Order Notification',
|
|
141
|
+
primary_industry: 'IT科技',
|
|
142
|
+
deputy_industry: '互联网|电子商务',
|
|
143
|
+
content: 'ORDER_STATUS {{status.DATA}}',
|
|
144
|
+
example: 'Order shipped',
|
|
145
|
+
})
|
|
146
|
+
expect(result.success).toBe(true)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('WeChatBotTemplateSchema rejects missing template_id', () => {
|
|
150
|
+
const result = WeChatBotTemplateSchema.safeParse({
|
|
151
|
+
title: 'Order Notification',
|
|
152
|
+
primary_industry: 'IT科技',
|
|
153
|
+
deputy_industry: '互联网|电子商务',
|
|
154
|
+
content: 'ORDER_STATUS {{status.DATA}}',
|
|
155
|
+
example: 'Order shipped',
|
|
156
|
+
})
|
|
157
|
+
expect(result.success).toBe(false)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
test('WeChatBotUserInfoSchema validates correct data', () => {
|
|
161
|
+
const result = WeChatBotUserInfoSchema.safeParse({
|
|
162
|
+
subscribe: 1,
|
|
163
|
+
openid: 'openid-123',
|
|
164
|
+
language: 'zh_CN',
|
|
165
|
+
subscribe_time: 1609459200,
|
|
166
|
+
remark: '',
|
|
167
|
+
tagid_list: [1, 2],
|
|
168
|
+
subscribe_scene: 'ADD_SCENE_QR_CODE',
|
|
169
|
+
qr_scene: 0,
|
|
170
|
+
qr_scene_str: '',
|
|
171
|
+
})
|
|
172
|
+
expect(result.success).toBe(true)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test('WeChatBotUserInfoSchema validates with optional unionid', () => {
|
|
176
|
+
const result = WeChatBotUserInfoSchema.safeParse({
|
|
177
|
+
subscribe: 1,
|
|
178
|
+
openid: 'openid-123',
|
|
179
|
+
language: 'zh_CN',
|
|
180
|
+
subscribe_time: 1609459200,
|
|
181
|
+
unionid: 'union-id-xyz',
|
|
182
|
+
remark: '',
|
|
183
|
+
tagid_list: [],
|
|
184
|
+
subscribe_scene: 'ADD_SCENE_SEARCH',
|
|
185
|
+
qr_scene: 0,
|
|
186
|
+
qr_scene_str: '',
|
|
187
|
+
})
|
|
188
|
+
expect(result.success).toBe(true)
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
test('WeChatBotUserInfoSchema rejects missing openid', () => {
|
|
192
|
+
const result = WeChatBotUserInfoSchema.safeParse({
|
|
193
|
+
subscribe: 1,
|
|
194
|
+
language: 'zh_CN',
|
|
195
|
+
subscribe_time: 1609459200,
|
|
196
|
+
remark: '',
|
|
197
|
+
tagid_list: [],
|
|
198
|
+
subscribe_scene: 'ADD_SCENE_QR_CODE',
|
|
199
|
+
qr_scene: 0,
|
|
200
|
+
qr_scene_str: '',
|
|
201
|
+
})
|
|
202
|
+
expect(result.success).toBe(false)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('WeChatBotError has correct name', () => {
|
|
206
|
+
const error = new WeChatBotError('Test error', 'TEST_CODE')
|
|
207
|
+
expect(error.name).toBe('WeChatBotError')
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('WeChatBotError has correct message', () => {
|
|
211
|
+
const error = new WeChatBotError('Test error', 'TEST_CODE')
|
|
212
|
+
expect(error.message).toBe('Test error')
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
test('WeChatBotError has correct code', () => {
|
|
216
|
+
const error = new WeChatBotError('Test error', 'TEST_CODE')
|
|
217
|
+
expect(error.code).toBe('TEST_CODE')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
test('WeChatBotError is instance of Error', () => {
|
|
221
|
+
const error = new WeChatBotError('Test error', 'TEST_CODE')
|
|
222
|
+
expect(error instanceof Error).toBe(true)
|
|
223
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
export interface WeChatBotAccountEntry {
|
|
4
|
+
app_id: string
|
|
5
|
+
app_secret: string
|
|
6
|
+
account_name: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface WeChatBotConfig {
|
|
10
|
+
current: { account_id: string } | null
|
|
11
|
+
accounts: Record<string, WeChatBotAccountEntry>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WeChatBotCredentials {
|
|
15
|
+
app_id: string
|
|
16
|
+
app_secret: string
|
|
17
|
+
account_name: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface WeChatBotNewsArticle {
|
|
21
|
+
title: string
|
|
22
|
+
description: string
|
|
23
|
+
url: string
|
|
24
|
+
picurl: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface WeChatBotTemplate {
|
|
28
|
+
template_id: string
|
|
29
|
+
title: string
|
|
30
|
+
primary_industry: string
|
|
31
|
+
deputy_industry: string
|
|
32
|
+
content: string
|
|
33
|
+
example: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WeChatBotUserInfo {
|
|
37
|
+
subscribe: number
|
|
38
|
+
openid: string
|
|
39
|
+
language: string
|
|
40
|
+
subscribe_time: number
|
|
41
|
+
unionid?: string
|
|
42
|
+
remark: string
|
|
43
|
+
tagid_list: number[]
|
|
44
|
+
subscribe_scene: string
|
|
45
|
+
qr_scene: number
|
|
46
|
+
qr_scene_str: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class WeChatBotError extends Error {
|
|
50
|
+
code: string
|
|
51
|
+
|
|
52
|
+
constructor(message: string, code: string) {
|
|
53
|
+
super(message)
|
|
54
|
+
this.name = 'WeChatBotError'
|
|
55
|
+
this.code = code
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const WeChatBotAccountEntrySchema = z.object({
|
|
60
|
+
app_id: z.string(),
|
|
61
|
+
app_secret: z.string(),
|
|
62
|
+
account_name: z.string(),
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export const WeChatBotConfigSchema = z.object({
|
|
66
|
+
current: z
|
|
67
|
+
.object({
|
|
68
|
+
account_id: z.string(),
|
|
69
|
+
})
|
|
70
|
+
.nullable(),
|
|
71
|
+
accounts: z.record(z.string(), WeChatBotAccountEntrySchema),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
export const WeChatBotCredentialsSchema = z.object({
|
|
75
|
+
app_id: z.string(),
|
|
76
|
+
app_secret: z.string(),
|
|
77
|
+
account_name: z.string(),
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export const WeChatBotNewsArticleSchema = z.object({
|
|
81
|
+
title: z.string(),
|
|
82
|
+
description: z.string(),
|
|
83
|
+
url: z.string(),
|
|
84
|
+
picurl: z.string(),
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
export const WeChatBotTemplateSchema = z.object({
|
|
88
|
+
template_id: z.string(),
|
|
89
|
+
title: z.string(),
|
|
90
|
+
primary_industry: z.string(),
|
|
91
|
+
deputy_industry: z.string(),
|
|
92
|
+
content: z.string(),
|
|
93
|
+
example: z.string(),
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
export const WeChatBotUserInfoSchema = z.object({
|
|
97
|
+
subscribe: z.number(),
|
|
98
|
+
openid: z.string(),
|
|
99
|
+
language: z.string(),
|
|
100
|
+
subscribe_time: z.number(),
|
|
101
|
+
unionid: z.string().optional(),
|
|
102
|
+
remark: z.string(),
|
|
103
|
+
tagid_list: z.array(z.number()),
|
|
104
|
+
subscribe_scene: z.string(),
|
|
105
|
+
qr_scene: z.number(),
|
|
106
|
+
qr_scene_str: z.string(),
|
|
107
|
+
})
|
|
@@ -86,6 +86,7 @@ export class WhatsAppClient {
|
|
|
86
86
|
private pendingResolve: (() => void) | null = null
|
|
87
87
|
private pendingPromise: Promise<void> | null = null
|
|
88
88
|
private authCompleteResolve: (() => void) | null = null
|
|
89
|
+
private authCompleteReject: ((err: Error) => void) | null = null
|
|
89
90
|
|
|
90
91
|
private storePath: string | null = null
|
|
91
92
|
|
|
@@ -248,8 +249,9 @@ export class WhatsAppClient {
|
|
|
248
249
|
this.pendingResolve = resolve
|
|
249
250
|
})
|
|
250
251
|
|
|
251
|
-
const authCompletePromise = new Promise<void>((resolve) => {
|
|
252
|
+
const authCompletePromise = new Promise<void>((resolve, reject) => {
|
|
252
253
|
this.authCompleteResolve = resolve
|
|
254
|
+
this.authCompleteReject = reject
|
|
253
255
|
})
|
|
254
256
|
|
|
255
257
|
const cleaned = phoneNumber.replace(/[^0-9]/g, '')
|
|
@@ -258,16 +260,24 @@ export class WhatsAppClient {
|
|
|
258
260
|
|
|
259
261
|
return new Promise((outerResolve, outerReject) => {
|
|
260
262
|
let codeReturned = false
|
|
261
|
-
let postPairingRetries = 0
|
|
262
|
-
const MAX_POST_PAIRING_RETRIES = 5
|
|
263
263
|
|
|
264
264
|
const overallTimeout = setTimeout(() => {
|
|
265
|
-
|
|
265
|
+
const err = new WhatsAppError('Pairing timed out', 'pairing_timeout')
|
|
266
|
+
if (codeReturned) {
|
|
267
|
+
this.authCompleteReject?.(err)
|
|
268
|
+
} else {
|
|
269
|
+
outerReject(err)
|
|
270
|
+
}
|
|
266
271
|
}, 120_000)
|
|
267
272
|
|
|
268
273
|
const onError = (err: unknown): void => {
|
|
269
274
|
clearTimeout(overallTimeout)
|
|
270
|
-
|
|
275
|
+
const error = err instanceof Error ? err : new WhatsAppError(String(err), 'pairing_error')
|
|
276
|
+
if (codeReturned) {
|
|
277
|
+
this.authCompleteReject?.(error)
|
|
278
|
+
} else {
|
|
279
|
+
outerReject(error)
|
|
280
|
+
}
|
|
271
281
|
}
|
|
272
282
|
|
|
273
283
|
const attempt = async (): Promise<void> => {
|
|
@@ -294,20 +304,21 @@ export class WhatsAppClient {
|
|
|
294
304
|
|
|
295
305
|
const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode
|
|
296
306
|
|
|
297
|
-
// 401 is normal for fresh credentials — always reconnect during pairing
|
|
298
307
|
if (statusCode === DisconnectReason.forbidden) {
|
|
299
308
|
clearTimeout(overallTimeout)
|
|
300
|
-
|
|
309
|
+
const err = new WhatsAppError('Account banned or restricted.', 'forbidden')
|
|
310
|
+
if (codeReturned) {
|
|
311
|
+
this.authCompleteReject?.(err)
|
|
312
|
+
} else {
|
|
313
|
+
outerReject(err)
|
|
314
|
+
}
|
|
301
315
|
return
|
|
302
316
|
}
|
|
303
317
|
|
|
304
318
|
if (codeReturned) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
outerReject(new WhatsAppError('Post-pairing reconnection failed.', 'post_pairing_failed'))
|
|
309
|
-
return
|
|
310
|
-
}
|
|
319
|
+
// Post-pairing: rely on overallTimeout (120s) instead of retry cap.
|
|
320
|
+
// Baileys cycles the connection during pairing — keep reconnecting
|
|
321
|
+
// until the user enters the code and the connection opens.
|
|
311
322
|
setTimeout(() => attempt().catch(onError), 2000)
|
|
312
323
|
return
|
|
313
324
|
}
|