@aster110/cc2wechat 1.0.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/plugin.json +6 -0
- package/.mcp.json +6 -0
- package/EXPERIENCE.md +148 -0
- package/README.md +66 -0
- package/dist/auth.d.ts +15 -0
- package/dist/auth.js +230 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +123 -0
- package/dist/cli.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +412 -0
- package/dist/server.js.map +1 -0
- package/dist/store.d.ts +12 -0
- package/dist/store.js +61 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/wechat-api.d.ts +33 -0
- package/dist/wechat-api.js +313 -0
- package/dist/wechat-api.js.map +1 -0
- package/package.json +28 -0
- package/skills/wechat-reply/SKILL.md +21 -0
- package/src/auth.ts +258 -0
- package/src/cli.ts +133 -0
- package/src/qrcode-terminal.d.ts +9 -0
- package/src/server.ts +479 -0
- package/src/store.ts +79 -0
- package/src/types.ts +144 -0
- package/src/wechat-api.ts +405 -0
- package/tsconfig.json +17 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { loginWithQRWeb } from './auth.js';
|
|
6
|
+
import { getActiveAccount, saveAccount, loadSyncBuf, saveSyncBuf } from './store.js';
|
|
7
|
+
import { getUpdates, sendMessage, sendTyping, getConfig, uploadAndSendMedia, } from './wechat-api.js';
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { MessageItemType } from './types.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// State
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
let pollingActive = false;
|
|
14
|
+
let pollingAbort = null;
|
|
15
|
+
/** Cache: userId -> typing_ticket */
|
|
16
|
+
const typingTicketCache = new Map();
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Message text extraction
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function extractText(msg) {
|
|
21
|
+
const parts = [];
|
|
22
|
+
for (const item of msg.item_list ?? []) {
|
|
23
|
+
if (item.type === MessageItemType.TEXT && item.text_item?.text) {
|
|
24
|
+
parts.push(item.text_item.text);
|
|
25
|
+
}
|
|
26
|
+
else if (item.type === MessageItemType.IMAGE) {
|
|
27
|
+
parts.push('[Image]');
|
|
28
|
+
}
|
|
29
|
+
else if (item.type === MessageItemType.VOICE && item.voice_item?.text) {
|
|
30
|
+
parts.push(`[Voice] ${item.voice_item.text}`);
|
|
31
|
+
}
|
|
32
|
+
else if (item.type === MessageItemType.FILE && item.file_item?.file_name) {
|
|
33
|
+
parts.push(`[File: ${item.file_item.file_name}]`);
|
|
34
|
+
}
|
|
35
|
+
else if (item.type === MessageItemType.VIDEO) {
|
|
36
|
+
parts.push('[Video]');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return parts.join('\n') || '[Empty message]';
|
|
40
|
+
}
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Text chunking for WeChat 4000-char limit
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
const MAX_CHUNK_LENGTH = 3900;
|
|
45
|
+
function chunkText(text) {
|
|
46
|
+
if (text.length <= MAX_CHUNK_LENGTH)
|
|
47
|
+
return [text];
|
|
48
|
+
const chunks = [];
|
|
49
|
+
let remaining = text;
|
|
50
|
+
while (remaining.length > 0) {
|
|
51
|
+
if (remaining.length <= MAX_CHUNK_LENGTH) {
|
|
52
|
+
chunks.push(remaining);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
// Try to break at newline
|
|
56
|
+
let breakAt = remaining.lastIndexOf('\n', MAX_CHUNK_LENGTH);
|
|
57
|
+
if (breakAt < MAX_CHUNK_LENGTH * 0.5) {
|
|
58
|
+
// No good newline break, try space
|
|
59
|
+
breakAt = remaining.lastIndexOf(' ', MAX_CHUNK_LENGTH);
|
|
60
|
+
}
|
|
61
|
+
if (breakAt < MAX_CHUNK_LENGTH * 0.3) {
|
|
62
|
+
breakAt = MAX_CHUNK_LENGTH;
|
|
63
|
+
}
|
|
64
|
+
chunks.push(remaining.slice(0, breakAt));
|
|
65
|
+
remaining = remaining.slice(breakAt).trimStart();
|
|
66
|
+
}
|
|
67
|
+
return chunks;
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Strip markdown for WeChat plain text
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
function stripMarkdown(text) {
|
|
73
|
+
let result = text;
|
|
74
|
+
// Code blocks: strip fences, keep content
|
|
75
|
+
result = result.replace(/```[^\n]*\n?([\s\S]*?)```/g, (_, code) => code.trim());
|
|
76
|
+
// Images: remove
|
|
77
|
+
result = result.replace(/!\[[^\]]*\]\([^)]*\)/g, '');
|
|
78
|
+
// Links: keep display text
|
|
79
|
+
result = result.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1');
|
|
80
|
+
// Bold/italic
|
|
81
|
+
result = result.replace(/\*\*(.+?)\*\*/g, '$1');
|
|
82
|
+
result = result.replace(/\*(.+?)\*/g, '$1');
|
|
83
|
+
result = result.replace(/__(.+?)__/g, '$1');
|
|
84
|
+
result = result.replace(/_(.+?)_/g, '$1');
|
|
85
|
+
// Headings
|
|
86
|
+
result = result.replace(/^#{1,6}\s+/gm, '');
|
|
87
|
+
// Horizontal rules
|
|
88
|
+
result = result.replace(/^[-*_]{3,}$/gm, '');
|
|
89
|
+
// Blockquotes
|
|
90
|
+
result = result.replace(/^>\s?/gm, '');
|
|
91
|
+
return result.trim();
|
|
92
|
+
}
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// MCP Server
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
const server = new Server({ name: 'wechat-channel', version: '1.0.0' }, {
|
|
97
|
+
capabilities: {
|
|
98
|
+
experimental: { 'claude/channel': {} },
|
|
99
|
+
tools: {},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
// -- Tools --
|
|
103
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
104
|
+
tools: [
|
|
105
|
+
{
|
|
106
|
+
name: 'reply',
|
|
107
|
+
description: 'Reply to a WeChat message. Supports text and image/file. Set media to a local file path to send an image or file.',
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
user_id: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
description: 'The WeChat user ID to reply to (from_user_id from the incoming message)',
|
|
114
|
+
},
|
|
115
|
+
context_token: {
|
|
116
|
+
type: 'string',
|
|
117
|
+
description: 'The context_token from the incoming message (required for reply association)',
|
|
118
|
+
},
|
|
119
|
+
content: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'Text content',
|
|
122
|
+
},
|
|
123
|
+
media: {
|
|
124
|
+
type: 'string',
|
|
125
|
+
description: 'Optional: absolute path to a local file (image/video/file) to send',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
required: ['user_id', 'context_token', 'content'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'login',
|
|
133
|
+
description: 'Login to WeChat by scanning a QR code. Run this first if not already logged in.',
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
}));
|
|
141
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
142
|
+
const { name, arguments: args } = request.params;
|
|
143
|
+
if (name === 'login') {
|
|
144
|
+
try {
|
|
145
|
+
const result = await loginWithQRWeb();
|
|
146
|
+
saveAccount({
|
|
147
|
+
accountId: result.accountId,
|
|
148
|
+
token: result.token,
|
|
149
|
+
baseUrl: result.baseUrl,
|
|
150
|
+
savedAt: new Date().toISOString(),
|
|
151
|
+
});
|
|
152
|
+
// Start polling after login
|
|
153
|
+
startPolling();
|
|
154
|
+
return {
|
|
155
|
+
content: [
|
|
156
|
+
{
|
|
157
|
+
type: 'text',
|
|
158
|
+
text: `WeChat login successful! Account: ${result.accountId}. Polling started.`,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
return {
|
|
165
|
+
content: [
|
|
166
|
+
{ type: 'text', text: `Login failed: ${String(err)}` },
|
|
167
|
+
],
|
|
168
|
+
isError: true,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (name === 'reply') {
|
|
173
|
+
const userId = args.user_id;
|
|
174
|
+
const contextToken = args.context_token;
|
|
175
|
+
const content = args.content;
|
|
176
|
+
const media = args.media;
|
|
177
|
+
if (!userId || !contextToken || !content) {
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
{ type: 'text', text: 'Missing required fields: user_id, context_token, content' },
|
|
181
|
+
],
|
|
182
|
+
isError: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// Validate media path if provided
|
|
186
|
+
if (media && !fs.existsSync(media)) {
|
|
187
|
+
return {
|
|
188
|
+
content: [
|
|
189
|
+
{ type: 'text', text: `Media file not found: ${media}` },
|
|
190
|
+
],
|
|
191
|
+
isError: true,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const account = getActiveAccount();
|
|
195
|
+
if (!account) {
|
|
196
|
+
return {
|
|
197
|
+
content: [
|
|
198
|
+
{ type: 'text', text: 'Not logged in. Use the login tool first.' },
|
|
199
|
+
],
|
|
200
|
+
isError: true,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
// Send typing indicator
|
|
205
|
+
const ticket = typingTicketCache.get(userId);
|
|
206
|
+
if (ticket) {
|
|
207
|
+
await sendTyping(account.token, userId, ticket, 1, account.baseUrl).catch(() => { });
|
|
208
|
+
}
|
|
209
|
+
// Strip markdown and chunk
|
|
210
|
+
const plainText = stripMarkdown(content);
|
|
211
|
+
const chunks = chunkText(plainText);
|
|
212
|
+
for (const chunk of chunks) {
|
|
213
|
+
await sendMessage(account.token, userId, chunk, contextToken, account.baseUrl);
|
|
214
|
+
}
|
|
215
|
+
// Send media if provided
|
|
216
|
+
let mediaSent = false;
|
|
217
|
+
if (media) {
|
|
218
|
+
await uploadAndSendMedia({
|
|
219
|
+
token: account.token,
|
|
220
|
+
toUser: userId,
|
|
221
|
+
contextToken,
|
|
222
|
+
filePath: media,
|
|
223
|
+
baseUrl: account.baseUrl,
|
|
224
|
+
});
|
|
225
|
+
mediaSent = true;
|
|
226
|
+
}
|
|
227
|
+
// Cancel typing
|
|
228
|
+
if (ticket) {
|
|
229
|
+
await sendTyping(account.token, userId, ticket, 2, account.baseUrl).catch(() => { });
|
|
230
|
+
}
|
|
231
|
+
const parts = [`Reply sent to ${userId} (${chunks.length} chunk${chunks.length > 1 ? 's' : ''})`];
|
|
232
|
+
if (mediaSent)
|
|
233
|
+
parts.push(`Media sent: ${media}`);
|
|
234
|
+
return {
|
|
235
|
+
content: [
|
|
236
|
+
{
|
|
237
|
+
type: 'text',
|
|
238
|
+
text: parts.join('. '),
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
return {
|
|
245
|
+
content: [
|
|
246
|
+
{ type: 'text', text: `Failed to send reply: ${String(err)}` },
|
|
247
|
+
],
|
|
248
|
+
isError: true,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
254
|
+
isError: true,
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Long-polling loop
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
const SESSION_EXPIRED_ERRCODE = -14;
|
|
261
|
+
const MAX_CONSECUTIVE_FAILURES = 3;
|
|
262
|
+
const BACKOFF_DELAY_MS = 30_000;
|
|
263
|
+
const RETRY_DELAY_MS = 2_000;
|
|
264
|
+
const SESSION_PAUSE_MS = 5 * 60_000;
|
|
265
|
+
function sleep(ms, signal) {
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
const t = setTimeout(resolve, ms);
|
|
268
|
+
signal?.addEventListener('abort', () => {
|
|
269
|
+
clearTimeout(t);
|
|
270
|
+
reject(new Error('aborted'));
|
|
271
|
+
}, { once: true });
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async function pollLoop(account) {
|
|
275
|
+
let buf = loadSyncBuf(account.accountId);
|
|
276
|
+
let consecutiveFailures = 0;
|
|
277
|
+
let nextTimeoutMs = 35_000;
|
|
278
|
+
process.stderr.write(`[wechat-channel] Polling started for account ${account.accountId}\n`);
|
|
279
|
+
while (pollingActive && !pollingAbort?.signal.aborted) {
|
|
280
|
+
try {
|
|
281
|
+
const resp = await getUpdates(account.token, buf, account.baseUrl, nextTimeoutMs);
|
|
282
|
+
// Update timeout if server suggests one
|
|
283
|
+
if (resp.longpolling_timeout_ms != null && resp.longpolling_timeout_ms > 0) {
|
|
284
|
+
nextTimeoutMs = resp.longpolling_timeout_ms;
|
|
285
|
+
}
|
|
286
|
+
// Check for API errors
|
|
287
|
+
const isApiError = (resp.ret !== undefined && resp.ret !== 0) ||
|
|
288
|
+
(resp.errcode !== undefined && resp.errcode !== 0);
|
|
289
|
+
if (isApiError) {
|
|
290
|
+
const isSessionExpired = resp.errcode === SESSION_EXPIRED_ERRCODE || resp.ret === SESSION_EXPIRED_ERRCODE;
|
|
291
|
+
if (isSessionExpired) {
|
|
292
|
+
process.stderr.write(`[wechat-channel] Session expired (errcode ${SESSION_EXPIRED_ERRCODE}), pausing ${Math.ceil(SESSION_PAUSE_MS / 60_000)} min\n`);
|
|
293
|
+
consecutiveFailures = 0;
|
|
294
|
+
await sleep(SESSION_PAUSE_MS, pollingAbort?.signal);
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
consecutiveFailures++;
|
|
298
|
+
process.stderr.write(`[wechat-channel] getUpdates error: ret=${resp.ret} errcode=${resp.errcode} errmsg=${resp.errmsg ?? ''} (${consecutiveFailures}/${MAX_CONSECUTIVE_FAILURES})\n`);
|
|
299
|
+
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
300
|
+
consecutiveFailures = 0;
|
|
301
|
+
await sleep(BACKOFF_DELAY_MS, pollingAbort?.signal);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
await sleep(RETRY_DELAY_MS, pollingAbort?.signal);
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
consecutiveFailures = 0;
|
|
309
|
+
// Save sync buf
|
|
310
|
+
if (resp.get_updates_buf != null && resp.get_updates_buf !== '') {
|
|
311
|
+
saveSyncBuf(account.accountId, resp.get_updates_buf);
|
|
312
|
+
buf = resp.get_updates_buf;
|
|
313
|
+
}
|
|
314
|
+
// Process messages
|
|
315
|
+
const msgs = resp.msgs ?? [];
|
|
316
|
+
for (const msg of msgs) {
|
|
317
|
+
// Only process user messages (message_type === 1)
|
|
318
|
+
if (msg.message_type !== 1)
|
|
319
|
+
continue;
|
|
320
|
+
const text = extractText(msg);
|
|
321
|
+
const fromUser = msg.from_user_id ?? 'unknown';
|
|
322
|
+
const contextToken = msg.context_token ?? '';
|
|
323
|
+
process.stderr.write(`[wechat-channel] Message from ${fromUser}: ${text.slice(0, 100)}\n`);
|
|
324
|
+
// Cache typing ticket for this user
|
|
325
|
+
try {
|
|
326
|
+
const cfg = await getConfig(account.token, fromUser, contextToken, account.baseUrl);
|
|
327
|
+
if (cfg.typing_ticket) {
|
|
328
|
+
typingTicketCache.set(fromUser, cfg.typing_ticket);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// non-critical
|
|
333
|
+
}
|
|
334
|
+
// Send typing indicator
|
|
335
|
+
const ticket = typingTicketCache.get(fromUser);
|
|
336
|
+
if (ticket) {
|
|
337
|
+
await sendTyping(account.token, fromUser, ticket, 1, account.baseUrl).catch(() => { });
|
|
338
|
+
}
|
|
339
|
+
// Push to Claude Code via channel notification
|
|
340
|
+
server.notification({
|
|
341
|
+
method: 'notifications/claude/channel',
|
|
342
|
+
params: {
|
|
343
|
+
content: `${text}\n\n[System: Reply via the "reply" tool. user_id and context_token are in the message metadata above.]`,
|
|
344
|
+
meta: {
|
|
345
|
+
source: 'wechat',
|
|
346
|
+
sender: fromUser,
|
|
347
|
+
user_id: fromUser,
|
|
348
|
+
context_token: contextToken,
|
|
349
|
+
message_id: String(msg.message_id ?? ''),
|
|
350
|
+
session_id: msg.session_id ?? '',
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
catch (err) {
|
|
357
|
+
if (pollingAbort?.signal.aborted)
|
|
358
|
+
return;
|
|
359
|
+
consecutiveFailures++;
|
|
360
|
+
process.stderr.write(`[wechat-channel] Poll error (${consecutiveFailures}/${MAX_CONSECUTIVE_FAILURES}): ${String(err)}\n`);
|
|
361
|
+
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
362
|
+
consecutiveFailures = 0;
|
|
363
|
+
await sleep(BACKOFF_DELAY_MS, pollingAbort?.signal);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
await sleep(RETRY_DELAY_MS, pollingAbort?.signal);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function startPolling() {
|
|
372
|
+
const account = getActiveAccount();
|
|
373
|
+
if (!account) {
|
|
374
|
+
process.stderr.write('[wechat-channel] No account found, skipping polling\n');
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (pollingActive) {
|
|
378
|
+
process.stderr.write('[wechat-channel] Polling already active\n');
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
pollingActive = true;
|
|
382
|
+
pollingAbort = new AbortController();
|
|
383
|
+
// Run poll loop in background (don't await)
|
|
384
|
+
pollLoop(account).catch((err) => {
|
|
385
|
+
if (!pollingAbort?.signal.aborted) {
|
|
386
|
+
process.stderr.write(`[wechat-channel] Poll loop crashed: ${String(err)}\n`);
|
|
387
|
+
}
|
|
388
|
+
pollingActive = false;
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
// ---------------------------------------------------------------------------
|
|
392
|
+
// Main
|
|
393
|
+
// ---------------------------------------------------------------------------
|
|
394
|
+
async function main() {
|
|
395
|
+
const transport = new StdioServerTransport();
|
|
396
|
+
await server.connect(transport);
|
|
397
|
+
process.stderr.write('[wechat-channel] MCP server started\n');
|
|
398
|
+
// Auto-start polling if we have saved credentials
|
|
399
|
+
const account = getActiveAccount();
|
|
400
|
+
if (account) {
|
|
401
|
+
process.stderr.write(`[wechat-channel] Found saved account: ${account.accountId}\n`);
|
|
402
|
+
startPolling();
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
process.stderr.write('[wechat-channel] No saved account. Use the login tool to connect.\n');
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
main().catch((err) => {
|
|
409
|
+
process.stderr.write(`[wechat-channel] Fatal: ${String(err)}\n`);
|
|
410
|
+
process.exit(1);
|
|
411
|
+
});
|
|
412
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface AccountData {
|
|
2
|
+
accountId: string;
|
|
3
|
+
token: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
savedAt: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function loadAccounts(): AccountData[];
|
|
8
|
+
export declare function saveAccount(account: AccountData): void;
|
|
9
|
+
export declare function getActiveAccount(): AccountData | null;
|
|
10
|
+
export declare function removeAccount(accountId: string): void;
|
|
11
|
+
export declare function loadSyncBuf(accountId: string): string;
|
|
12
|
+
export declare function saveSyncBuf(accountId: string, buf: string): void;
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
const CHANNEL_DIR = path.join(os.homedir(), '.claude', 'channels', 'wechat-channel');
|
|
5
|
+
function ensureDir(dir) {
|
|
6
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
7
|
+
}
|
|
8
|
+
function accountsFilePath() {
|
|
9
|
+
return path.join(CHANNEL_DIR, 'accounts.json');
|
|
10
|
+
}
|
|
11
|
+
export function loadAccounts() {
|
|
12
|
+
try {
|
|
13
|
+
const raw = fs.readFileSync(accountsFilePath(), 'utf-8');
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function saveAccount(account) {
|
|
22
|
+
ensureDir(CHANNEL_DIR);
|
|
23
|
+
const accounts = loadAccounts().filter((a) => a.accountId !== account.accountId);
|
|
24
|
+
accounts.push(account);
|
|
25
|
+
const filePath = accountsFilePath();
|
|
26
|
+
fs.writeFileSync(filePath, JSON.stringify(accounts, null, 2), 'utf-8');
|
|
27
|
+
try {
|
|
28
|
+
fs.chmodSync(filePath, 0o600);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// best-effort
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function getActiveAccount() {
|
|
35
|
+
const accounts = loadAccounts();
|
|
36
|
+
return accounts.length > 0 ? accounts[accounts.length - 1] : null;
|
|
37
|
+
}
|
|
38
|
+
export function removeAccount(accountId) {
|
|
39
|
+
const accounts = loadAccounts().filter((a) => a.accountId !== accountId);
|
|
40
|
+
ensureDir(CHANNEL_DIR);
|
|
41
|
+
fs.writeFileSync(accountsFilePath(), JSON.stringify(accounts, null, 2), 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Sync buf (long-poll cursor)
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
function syncBufFilePath(accountId) {
|
|
47
|
+
return path.join(CHANNEL_DIR, `sync-buf-${accountId}.txt`);
|
|
48
|
+
}
|
|
49
|
+
export function loadSyncBuf(accountId) {
|
|
50
|
+
try {
|
|
51
|
+
return fs.readFileSync(syncBufFilePath(accountId), 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function saveSyncBuf(accountId, buf) {
|
|
58
|
+
ensureDir(CHANNEL_DIR);
|
|
59
|
+
fs.writeFileSync(syncBufFilePath(accountId), buf, 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/** Common request metadata attached to every CGI request. */
|
|
2
|
+
export interface BaseInfo {
|
|
3
|
+
channel_version?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const MessageType: {
|
|
6
|
+
readonly NONE: 0;
|
|
7
|
+
readonly USER: 1;
|
|
8
|
+
readonly BOT: 2;
|
|
9
|
+
};
|
|
10
|
+
export declare const MessageItemType: {
|
|
11
|
+
readonly NONE: 0;
|
|
12
|
+
readonly TEXT: 1;
|
|
13
|
+
readonly IMAGE: 2;
|
|
14
|
+
readonly VOICE: 3;
|
|
15
|
+
readonly FILE: 4;
|
|
16
|
+
readonly VIDEO: 5;
|
|
17
|
+
};
|
|
18
|
+
export declare const MessageState: {
|
|
19
|
+
readonly NEW: 0;
|
|
20
|
+
readonly GENERATING: 1;
|
|
21
|
+
readonly FINISH: 2;
|
|
22
|
+
};
|
|
23
|
+
export declare const TypingStatus: {
|
|
24
|
+
readonly TYPING: 1;
|
|
25
|
+
readonly CANCEL: 2;
|
|
26
|
+
};
|
|
27
|
+
export interface TextItem {
|
|
28
|
+
text?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CDNMedia {
|
|
31
|
+
encrypt_query_param?: string;
|
|
32
|
+
aes_key?: string;
|
|
33
|
+
encrypt_type?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface ImageItem {
|
|
36
|
+
media?: CDNMedia;
|
|
37
|
+
thumb_media?: CDNMedia;
|
|
38
|
+
aeskey?: string;
|
|
39
|
+
url?: string;
|
|
40
|
+
mid_size?: number;
|
|
41
|
+
thumb_size?: number;
|
|
42
|
+
thumb_height?: number;
|
|
43
|
+
thumb_width?: number;
|
|
44
|
+
hd_size?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface VoiceItem {
|
|
47
|
+
media?: CDNMedia;
|
|
48
|
+
encode_type?: number;
|
|
49
|
+
bits_per_sample?: number;
|
|
50
|
+
sample_rate?: number;
|
|
51
|
+
playtime?: number;
|
|
52
|
+
text?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface FileItem {
|
|
55
|
+
media?: CDNMedia;
|
|
56
|
+
file_name?: string;
|
|
57
|
+
md5?: string;
|
|
58
|
+
len?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface VideoItem {
|
|
61
|
+
media?: CDNMedia;
|
|
62
|
+
video_size?: number;
|
|
63
|
+
play_length?: number;
|
|
64
|
+
video_md5?: string;
|
|
65
|
+
thumb_media?: CDNMedia;
|
|
66
|
+
thumb_size?: number;
|
|
67
|
+
thumb_height?: number;
|
|
68
|
+
thumb_width?: number;
|
|
69
|
+
}
|
|
70
|
+
export interface RefMessage {
|
|
71
|
+
message_item?: MessageItem;
|
|
72
|
+
title?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface MessageItem {
|
|
75
|
+
type?: number;
|
|
76
|
+
create_time_ms?: number;
|
|
77
|
+
update_time_ms?: number;
|
|
78
|
+
is_completed?: boolean;
|
|
79
|
+
msg_id?: string;
|
|
80
|
+
ref_msg?: RefMessage;
|
|
81
|
+
text_item?: TextItem;
|
|
82
|
+
image_item?: ImageItem;
|
|
83
|
+
voice_item?: VoiceItem;
|
|
84
|
+
file_item?: FileItem;
|
|
85
|
+
video_item?: VideoItem;
|
|
86
|
+
}
|
|
87
|
+
export interface WeixinMessage {
|
|
88
|
+
seq?: number;
|
|
89
|
+
message_id?: number;
|
|
90
|
+
from_user_id?: string;
|
|
91
|
+
to_user_id?: string;
|
|
92
|
+
client_id?: string;
|
|
93
|
+
create_time_ms?: number;
|
|
94
|
+
update_time_ms?: number;
|
|
95
|
+
delete_time_ms?: number;
|
|
96
|
+
session_id?: string;
|
|
97
|
+
group_id?: string;
|
|
98
|
+
message_type?: number;
|
|
99
|
+
message_state?: number;
|
|
100
|
+
item_list?: MessageItem[];
|
|
101
|
+
context_token?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface GetUpdatesReq {
|
|
104
|
+
get_updates_buf?: string;
|
|
105
|
+
}
|
|
106
|
+
export interface GetUpdatesResp {
|
|
107
|
+
ret?: number;
|
|
108
|
+
errcode?: number;
|
|
109
|
+
errmsg?: string;
|
|
110
|
+
msgs?: WeixinMessage[];
|
|
111
|
+
get_updates_buf?: string;
|
|
112
|
+
longpolling_timeout_ms?: number;
|
|
113
|
+
}
|
|
114
|
+
export interface SendMessageReq {
|
|
115
|
+
msg?: WeixinMessage;
|
|
116
|
+
}
|
|
117
|
+
export interface SendTypingReq {
|
|
118
|
+
ilink_user_id?: string;
|
|
119
|
+
typing_ticket?: string;
|
|
120
|
+
status?: number;
|
|
121
|
+
}
|
|
122
|
+
export interface GetConfigResp {
|
|
123
|
+
ret?: number;
|
|
124
|
+
errmsg?: string;
|
|
125
|
+
typing_ticket?: string;
|
|
126
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const MessageType = {
|
|
2
|
+
NONE: 0,
|
|
3
|
+
USER: 1,
|
|
4
|
+
BOT: 2,
|
|
5
|
+
};
|
|
6
|
+
export const MessageItemType = {
|
|
7
|
+
NONE: 0,
|
|
8
|
+
TEXT: 1,
|
|
9
|
+
IMAGE: 2,
|
|
10
|
+
VOICE: 3,
|
|
11
|
+
FILE: 4,
|
|
12
|
+
VIDEO: 5,
|
|
13
|
+
};
|
|
14
|
+
export const MessageState = {
|
|
15
|
+
NEW: 0,
|
|
16
|
+
GENERATING: 1,
|
|
17
|
+
FINISH: 2,
|
|
18
|
+
};
|
|
19
|
+
export const TypingStatus = {
|
|
20
|
+
TYPING: 1,
|
|
21
|
+
CANCEL: 2,
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,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"}
|