@zhin.js/adapter-wechat-mp 0.1.11 → 0.1.13
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 +17 -0
- package/README.md +65 -433
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @zhin.js/adapter-wechat-mp
|
|
2
2
|
|
|
3
|
+
## 0.1.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [b27e633]
|
|
8
|
+
- @zhin.js/http@1.0.18
|
|
9
|
+
- zhin.js@1.0.27
|
|
10
|
+
|
|
11
|
+
## 0.1.12
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 106d357: fix: ai
|
|
16
|
+
- Updated dependencies [106d357]
|
|
17
|
+
- @zhin.js/http@1.0.17
|
|
18
|
+
- zhin.js@1.0.26
|
|
19
|
+
|
|
3
20
|
## 0.1.11
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @zhin.js/adapter-wechat-mp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Zhin.js 微信公众号适配器,支持微信公众号的消息收发。
|
|
4
4
|
|
|
5
5
|
## 功能特性
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- 💬 **双向通信**: 支持被动回复和主动推送
|
|
13
|
-
- 🎛️ **多媒体支持**: 支持图片、语音、视频等多媒体消息
|
|
14
|
-
- 🌐 **集成化**: 集成 zhin-next HTTP 服务,无需独立服务器
|
|
7
|
+
- Webhook 事件接收(HTTP 回调)
|
|
8
|
+
- 签名验证
|
|
9
|
+
- Access Token 自动刷新
|
|
10
|
+
- XML 消息解析
|
|
11
|
+
- 可选消息加密(AES)
|
|
15
12
|
|
|
16
13
|
## 安装
|
|
17
14
|
|
|
@@ -19,460 +16,95 @@
|
|
|
19
16
|
pnpm add @zhin.js/adapter-wechat-mp
|
|
20
17
|
```
|
|
21
18
|
|
|
22
|
-
##
|
|
19
|
+
## 依赖
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
- `xml2js` - XML解析和生成
|
|
26
|
-
- `axios` - HTTP请求
|
|
27
|
-
- `crypto` - 签名验证 (Node.js 内置)
|
|
28
|
-
- `@zhin.js/http` - HTTP 服务和路由 (peer dependency)
|
|
29
|
-
|
|
30
|
-
## 前置准备
|
|
31
|
-
|
|
32
|
-
### 1. 申请微信公众号
|
|
33
|
-
|
|
34
|
-
1. 前往 [微信公众平台](https://mp.weixin.qq.com/) 注册账号
|
|
35
|
-
2. 选择订阅号或服务号(服务号功能更丰富)
|
|
36
|
-
3. 完成认证(可选,但认证后功能更多)
|
|
37
|
-
|
|
38
|
-
### 2. 获取开发者信息
|
|
39
|
-
|
|
40
|
-
1. 登录微信公众平台
|
|
41
|
-
2. 进入「开发」->「基本配置」
|
|
42
|
-
3. 获取以下信息:
|
|
43
|
-
- **AppID** (应用ID)
|
|
44
|
-
- **AppSecret** (应用密钥)
|
|
45
|
-
- 设置 **Token** (自定义,用于验证)
|
|
46
|
-
- 设置 **EncodingAESKey** (可选,用于加密)
|
|
47
|
-
|
|
48
|
-
### 3. 配置服务器
|
|
49
|
-
|
|
50
|
-
1. 在「基本配置」中设置服务器地址:
|
|
51
|
-
```
|
|
52
|
-
URL: http://your-domain.com/wechat
|
|
53
|
-
Token: 你设置的token
|
|
54
|
-
```
|
|
55
|
-
2. 选择消息加解密方式(明文模式或安全模式)
|
|
21
|
+
- `@zhin.js/http` — HTTP 服务(提供 Webhook 路由)
|
|
56
22
|
|
|
57
23
|
## 配置
|
|
58
24
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
const wechatConfig: WeChatMPConfig = {
|
|
78
|
-
context: 'wechat-mp',
|
|
79
|
-
name: 'advanced-wechat-bot',
|
|
80
|
-
appId: 'wx1234567890abcdef',
|
|
81
|
-
appSecret: 'your-app-secret-key',
|
|
82
|
-
token: 'your-verification-token',
|
|
83
|
-
encodingAESKey: 'your-encoding-aes-key', // 加密模式需要
|
|
84
|
-
encrypt: false, // 是否启用加密模式
|
|
85
|
-
path: '/wechat/webhook' // Webhook路径(在 HTTP 服务上)
|
|
86
|
-
}
|
|
25
|
+
```yaml
|
|
26
|
+
# zhin.config.yml
|
|
27
|
+
bots:
|
|
28
|
+
- context: wechat-mp
|
|
29
|
+
name: my-wechat-bot
|
|
30
|
+
appId: ${WECHAT_APP_ID}
|
|
31
|
+
appSecret: ${WECHAT_APP_SECRET}
|
|
32
|
+
token: ${WECHAT_TOKEN}
|
|
33
|
+
path: /wechat/webhook
|
|
34
|
+
# 可选配置
|
|
35
|
+
# encodingAESKey: your-aes-key
|
|
36
|
+
# encrypt: false
|
|
37
|
+
|
|
38
|
+
plugins:
|
|
39
|
+
- adapter-wechat-mp
|
|
40
|
+
- http
|
|
87
41
|
```
|
|
88
42
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
## 使用示例
|
|
92
|
-
|
|
93
|
-
### 基础使用
|
|
43
|
+
### TypeScript 配置
|
|
94
44
|
|
|
95
45
|
```typescript
|
|
96
|
-
import {
|
|
97
|
-
import WeChatMPAdapter from '@zhin.js/adapter-wechat-mp'
|
|
46
|
+
import { defineConfig } from 'zhin.js'
|
|
98
47
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
adapters: {
|
|
103
|
-
'wechat-mp': {
|
|
48
|
+
export default defineConfig({
|
|
49
|
+
bots: [
|
|
50
|
+
{
|
|
104
51
|
context: 'wechat-mp',
|
|
105
52
|
name: 'my-wechat-bot',
|
|
106
|
-
appId:
|
|
107
|
-
appSecret:
|
|
108
|
-
token:
|
|
109
|
-
path: '/wechat'
|
|
53
|
+
appId: process.env.WECHAT_APP_ID!,
|
|
54
|
+
appSecret: process.env.WECHAT_APP_SECRET!,
|
|
55
|
+
token: process.env.WECHAT_TOKEN!,
|
|
56
|
+
path: '/wechat/webhook',
|
|
110
57
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// 处理文本消息
|
|
115
|
-
app.on('message.receive', (message) => {
|
|
116
|
-
if (message.$adapter === 'wechat-mp') {
|
|
117
|
-
console.log('收到微信消息:', message.$content)
|
|
118
|
-
|
|
119
|
-
// 自动回复
|
|
120
|
-
message.$reply('感谢您的消息!')
|
|
121
|
-
}
|
|
58
|
+
],
|
|
59
|
+
plugins: ['adapter-wechat-mp', 'http']
|
|
122
60
|
})
|
|
123
|
-
|
|
124
|
-
// 处理关注事件
|
|
125
|
-
app.on('message.receive', (message) => {
|
|
126
|
-
if (message.$adapter === 'wechat-mp' &&
|
|
127
|
-
message.$content.some(seg => seg.type === 'event' && seg.data.event === 'subscribe')) {
|
|
128
|
-
message.$reply('欢迎关注我们的公众号!')
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
app.start()
|
|
133
61
|
```
|
|
134
62
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
// 发送文本消息
|
|
139
|
-
await app.sendMessage({
|
|
140
|
-
context: 'wechat-mp',
|
|
141
|
-
bot: 'my-wechat-bot',
|
|
142
|
-
id: 'user-openid',
|
|
143
|
-
type: 'private',
|
|
144
|
-
content: '这是一条文本消息'
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
// 发送图片消息
|
|
148
|
-
await app.sendMessage({
|
|
149
|
-
context: 'wechat-mp',
|
|
150
|
-
bot: 'my-wechat-bot',
|
|
151
|
-
id: 'user-openid',
|
|
152
|
-
type: 'private',
|
|
153
|
-
content: [
|
|
154
|
-
{ type: 'image', data: { mediaId: 'uploaded-media-id' } }
|
|
155
|
-
]
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
// 发送语音消息
|
|
159
|
-
await app.sendMessage({
|
|
160
|
-
context: 'wechat-mp',
|
|
161
|
-
bot: 'my-wechat-bot',
|
|
162
|
-
id: 'user-openid',
|
|
163
|
-
type: 'private',
|
|
164
|
-
content: [
|
|
165
|
-
{ type: 'voice', data: { mediaId: 'voice-media-id' } }
|
|
166
|
-
]
|
|
167
|
-
})
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### 处理不同消息类型
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
app.on('message.receive', (message) => {
|
|
174
|
-
if (message.$adapter !== 'wechat-mp') return;
|
|
175
|
-
|
|
176
|
-
for (const segment of message.$content) {
|
|
177
|
-
switch (segment.type) {
|
|
178
|
-
case 'text':
|
|
179
|
-
console.log('文本消息:', segment.data.text);
|
|
180
|
-
break;
|
|
181
|
-
|
|
182
|
-
case 'image':
|
|
183
|
-
console.log('图片消息:', segment.data.url, segment.data.mediaId);
|
|
184
|
-
break;
|
|
185
|
-
|
|
186
|
-
case 'voice':
|
|
187
|
-
console.log('语音消息:', segment.data.mediaId, segment.data.recognition);
|
|
188
|
-
break;
|
|
189
|
-
|
|
190
|
-
case 'video':
|
|
191
|
-
console.log('视频消息:', segment.data.mediaId);
|
|
192
|
-
break;
|
|
193
|
-
|
|
194
|
-
case 'location':
|
|
195
|
-
console.log('位置消息:', segment.data.latitude, segment.data.longitude);
|
|
196
|
-
break;
|
|
197
|
-
|
|
198
|
-
case 'link':
|
|
199
|
-
console.log('链接消息:', segment.data.title, segment.data.url);
|
|
200
|
-
break;
|
|
201
|
-
|
|
202
|
-
case 'event':
|
|
203
|
-
console.log('事件:', segment.data.event, segment.data.eventKey);
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
})
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### 使用公众号API
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
import { WeChatMPBot } from '@zhin.js/adapter-wechat-mp'
|
|
214
|
-
|
|
215
|
-
// 获取bot实例
|
|
216
|
-
const bot = app.getContext('wechat-mp')?.['my-wechat-bot'] as WeChatMPBot;
|
|
217
|
-
|
|
218
|
-
// 获取用户信息
|
|
219
|
-
const userInfo = await bot.getUserInfo('user-openid');
|
|
220
|
-
console.log('用户信息:', userInfo);
|
|
221
|
-
|
|
222
|
-
// 上传多媒体文件
|
|
223
|
-
const mediaId = await bot.uploadMedia('image', imageBuffer);
|
|
224
|
-
console.log('媒体ID:', mediaId);
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
## 支持的消息类型
|
|
228
|
-
|
|
229
|
-
### 接收消息
|
|
230
|
-
|
|
231
|
-
| 微信消息类型 | MessageSegment 类型 | 说明 |
|
|
232
|
-
|------------|-------------------|------|
|
|
233
|
-
| text | `text` | 文本消息 |
|
|
234
|
-
| image | `image` | 图片消息 |
|
|
235
|
-
| voice | `voice` | 语音消息 |
|
|
236
|
-
| video | `video` | 视频消息 |
|
|
237
|
-
| shortvideo | `video` | 小视频消息 |
|
|
238
|
-
| location | `location` | 地理位置消息 |
|
|
239
|
-
| link | `link` | 链接消息 |
|
|
240
|
-
| event | `event` | 事件消息 |
|
|
241
|
-
|
|
242
|
-
### 发送消息
|
|
243
|
-
|
|
244
|
-
| MessageSegment 类型 | 微信API | 说明 |
|
|
245
|
-
|-------------------|---------|------|
|
|
246
|
-
| `text` | 客服消息 | 文本消息 |
|
|
247
|
-
| `image` | 客服消息 | 图片消息(需要mediaId) |
|
|
248
|
-
| `voice` | 客服消息 | 语音消息(需要mediaId) |
|
|
249
|
-
| `video` | 客服消息 | 视频消息(需要mediaId) |
|
|
250
|
-
|
|
251
|
-
### 事件类型
|
|
252
|
-
|
|
253
|
-
| 事件类型 | 说明 |
|
|
254
|
-
|---------|------|
|
|
255
|
-
| subscribe | 关注事件 |
|
|
256
|
-
| unsubscribe | 取关事件 |
|
|
257
|
-
| CLICK | 菜单点击事件 |
|
|
258
|
-
| VIEW | 菜单链接事件 |
|
|
259
|
-
| LOCATION | 地理位置事件 |
|
|
260
|
-
|
|
261
|
-
## 频道类型
|
|
262
|
-
|
|
263
|
-
| 类型 | 说明 | channel_id 格式 |
|
|
264
|
-
|------|------|----------------|
|
|
265
|
-
| `private` | 用户私聊 | 用户OpenID |
|
|
266
|
-
|
|
267
|
-
注意:微信公众号只支持 `private` 类型,因为所有消息都是用户与公众号的私聊。
|
|
268
|
-
|
|
269
|
-
## 开发模式设置
|
|
270
|
-
|
|
271
|
-
### 1. 本地开发
|
|
272
|
-
|
|
273
|
-
使用内网穿透工具(如ngrok):
|
|
274
|
-
|
|
275
|
-
```bash
|
|
276
|
-
# 安装ngrok
|
|
277
|
-
npm install -g ngrok
|
|
278
|
-
|
|
279
|
-
# 启动内网穿透
|
|
280
|
-
ngrok http 3000
|
|
281
|
-
|
|
282
|
-
# 将生成的https地址设置为微信服务器URL
|
|
283
|
-
# 例如: https://abc123.ngrok.io/wechat
|
|
284
|
-
```
|
|
63
|
+
## 使用示例
|
|
285
64
|
|
|
286
|
-
###
|
|
65
|
+
### 注册命令
|
|
287
66
|
|
|
288
67
|
```typescript
|
|
289
|
-
|
|
290
|
-
const wechatConfig = {
|
|
291
|
-
context: 'wechat-mp',
|
|
292
|
-
name: 'production-bot',
|
|
293
|
-
appId: process.env.WECHAT_APP_ID,
|
|
294
|
-
appSecret: process.env.WECHAT_APP_SECRET,
|
|
295
|
-
token: process.env.WECHAT_TOKEN,
|
|
296
|
-
port: process.env.PORT || 80,
|
|
297
|
-
path: '/wechat'
|
|
298
|
-
}
|
|
299
|
-
```
|
|
68
|
+
import { usePlugin, MessageCommand } from 'zhin.js'
|
|
300
69
|
|
|
301
|
-
|
|
70
|
+
const { addCommand } = usePlugin()
|
|
302
71
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
location /wechat {
|
|
309
|
-
proxy_pass http://localhost:3000/wechat;
|
|
310
|
-
proxy_set_header Host $host;
|
|
311
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
72
|
+
addCommand(
|
|
73
|
+
new MessageCommand('hello')
|
|
74
|
+
.desc('微信问候')
|
|
75
|
+
.action((message) => `你好,${message.$sender.name}!`)
|
|
76
|
+
)
|
|
314
77
|
```
|
|
315
78
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
### 1. 自定义菜单
|
|
79
|
+
### 消息中间件
|
|
319
80
|
|
|
320
81
|
```typescript
|
|
321
|
-
|
|
322
|
-
const menuData = {
|
|
323
|
-
"button": [
|
|
324
|
-
{
|
|
325
|
-
"type": "click",
|
|
326
|
-
"name": "功能1",
|
|
327
|
-
"key": "MENU_KEY_1"
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
"type": "view",
|
|
331
|
-
"name": "官网",
|
|
332
|
-
"url": "https://your-website.com"
|
|
333
|
-
}
|
|
334
|
-
]
|
|
335
|
-
}
|
|
336
|
-
```
|
|
82
|
+
import { usePlugin } from 'zhin.js'
|
|
337
83
|
|
|
338
|
-
|
|
84
|
+
const { addMiddleware } = usePlugin()
|
|
339
85
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
touser: 'user-openid',
|
|
344
|
-
template_id: 'template-id',
|
|
345
|
-
data: {
|
|
346
|
-
first: { value: '标题' },
|
|
347
|
-
keyword1: { value: '内容1' },
|
|
348
|
-
keyword2: { value: '内容2' },
|
|
349
|
-
remark: { value: '备注' }
|
|
86
|
+
addMiddleware(async (message, next) => {
|
|
87
|
+
if (message.$adapter === 'wechat-mp') {
|
|
88
|
+
console.log('收到微信消息:', message.$content)
|
|
350
89
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
### 3. 素材管理
|
|
355
|
-
|
|
356
|
-
```typescript
|
|
357
|
-
// 上传永久素材
|
|
358
|
-
const permanentMedia = await bot.uploadPermanentMedia('image', buffer);
|
|
359
|
-
|
|
360
|
-
// 获取素材列表
|
|
361
|
-
const mediaList = await bot.getMediaList('image', 0, 20);
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## 错误处理
|
|
365
|
-
|
|
366
|
-
### 常见错误码
|
|
367
|
-
|
|
368
|
-
| 错误码 | 说明 | 解决方案 |
|
|
369
|
-
|--------|------|----------|
|
|
370
|
-
| 40001 | AppSecret错误 | 检查AppSecret配置 |
|
|
371
|
-
| 40002 | 不合法的凭证类型 | 检查access_token |
|
|
372
|
-
| 40003 | 不合法的OpenID | 检查用户OpenID |
|
|
373
|
-
| 40004 | 不合法的媒体文件类型 | 检查上传文件格式 |
|
|
374
|
-
| 40013 | 不合法的AppID | 检查AppID配置 |
|
|
375
|
-
| 42001 | access_token超时 | 会自动刷新token |
|
|
376
|
-
|
|
377
|
-
### 调试建议
|
|
378
|
-
|
|
379
|
-
1. **检查签名验证**:
|
|
380
|
-
```javascript
|
|
381
|
-
// 验证微信服务器配置时的日志
|
|
382
|
-
console.log('Signature verification:', { signature, timestamp, nonce });
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
2. **查看XML消息**:
|
|
386
|
-
```javascript
|
|
387
|
-
// 打印接收到的原始XML
|
|
388
|
-
console.log('Received XML:', xmlBody);
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
3. **监控Token状态**:
|
|
392
|
-
```javascript
|
|
393
|
-
// 定期检查token有效性
|
|
394
|
-
console.log('Access Token:', this.accessToken);
|
|
395
|
-
console.log('Expires at:', new Date(this.tokenExpireTime));
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
## 安全注意事项
|
|
399
|
-
|
|
400
|
-
1. **保护敏感信息**: 不要在代码中硬编码AppSecret
|
|
401
|
-
2. **使用HTTPS**: 生产环境建议使用HTTPS
|
|
402
|
-
3. **签名验证**: 始终验证微信请求的签名
|
|
403
|
-
4. **加密通信**: 敏感场景可启用消息加密
|
|
404
|
-
5. **频率限制**: 注意微信API的调用频率限制
|
|
405
|
-
|
|
406
|
-
## API限制
|
|
407
|
-
|
|
408
|
-
1. **消息发送**: 每天主动推送消息有限制
|
|
409
|
-
2. **API调用**: 大部分API每分钟调用次数有限制
|
|
410
|
-
3. **媒体上传**: 临时素材3天后失效
|
|
411
|
-
4. **用户信息**: 只能获取关注用户的信息
|
|
412
|
-
|
|
413
|
-
## 故障排除
|
|
414
|
-
|
|
415
|
-
### 1. 服务器验证失败
|
|
416
|
-
- 检查Token配置是否正确
|
|
417
|
-
- 确认URL可以正常访问
|
|
418
|
-
- 检查签名算法实现
|
|
419
|
-
|
|
420
|
-
### 2. 消息接收异常
|
|
421
|
-
- 检查HTTP服务器是否正常启动
|
|
422
|
-
- 验证防火墙和端口配置
|
|
423
|
-
- 查看微信开发者工具的错误日志
|
|
424
|
-
|
|
425
|
-
### 3. 消息发送失败
|
|
426
|
-
- 检查access_token是否有效
|
|
427
|
-
- 确认用户已关注公众号
|
|
428
|
-
- 检查消息格式是否正确
|
|
429
|
-
|
|
430
|
-
### 4. 多媒体消息问题
|
|
431
|
-
- 确认文件格式和大小符合要求
|
|
432
|
-
- 检查mediaId是否有效
|
|
433
|
-
- 验证文件上传是否成功
|
|
434
|
-
|
|
435
|
-
## 示例项目
|
|
436
|
-
|
|
437
|
-
完整的使用示例可以在 `example/` 目录中找到。
|
|
438
|
-
|
|
439
|
-
## API 参考
|
|
440
|
-
|
|
441
|
-
### WeChatMPBot 类
|
|
442
|
-
|
|
443
|
-
#### 配置选项
|
|
444
|
-
|
|
445
|
-
```typescript
|
|
446
|
-
interface WeChatMPConfig {
|
|
447
|
-
context: 'wechat-mp'
|
|
448
|
-
name: string
|
|
449
|
-
appId: string
|
|
450
|
-
appSecret: string
|
|
451
|
-
token: string
|
|
452
|
-
encodingAESKey?: string
|
|
453
|
-
port?: number
|
|
454
|
-
path?: string
|
|
455
|
-
encrypt?: boolean
|
|
456
|
-
}
|
|
90
|
+
await next()
|
|
91
|
+
})
|
|
457
92
|
```
|
|
458
93
|
|
|
459
|
-
|
|
94
|
+
## 微信公众号配置
|
|
460
95
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
- `uploadMedia(type, buffer)`: 上传多媒体文件
|
|
96
|
+
1. 登录 [微信公众平台](https://mp.weixin.qq.com/)
|
|
97
|
+
2. 在「开发 → 基本配置」中获取 `AppID` 和 `AppSecret`
|
|
98
|
+
3. 配置服务器地址(URL):`http://your-server:8086/api/wechat/webhook`
|
|
99
|
+
4. 设置 Token(与配置文件中的 `token` 一致)
|
|
100
|
+
5. 如需消息加解密,设置 EncodingAESKey
|
|
467
101
|
|
|
468
|
-
|
|
102
|
+
## 注意事项
|
|
469
103
|
|
|
470
|
-
-
|
|
104
|
+
- 微信公众号要求服务器必须在 5 秒内响应
|
|
105
|
+
- 服务器地址必须是公网可访问的 HTTP/HTTPS URL
|
|
106
|
+
- 建议使用已备案的域名
|
|
471
107
|
|
|
472
|
-
##
|
|
108
|
+
## 许可证
|
|
473
109
|
|
|
474
|
-
|
|
475
|
-
- 支持基础消息收发
|
|
476
|
-
- 实现签名验证和Token管理
|
|
477
|
-
- 支持多种消息类型和事件
|
|
478
|
-
- 提供完整的API封装
|
|
110
|
+
MIT License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-wechat-mp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Zhin.js adapter for WeChat Official Account (微信公众号)",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"form-data": "^4.0.0"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@zhin.js/http": "1.0.
|
|
16
|
-
"zhin.js": "1.0.
|
|
15
|
+
"@zhin.js/http": "1.0.18",
|
|
16
|
+
"zhin.js": "1.0.27"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"typescript": "^5.3.3",
|
|
20
20
|
"@types/node": "^20.10.6",
|
|
21
21
|
"@types/koa": "^2.15.0",
|
|
22
|
-
"zhin.js": "1.0.
|
|
22
|
+
"zhin.js": "1.0.27"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"zhin",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "pnpm build:node",
|
|
58
|
-
"clean": "
|
|
58
|
+
"clean": "rimraf lib",
|
|
59
59
|
"build:node": "tsc"
|
|
60
60
|
}
|
|
61
61
|
}
|