wechat-bridge-opencode 0.1.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/.opencode/tools/send-wechat.ts +88 -0
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/bin/wechat-acp.d.ts +14 -0
- package/dist/bin/wechat-acp.d.ts.map +1 -0
- package/dist/bin/wechat-acp.js +284 -0
- package/dist/bin/wechat-acp.js.map +1 -0
- package/dist/bin/wechat-opencode.d.ts +14 -0
- package/dist/bin/wechat-opencode.d.ts.map +1 -0
- package/dist/bin/wechat-opencode.js +284 -0
- package/dist/bin/wechat-opencode.js.map +1 -0
- package/dist/package.json +60 -0
- package/dist/src/acp/agent-manager.d.ts +23 -0
- package/dist/src/acp/agent-manager.d.ts.map +1 -0
- package/dist/src/acp/agent-manager.js +134 -0
- package/dist/src/acp/agent-manager.js.map +1 -0
- package/dist/src/acp/client.d.ts +49 -0
- package/dist/src/acp/client.d.ts.map +1 -0
- package/dist/src/acp/client.js +219 -0
- package/dist/src/acp/client.js.map +1 -0
- package/dist/src/acp/opencode-sessions.d.ts +17 -0
- package/dist/src/acp/opencode-sessions.d.ts.map +1 -0
- package/dist/src/acp/opencode-sessions.js +59 -0
- package/dist/src/acp/opencode-sessions.js.map +1 -0
- package/dist/src/acp/session.d.ts +75 -0
- package/dist/src/acp/session.d.ts.map +1 -0
- package/dist/src/acp/session.js +273 -0
- package/dist/src/acp/session.js.map +1 -0
- package/dist/src/acp/workspace-manager.d.ts +48 -0
- package/dist/src/acp/workspace-manager.d.ts.map +1 -0
- package/dist/src/acp/workspace-manager.js +141 -0
- package/dist/src/acp/workspace-manager.js.map +1 -0
- package/dist/src/adapter/inbound.d.ts +10 -0
- package/dist/src/adapter/inbound.d.ts.map +1 -0
- package/dist/src/adapter/inbound.js +149 -0
- package/dist/src/adapter/inbound.js.map +1 -0
- package/dist/src/adapter/outbound.d.ts +9 -0
- package/dist/src/adapter/outbound.d.ts.map +1 -0
- package/dist/src/adapter/outbound.js +25 -0
- package/dist/src/adapter/outbound.js.map +1 -0
- package/dist/src/adapter/workspace-cmd.d.ts +53 -0
- package/dist/src/adapter/workspace-cmd.d.ts.map +1 -0
- package/dist/src/adapter/workspace-cmd.js +172 -0
- package/dist/src/adapter/workspace-cmd.js.map +1 -0
- package/dist/src/bridge.d.ts +42 -0
- package/dist/src/bridge.d.ts.map +1 -0
- package/dist/src/bridge.js +557 -0
- package/dist/src/bridge.js.map +1 -0
- package/dist/src/config.d.ts +63 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +88 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/weixin/api.d.ts +50 -0
- package/dist/src/weixin/api.d.ts.map +1 -0
- package/dist/src/weixin/api.js +87 -0
- package/dist/src/weixin/api.js.map +1 -0
- package/dist/src/weixin/auth.d.ts +20 -0
- package/dist/src/weixin/auth.d.ts.map +1 -0
- package/dist/src/weixin/auth.js +88 -0
- package/dist/src/weixin/auth.js.map +1 -0
- package/dist/src/weixin/media.d.ts +24 -0
- package/dist/src/weixin/media.d.ts.map +1 -0
- package/dist/src/weixin/media.js +91 -0
- package/dist/src/weixin/media.js.map +1 -0
- package/dist/src/weixin/monitor.d.ts +16 -0
- package/dist/src/weixin/monitor.d.ts.map +1 -0
- package/dist/src/weixin/monitor.js +111 -0
- package/dist/src/weixin/monitor.js.map +1 -0
- package/dist/src/weixin/send.d.ts +32 -0
- package/dist/src/weixin/send.d.ts.map +1 -0
- package/dist/src/weixin/send.js +193 -0
- package/dist/src/weixin/send.js.map +1 -0
- package/dist/src/weixin/types.d.ts +150 -0
- package/dist/src/weixin/types.d.ts.map +1 -0
- package/dist/src/weixin/types.js +33 -0
- package/dist/src/weixin/types.js.map +1 -0
- package/package.json +60 -0
- package/scripts/install-tool.mjs +14 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../src/weixin/monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send messages via WeChat iLink API.
|
|
3
|
+
*/
|
|
4
|
+
export interface WeixinSendOpts {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
token?: string;
|
|
7
|
+
contextToken?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function sendTextMessage(to: string, text: string, opts: WeixinSendOpts): Promise<string>;
|
|
10
|
+
export interface SendMediaOpts extends WeixinSendOpts {
|
|
11
|
+
cdnBaseUrl: string;
|
|
12
|
+
fileName?: string;
|
|
13
|
+
mimeType?: string;
|
|
14
|
+
thumbBuffer?: Buffer;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Send a media message (image/file/video/voice) to a WeChat user.
|
|
18
|
+
*
|
|
19
|
+
* Flow:
|
|
20
|
+
* 1. Generate 16-byte AES key
|
|
21
|
+
* 2. Call getUploadUrl with AES key (server encrypts upload_param with it)
|
|
22
|
+
* 3. Encrypt file content with AES-128-ECB
|
|
23
|
+
* 4. Upload encrypted content to CDN using server-returned upload_param
|
|
24
|
+
* 5. Send message with CDN media reference
|
|
25
|
+
*/
|
|
26
|
+
export declare function sendMediaMessage(to: string, mediaType: 1 | 2 | 3 | 4, // IMAGE=1, VIDEO=2, FILE=3, VOICE=4
|
|
27
|
+
buffer: Buffer, opts: SendMediaOpts): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Split text into segments of max length, respecting line breaks where possible.
|
|
30
|
+
*/
|
|
31
|
+
export declare function splitText(text: string, maxLen: number): string[];
|
|
32
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/weixin/send.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,oCAAoC;AAC9D,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CAiJjB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBhE"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send messages via WeChat iLink API.
|
|
3
|
+
*/
|
|
4
|
+
import crypto from "node:crypto";
|
|
5
|
+
import { sendMessage, getUploadUrl } from "./api.js";
|
|
6
|
+
import { encryptAesEcb, uploadToCdn } from "./media.js";
|
|
7
|
+
import { MessageType, MessageState, MessageItemType, UploadMediaType, } from "./types.js";
|
|
8
|
+
export async function sendTextMessage(to, text, opts) {
|
|
9
|
+
if (!opts.contextToken) {
|
|
10
|
+
throw new Error("contextToken is required to send a message");
|
|
11
|
+
}
|
|
12
|
+
const clientId = `wechat-acp-${crypto.randomUUID()}`;
|
|
13
|
+
await sendMessage({
|
|
14
|
+
baseUrl: opts.baseUrl,
|
|
15
|
+
token: opts.token,
|
|
16
|
+
body: {
|
|
17
|
+
msg: {
|
|
18
|
+
from_user_id: "",
|
|
19
|
+
to_user_id: to,
|
|
20
|
+
client_id: clientId,
|
|
21
|
+
message_type: MessageType.BOT,
|
|
22
|
+
message_state: MessageState.FINISH,
|
|
23
|
+
context_token: opts.contextToken,
|
|
24
|
+
item_list: [{ type: 1, text_item: { text } }],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
return clientId;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Send a media message (image/file/video/voice) to a WeChat user.
|
|
32
|
+
*
|
|
33
|
+
* Flow:
|
|
34
|
+
* 1. Generate 16-byte AES key
|
|
35
|
+
* 2. Call getUploadUrl with AES key (server encrypts upload_param with it)
|
|
36
|
+
* 3. Encrypt file content with AES-128-ECB
|
|
37
|
+
* 4. Upload encrypted content to CDN using server-returned upload_param
|
|
38
|
+
* 5. Send message with CDN media reference
|
|
39
|
+
*/
|
|
40
|
+
export async function sendMediaMessage(to, mediaType, // IMAGE=1, VIDEO=2, FILE=3, VOICE=4
|
|
41
|
+
buffer, opts) {
|
|
42
|
+
if (!opts.contextToken) {
|
|
43
|
+
throw new Error("contextToken is required to send a media message");
|
|
44
|
+
}
|
|
45
|
+
const clientId = crypto.randomBytes(16).toString("hex"); // 32-char hex, like openclaw-weixin
|
|
46
|
+
const rawSize = buffer.length;
|
|
47
|
+
const rawMd5 = crypto.createHash("md5").update(buffer).digest("hex");
|
|
48
|
+
// Step 1: Generate a 16-byte AES key
|
|
49
|
+
// The server will use this key to encrypt the upload_param
|
|
50
|
+
const aesKey = crypto.randomBytes(16);
|
|
51
|
+
const aesKeyHex = aesKey.toString("hex");
|
|
52
|
+
// Step 2: Get upload URL from server (server encrypts it with our AES key)
|
|
53
|
+
// filesize should be the encrypted file size (with PKCS7 padding)
|
|
54
|
+
// AES-128-ECB PKCS7: ceil((rawSize + 1) / 16) * 16
|
|
55
|
+
const encryptedSize = Math.ceil((rawSize + 1) / 16) * 16;
|
|
56
|
+
const uploadResp = await getUploadUrl({
|
|
57
|
+
baseUrl: opts.baseUrl,
|
|
58
|
+
token: opts.token,
|
|
59
|
+
body: {
|
|
60
|
+
filekey: clientId,
|
|
61
|
+
media_type: mediaType,
|
|
62
|
+
to_user_id: to,
|
|
63
|
+
rawsize: rawSize,
|
|
64
|
+
rawfilemd5: rawMd5,
|
|
65
|
+
filesize: encryptedSize,
|
|
66
|
+
no_need_thumb: !opts.thumbBuffer,
|
|
67
|
+
aeskey: aesKeyHex,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
if (!uploadResp.upload_param) {
|
|
71
|
+
throw new Error("getUploadUrl: missing upload_param in response");
|
|
72
|
+
}
|
|
73
|
+
// Step 3: Upload to CDN (uploadToCdn handles encryption internally)
|
|
74
|
+
const uploadUrl = uploadResp.upload_full_url
|
|
75
|
+
?? `${opts.cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(uploadResp.upload_param)}&filekey=${encodeURIComponent(clientId)}`;
|
|
76
|
+
const encryptQueryParam = await uploadToCdn({
|
|
77
|
+
buffer,
|
|
78
|
+
uploadParam: uploadResp.upload_param,
|
|
79
|
+
aesKey,
|
|
80
|
+
filekey: clientId,
|
|
81
|
+
cdnBaseUrl: opts.cdnBaseUrl,
|
|
82
|
+
uploadUrl,
|
|
83
|
+
});
|
|
84
|
+
// Step 5: Build CDNMedia reference
|
|
85
|
+
// Match reference: base64-encode the hex string (32 chars → 44 char base64), not raw bytes
|
|
86
|
+
const aesKeyBase64 = Buffer.from(aesKeyHex).toString("base64");
|
|
87
|
+
const cdnMedia = {
|
|
88
|
+
encrypt_query_param: encryptQueryParam,
|
|
89
|
+
aes_key: aesKeyBase64,
|
|
90
|
+
encrypt_type: 1,
|
|
91
|
+
};
|
|
92
|
+
// Step 7: Handle thumb if provided
|
|
93
|
+
let thumbCdnMedia;
|
|
94
|
+
if (opts.thumbBuffer && uploadResp.thumb_upload_param) {
|
|
95
|
+
const thumbAesKey = crypto.randomBytes(16);
|
|
96
|
+
const thumbAesKeyHex = thumbAesKey.toString("hex");
|
|
97
|
+
const encryptedThumb = encryptAesEcb(opts.thumbBuffer, thumbAesKey);
|
|
98
|
+
const thumbEncryptQueryParam = await uploadToCdn({
|
|
99
|
+
buffer: encryptedThumb,
|
|
100
|
+
uploadParam: uploadResp.thumb_upload_param,
|
|
101
|
+
aesKey: thumbAesKey,
|
|
102
|
+
filekey: `${clientId}_thumb`,
|
|
103
|
+
cdnBaseUrl: opts.cdnBaseUrl,
|
|
104
|
+
});
|
|
105
|
+
thumbCdnMedia = {
|
|
106
|
+
encrypt_query_param: thumbEncryptQueryParam,
|
|
107
|
+
aes_key: Buffer.from(thumbAesKeyHex).toString("base64"),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Step 7: Construct message item based on media type
|
|
111
|
+
let itemList;
|
|
112
|
+
switch (mediaType) {
|
|
113
|
+
case UploadMediaType.IMAGE:
|
|
114
|
+
itemList = [{
|
|
115
|
+
type: MessageItemType.IMAGE,
|
|
116
|
+
image_item: {
|
|
117
|
+
media: cdnMedia,
|
|
118
|
+
aeskey: cdnMedia.aes_key,
|
|
119
|
+
url: cdnMedia.encrypt_query_param,
|
|
120
|
+
mid_size: encryptedSize,
|
|
121
|
+
},
|
|
122
|
+
}];
|
|
123
|
+
break;
|
|
124
|
+
case UploadMediaType.VIDEO:
|
|
125
|
+
itemList = [{
|
|
126
|
+
type: MessageItemType.VIDEO,
|
|
127
|
+
video_item: {
|
|
128
|
+
media: cdnMedia,
|
|
129
|
+
thumb_media: thumbCdnMedia,
|
|
130
|
+
},
|
|
131
|
+
}];
|
|
132
|
+
break;
|
|
133
|
+
case UploadMediaType.FILE:
|
|
134
|
+
itemList = [{
|
|
135
|
+
type: MessageItemType.FILE,
|
|
136
|
+
file_item: {
|
|
137
|
+
media: cdnMedia,
|
|
138
|
+
file_name: opts.fileName ?? "file",
|
|
139
|
+
len: String(rawSize),
|
|
140
|
+
},
|
|
141
|
+
}];
|
|
142
|
+
break;
|
|
143
|
+
case UploadMediaType.VOICE:
|
|
144
|
+
itemList = [{
|
|
145
|
+
type: MessageItemType.VOICE,
|
|
146
|
+
voice_item: {
|
|
147
|
+
media: cdnMedia,
|
|
148
|
+
},
|
|
149
|
+
}];
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
throw new Error(`Unsupported media type: ${mediaType}`);
|
|
153
|
+
}
|
|
154
|
+
// Step 8: Send the message
|
|
155
|
+
await sendMessage({
|
|
156
|
+
baseUrl: opts.baseUrl,
|
|
157
|
+
token: opts.token,
|
|
158
|
+
body: {
|
|
159
|
+
msg: {
|
|
160
|
+
from_user_id: "",
|
|
161
|
+
to_user_id: to,
|
|
162
|
+
client_id: clientId,
|
|
163
|
+
message_type: MessageType.BOT,
|
|
164
|
+
message_state: MessageState.FINISH,
|
|
165
|
+
context_token: opts.contextToken,
|
|
166
|
+
item_list: itemList,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
return clientId;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Split text into segments of max length, respecting line breaks where possible.
|
|
174
|
+
*/
|
|
175
|
+
export function splitText(text, maxLen) {
|
|
176
|
+
if (text.length <= maxLen)
|
|
177
|
+
return [text];
|
|
178
|
+
const segments = [];
|
|
179
|
+
let remaining = text;
|
|
180
|
+
while (remaining.length > 0) {
|
|
181
|
+
if (remaining.length <= maxLen) {
|
|
182
|
+
segments.push(remaining);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
let breakAt = remaining.lastIndexOf("\n", maxLen);
|
|
186
|
+
if (breakAt <= 0)
|
|
187
|
+
breakAt = maxLen;
|
|
188
|
+
segments.push(remaining.substring(0, breakAt));
|
|
189
|
+
remaining = remaining.substring(breakAt).replace(/^\n/, "");
|
|
190
|
+
}
|
|
191
|
+
return segments;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/weixin/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat iLink protocol types.
|
|
3
|
+
* Adapted from @tencent-weixin/openclaw-weixin api/types.ts
|
|
4
|
+
*/
|
|
5
|
+
export interface BaseInfo {
|
|
6
|
+
channel_version?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const UploadMediaType: {
|
|
9
|
+
readonly IMAGE: 1;
|
|
10
|
+
readonly VIDEO: 2;
|
|
11
|
+
readonly FILE: 3;
|
|
12
|
+
readonly VOICE: 4;
|
|
13
|
+
};
|
|
14
|
+
export declare const MessageType: {
|
|
15
|
+
readonly NONE: 0;
|
|
16
|
+
readonly USER: 1;
|
|
17
|
+
readonly BOT: 2;
|
|
18
|
+
};
|
|
19
|
+
export declare const MessageItemType: {
|
|
20
|
+
readonly NONE: 0;
|
|
21
|
+
readonly TEXT: 1;
|
|
22
|
+
readonly IMAGE: 2;
|
|
23
|
+
readonly VOICE: 3;
|
|
24
|
+
readonly FILE: 4;
|
|
25
|
+
readonly VIDEO: 5;
|
|
26
|
+
};
|
|
27
|
+
export declare const MessageState: {
|
|
28
|
+
readonly NEW: 0;
|
|
29
|
+
readonly GENERATING: 1;
|
|
30
|
+
readonly FINISH: 2;
|
|
31
|
+
};
|
|
32
|
+
export declare const TypingStatus: {
|
|
33
|
+
readonly TYPING: 1;
|
|
34
|
+
readonly CANCEL: 2;
|
|
35
|
+
};
|
|
36
|
+
export interface TextItem {
|
|
37
|
+
text?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface CDNMedia {
|
|
40
|
+
encrypt_query_param?: string;
|
|
41
|
+
aes_key?: string;
|
|
42
|
+
encrypt_type?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ImageItem {
|
|
45
|
+
media?: CDNMedia;
|
|
46
|
+
thumb_media?: CDNMedia;
|
|
47
|
+
aeskey?: string;
|
|
48
|
+
url?: string;
|
|
49
|
+
mid_size?: number;
|
|
50
|
+
thumb_size?: number;
|
|
51
|
+
thumb_height?: number;
|
|
52
|
+
thumb_width?: number;
|
|
53
|
+
hd_size?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface VoiceItem {
|
|
56
|
+
media?: CDNMedia;
|
|
57
|
+
encode_type?: number;
|
|
58
|
+
bits_per_sample?: number;
|
|
59
|
+
sample_rate?: number;
|
|
60
|
+
playtime?: number;
|
|
61
|
+
text?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface FileItem {
|
|
64
|
+
media?: CDNMedia;
|
|
65
|
+
file_name?: string;
|
|
66
|
+
md5?: string;
|
|
67
|
+
len?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface VideoItem {
|
|
70
|
+
media?: CDNMedia;
|
|
71
|
+
video_size?: number;
|
|
72
|
+
play_length?: number;
|
|
73
|
+
video_md5?: string;
|
|
74
|
+
thumb_media?: CDNMedia;
|
|
75
|
+
thumb_size?: number;
|
|
76
|
+
thumb_height?: number;
|
|
77
|
+
thumb_width?: number;
|
|
78
|
+
}
|
|
79
|
+
export interface RefMessage {
|
|
80
|
+
message_item?: MessageItem;
|
|
81
|
+
title?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface MessageItem {
|
|
84
|
+
type?: number;
|
|
85
|
+
create_time_ms?: number;
|
|
86
|
+
update_time_ms?: number;
|
|
87
|
+
is_completed?: boolean;
|
|
88
|
+
msg_id?: string;
|
|
89
|
+
ref_msg?: RefMessage;
|
|
90
|
+
text_item?: TextItem;
|
|
91
|
+
image_item?: ImageItem;
|
|
92
|
+
voice_item?: VoiceItem;
|
|
93
|
+
file_item?: FileItem;
|
|
94
|
+
video_item?: VideoItem;
|
|
95
|
+
}
|
|
96
|
+
export interface WeixinMessage {
|
|
97
|
+
seq?: number;
|
|
98
|
+
message_id?: number;
|
|
99
|
+
from_user_id?: string;
|
|
100
|
+
to_user_id?: string;
|
|
101
|
+
client_id?: string;
|
|
102
|
+
create_time_ms?: number;
|
|
103
|
+
update_time_ms?: number;
|
|
104
|
+
delete_time_ms?: number;
|
|
105
|
+
session_id?: string;
|
|
106
|
+
group_id?: string;
|
|
107
|
+
message_type?: number;
|
|
108
|
+
message_state?: number;
|
|
109
|
+
item_list?: MessageItem[];
|
|
110
|
+
context_token?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface GetUpdatesResp {
|
|
113
|
+
ret?: number;
|
|
114
|
+
errcode?: number;
|
|
115
|
+
errmsg?: string;
|
|
116
|
+
msgs?: WeixinMessage[];
|
|
117
|
+
get_updates_buf?: string;
|
|
118
|
+
longpolling_timeout_ms?: number;
|
|
119
|
+
}
|
|
120
|
+
export interface SendMessageReq {
|
|
121
|
+
msg?: WeixinMessage;
|
|
122
|
+
}
|
|
123
|
+
export interface GetUploadUrlReq {
|
|
124
|
+
filekey?: string;
|
|
125
|
+
media_type?: number;
|
|
126
|
+
to_user_id?: string;
|
|
127
|
+
rawsize?: number;
|
|
128
|
+
rawfilemd5?: string;
|
|
129
|
+
filesize?: number;
|
|
130
|
+
thumb_rawsize?: number;
|
|
131
|
+
thumb_rawfilemd5?: string;
|
|
132
|
+
thumb_filesize?: number;
|
|
133
|
+
no_need_thumb?: boolean;
|
|
134
|
+
aeskey?: string;
|
|
135
|
+
}
|
|
136
|
+
export interface GetUploadUrlResp {
|
|
137
|
+
upload_param?: string;
|
|
138
|
+
thumb_upload_param?: string;
|
|
139
|
+
/** 完整上传 URL(服务端直接返回,无需客户端拼接) */
|
|
140
|
+
upload_full_url?: string;
|
|
141
|
+
}
|
|
142
|
+
export interface SendTypingReq {
|
|
143
|
+
ilink_user_id: string;
|
|
144
|
+
typing_ticket: string;
|
|
145
|
+
status: number;
|
|
146
|
+
}
|
|
147
|
+
export interface GetConfigResp {
|
|
148
|
+
typing_ticket?: string;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/weixin/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat iLink protocol types.
|
|
3
|
+
* Adapted from @tencent-weixin/openclaw-weixin api/types.ts
|
|
4
|
+
*/
|
|
5
|
+
export const UploadMediaType = {
|
|
6
|
+
IMAGE: 1,
|
|
7
|
+
VIDEO: 2,
|
|
8
|
+
FILE: 3,
|
|
9
|
+
VOICE: 4,
|
|
10
|
+
};
|
|
11
|
+
export const MessageType = {
|
|
12
|
+
NONE: 0,
|
|
13
|
+
USER: 1,
|
|
14
|
+
BOT: 2,
|
|
15
|
+
};
|
|
16
|
+
export const MessageItemType = {
|
|
17
|
+
NONE: 0,
|
|
18
|
+
TEXT: 1,
|
|
19
|
+
IMAGE: 2,
|
|
20
|
+
VOICE: 3,
|
|
21
|
+
FILE: 4,
|
|
22
|
+
VIDEO: 5,
|
|
23
|
+
};
|
|
24
|
+
export const MessageState = {
|
|
25
|
+
NEW: 0,
|
|
26
|
+
GENERATING: 1,
|
|
27
|
+
FINISH: 2,
|
|
28
|
+
};
|
|
29
|
+
export const TypingStatus = {
|
|
30
|
+
TYPING: 1,
|
|
31
|
+
CANCEL: 2,
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/weixin/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACA,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;CACE,CAAC;AAEX,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACA,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,EAAE,CAAC;IACN,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,CAAC;CACD,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;CACD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wechat-bridge-opencode",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Bridge WeChat to any Opencode",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/",
|
|
8
|
+
".opencode/tools/send-wechat.ts",
|
|
9
|
+
"scripts/install-tool.mjs",
|
|
10
|
+
"README.md",
|
|
11
|
+
"package.json"
|
|
12
|
+
],
|
|
13
|
+
"bin": {
|
|
14
|
+
"wbo": "dist/bin/wechat-opencode.js"
|
|
15
|
+
},
|
|
16
|
+
"main": "./dist/src/index.js",
|
|
17
|
+
"types": "./dist/src/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"import": "./dist/src/index.js",
|
|
21
|
+
"types": "./dist/src/index.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"prepack": "npm run build",
|
|
27
|
+
"start": "node dist/bin/wechat-opencode.js",
|
|
28
|
+
"dev": "tsc --watch",
|
|
29
|
+
"postinstall": "node scripts/install-tool.mjs"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@agentclientprotocol/sdk": "^0.16.1",
|
|
33
|
+
"better-sqlite3": "^12.8.0",
|
|
34
|
+
"qrcode-terminal": "^0.12.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"typescript": "^5.5.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20.0.0"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/pan17/wechat-opencode.git"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/pan17/wechat-opencode#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/pan17/wechat-opencode/issues"
|
|
51
|
+
},
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"keywords": [
|
|
54
|
+
"wechat",
|
|
55
|
+
"opencode",
|
|
56
|
+
"agent-client-protocol",
|
|
57
|
+
"ai-agent",
|
|
58
|
+
"bridge"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall: copy send-wechat tool to global opencode tools directory.
|
|
3
|
+
*/
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
|
|
8
|
+
const src = path.join(import.meta.dirname, "..", ".opencode", "tools", "send-wechat.ts");
|
|
9
|
+
const dstDir = path.join(os.homedir(), ".config", "opencode", "tools");
|
|
10
|
+
const dst = path.join(dstDir, "send-wechat.ts");
|
|
11
|
+
|
|
12
|
+
fs.mkdirSync(dstDir, { recursive: true });
|
|
13
|
+
fs.copyFileSync(src, dst);
|
|
14
|
+
console.log("[wechat-bridge-opencode] Installed send-wechat tool to", dst);
|