@rezti/dsh-rez-wechat 0.1.16 → 0.1.18
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/README.md +2 -2
- package/lib/wecom-channel.d.ts +1 -1
- package/lib/wecom-channel.js +9 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
dsh plugin --profile web add @rezti/dsh-rez-suite
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
以后升级只记:`dsh plugin --profile web
|
|
9
|
+
以后升级只记:`dsh plugin --profile web add @rezti/dsh-rez-suite@latest`。不要再单独 add 本包。
|
|
10
10
|
|
|
11
11
|
| 能力 | 做法 |
|
|
12
12
|
|---|---|
|
|
@@ -30,7 +30,7 @@ dsh plugin --profile web add @rezti/dsh-rez-suite
|
|
|
30
30
|
- 可绑房间:搞钱、产品、运营、人事助理、财务助理、法务助理、设计、发布、电商、实验室(不要绑「微信」个人通道)
|
|
31
31
|
- 同一房间固定一条网页会话;只有「重启对话」才新开并把旧的归档
|
|
32
32
|
- 会话标题是房间名;网页必须开着
|
|
33
|
-
- 收文本 /
|
|
33
|
+
- 收文本 / 混排文字 / 单聊语音(官方已转写成 `voice.content`,当普通文字进房间)、流式回复、进入会话欢迎语;图片和文件请走网页端或 Nextcloud。个人微信语音不转写。群聊语音官方不保证有转写。
|
|
34
34
|
- BotID / Secret 在企业微信管理后台 → 智能机器人([开发前必读](https://developer.work.weixin.qq.com/document/path/101805) / [长连接](https://developer.work.weixin.qq.com/document/path/101463))
|
|
35
35
|
|
|
36
36
|
扫码 UI 在 suite 面板;通道本身在本包。不要对同一 profile 既 add suite 又 add wechat,会重复注册。
|
package/lib/wecom-channel.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Uses @wecom/aibot-node-sdk (botId + secret). Do not hand-roll the WS.
|
|
4
4
|
*/
|
|
5
5
|
import { type WecomBotPublic, type WecomBotRecord } from './wecom-store.js';
|
|
6
|
-
export declare const WECOM_NON_TEXT_HINT = "\u8BF7\u53D1\u6587\u5B57\u3002\u56FE\u7247\
|
|
6
|
+
export declare const WECOM_NON_TEXT_HINT = "\u8BF7\u53D1\u6587\u5B57\u3002\u56FE\u7247\u548C\u6587\u4EF6\u8BF7\u8D70\u7F51\u9875\u7AEF\u6216 Nextcloud\u3002";
|
|
7
7
|
export type WecomBindingPhase = 'idle' | 'connecting' | 'authenticated' | 'error';
|
|
8
8
|
export interface WecomBindingStatus {
|
|
9
9
|
room: string;
|
package/lib/wecom-channel.js
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { dshHome } from '@rezti/dsh-rez-sso';
|
|
7
7
|
import { runHeadlessViaWeb } from './web-shim.js';
|
|
8
8
|
import { loadWecomChannels, publicWecomBots, saveWecomChannels, applyWecomBotPatch, WECOM_BINDABLE_ROOMS, } from './wecom-store.js';
|
|
9
|
-
export const WECOM_NON_TEXT_HINT = '
|
|
9
|
+
export const WECOM_NON_TEXT_HINT = '请发文字。图片和文件请走网页端或 Nextcloud。';
|
|
10
10
|
const MAX_SEEN_MSGIDS = 200;
|
|
11
11
|
export function extractWecomText(frame) {
|
|
12
12
|
if (typeof frame !== 'object' || frame === null)
|
|
@@ -18,6 +18,10 @@ export function extractWecomText(frame) {
|
|
|
18
18
|
const fromText = textContent(rec.text);
|
|
19
19
|
if (fromText.length > 0)
|
|
20
20
|
return fromText;
|
|
21
|
+
// Official AI-bot voice is already ASR text (single chat). See work.weixin path/100719.
|
|
22
|
+
const fromVoice = textContent(rec.voice);
|
|
23
|
+
if (fromVoice.length > 0)
|
|
24
|
+
return fromVoice;
|
|
21
25
|
if (typeof rec.content === 'string' && rec.content.trim().length > 0)
|
|
22
26
|
return rec.content.trim();
|
|
23
27
|
const mixed = rec.mixed;
|
|
@@ -29,7 +33,8 @@ export function extractWecomText(frame) {
|
|
|
29
33
|
if (typeof item !== 'object' || item === null)
|
|
30
34
|
continue;
|
|
31
35
|
const row = item;
|
|
32
|
-
const nested = textContent(row.text) || (
|
|
36
|
+
const nested = textContent(row.text) || textContent(row.voice)
|
|
37
|
+
|| (typeof row.content === 'string' ? row.content.trim() : '');
|
|
33
38
|
if (nested.length > 0)
|
|
34
39
|
parts.push(nested);
|
|
35
40
|
}
|
|
@@ -191,13 +196,13 @@ export class WecomChannel {
|
|
|
191
196
|
client.on('message.mixed', (frame) => { this.enqueue(row, () => this.handleText(row, frame)); });
|
|
192
197
|
client.on('message.image', (frame) => { this.enqueue(row, () => this.handleNonText(row, frame)); });
|
|
193
198
|
client.on('message.file', (frame) => { this.enqueue(row, () => this.handleNonText(row, frame)); });
|
|
194
|
-
client.on('message.voice', (frame) => { this.enqueue(row, () => this.
|
|
199
|
+
client.on('message.voice', (frame) => { this.enqueue(row, () => this.handleText(row, frame)); });
|
|
195
200
|
client.on('message.video', (frame) => { this.enqueue(row, () => this.handleNonText(row, frame)); });
|
|
196
201
|
client.on('event.enter_chat', (frame) => {
|
|
197
202
|
this.enqueue(row, async () => {
|
|
198
203
|
await client.replyWelcome(frame, {
|
|
199
204
|
msgtype: 'text',
|
|
200
|
-
text: { content: `您好,我是「${bot.room}
|
|
205
|
+
text: { content: `您好,我是「${bot.room}」。直接发文字或语音即可。` },
|
|
201
206
|
});
|
|
202
207
|
});
|
|
203
208
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rezti/dsh-rez-wechat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "ReZ-TI WeChat/WeCom bridges. Personal WeChat is QClaw/ClawBot scan-and-chat via dsh-wechat-bridge; WeCom AI bots use the official @wecom/aibot-node-sdk (BotID + Secret) bound per Harness room.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
],
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@rezti/dsh-rez-sso": "^0.1.18",
|
|
30
31
|
"@wecom/aibot-node-sdk": "^1.0.7",
|
|
31
|
-
"qrcode": "^1.5.4"
|
|
32
|
-
"@rezti/dsh-rez-sso": "0.1.14"
|
|
32
|
+
"qrcode": "^1.5.4"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
36
|
-
"@deepseek-ai/dsh-host-webserver": "
|
|
37
|
-
"@deepseek-ai/dsh-system-prompt": "
|
|
36
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-rc.2",
|
|
37
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
|
|
38
38
|
"@types/node": "^22.20.0",
|
|
39
39
|
"@types/qrcode": "^1.5.5",
|
|
40
40
|
"typescript": "~5.7.2"
|