crewly 1.4.69 → 1.4.70

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.
Files changed (41) hide show
  1. package/dist/backend/backend/src/constants.d.ts +1 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +1 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
  6. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +4 -1
  7. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
  8. package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts +17 -9
  9. package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts.map +1 -1
  10. package/dist/backend/backend/src/middleware/require-auth.middleware.js +60 -10
  11. package/dist/backend/backend/src/middleware/require-auth.middleware.js.map +1 -1
  12. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  13. package/dist/backend/backend/src/routes/api.routes.js +3 -0
  14. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  15. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +6 -1
  16. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
  17. package/dist/backend/backend/src/services/agent/claude-runtime.service.js +14 -2
  18. package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
  19. package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.d.ts +47 -0
  20. package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.d.ts.map +1 -0
  21. package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.js +69 -0
  22. package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.js.map +1 -0
  23. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +1 -1
  24. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/wechat/wechat-bridge.service.d.ts +69 -0
  26. package/dist/backend/backend/src/services/wechat/wechat-bridge.service.d.ts.map +1 -0
  27. package/dist/backend/backend/src/services/wechat/wechat-bridge.service.js +133 -0
  28. package/dist/backend/backend/src/services/wechat/wechat-bridge.service.js.map +1 -0
  29. package/dist/backend/backend/src/services/wechat/wechat.controller.d.ts +51 -0
  30. package/dist/backend/backend/src/services/wechat/wechat.controller.d.ts.map +1 -0
  31. package/dist/backend/backend/src/services/wechat/wechat.controller.js +104 -0
  32. package/dist/backend/backend/src/services/wechat/wechat.controller.js.map +1 -0
  33. package/dist/backend/backend/src/services/wechat/wechat.service.d.ts +171 -0
  34. package/dist/backend/backend/src/services/wechat/wechat.service.d.ts.map +1 -0
  35. package/dist/backend/backend/src/services/wechat/wechat.service.js +411 -0
  36. package/dist/backend/backend/src/services/wechat/wechat.service.js.map +1 -0
  37. package/dist/cli/backend/src/constants.d.ts +1 -0
  38. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  39. package/dist/cli/backend/src/constants.js +1 -0
  40. package/dist/cli/backend/src/constants.js.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,69 @@
1
+ /**
2
+ * WeChat Messenger Adapter
3
+ *
4
+ * Implements the MessengerAdapter interface for the WeChat iLink Bot.
5
+ * Delegates to WeChatService for actual operations.
6
+ *
7
+ * @module services/messaging/adapters/wechat-messenger.adapter
8
+ */
9
+ import { getWeChatService } from '../../wechat/wechat.service.js';
10
+ import { WeChatBridge } from '../../wechat/wechat-bridge.service.js';
11
+ /**
12
+ * Messenger adapter for WeChat using the iLink Bot API.
13
+ */
14
+ export class WeChatMessengerAdapter {
15
+ platform = 'wechat';
16
+ /**
17
+ * Initialize the adapter by restoring persisted WeChat connection.
18
+ *
19
+ * @param config - Configuration (unused — token loaded from disk)
20
+ */
21
+ async initialize(config) {
22
+ const service = getWeChatService();
23
+ await service.tryRestore();
24
+ }
25
+ /**
26
+ * Send a text message via WeChat.
27
+ *
28
+ * Uses the WeChatBridge to find the context token for the channel
29
+ * (conversation ID) and send the reply.
30
+ *
31
+ * @param channel - Conversation ID (e.g., "wechat-user123")
32
+ * @param text - Message content
33
+ * @param _options - Send options (unused for WeChat)
34
+ */
35
+ async sendMessage(channel, text, _options) {
36
+ const bridge = WeChatBridge.getInstance();
37
+ const contextToken = bridge.getContextToken(channel);
38
+ if (!contextToken) {
39
+ throw new Error(`No WeChat context token for channel: ${channel}`);
40
+ }
41
+ const service = getWeChatService();
42
+ await service.sendMessage(text, contextToken);
43
+ }
44
+ /**
45
+ * Get the current connection status.
46
+ *
47
+ * @returns Status object with connection state
48
+ */
49
+ getStatus() {
50
+ const service = getWeChatService();
51
+ const status = service.getStatus();
52
+ return {
53
+ connected: service.isConnected(),
54
+ platform: this.platform,
55
+ details: {
56
+ state: status.state,
57
+ botName: status.botName,
58
+ },
59
+ };
60
+ }
61
+ /**
62
+ * Disconnect the WeChat service.
63
+ */
64
+ async disconnect() {
65
+ const service = getWeChatService();
66
+ service.disconnect();
67
+ }
68
+ }
69
+ //# sourceMappingURL=wechat-messenger.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-messenger.adapter.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/messaging/adapters/wechat-messenger.adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAGrE;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACxB,QAAQ,GAAG,QAA6B,CAAC;IAElD;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,MAA+B;QAC9C,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAAY,EAAE,QAAsB;QACrE,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAErD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QAEnC,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE;YAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,OAAO,CAAC,UAAU,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Supported messenger platforms.
3
3
  */
4
- export type MessengerPlatform = 'slack' | 'telegram' | 'discord' | 'google-chat';
4
+ export type MessengerPlatform = 'slack' | 'telegram' | 'discord' | 'google-chat' | 'wechat';
5
5
  /**
6
6
  * A message received from any messenger platform.
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"messenger-adapter.interface.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/messenger-adapter.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,kEAAkE;IAClE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,mDAAmD;IACnD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,wCAAwC;IACxC,SAAS,IAAI;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACpG,wCAAwC;IACxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B"}
1
+ {"version":3,"file":"messenger-adapter.interface.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/messenger-adapter.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;AAE5F;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,kEAAkE;IAClE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,mDAAmD;IACnD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,wCAAwC;IACxC,SAAS,IAAI;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACpG,wCAAwC;IACxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * WeChat Orchestrator Bridge
3
+ *
4
+ * Routes incoming WeChat messages to the orchestrator message queue
5
+ * and sends orchestrator replies back via WeChat.
6
+ *
7
+ * Similar to SlackOrchestratorBridge but for the WeChat iLink Bot channel.
8
+ *
9
+ * @module services/wechat/wechat-bridge.service
10
+ */
11
+ /** Minimal interface for MessageQueueService to avoid circular imports. */
12
+ interface IMessageQueueServiceLike {
13
+ enqueue(input: {
14
+ content: string;
15
+ conversationId: string;
16
+ source: 'wechat';
17
+ sourceMetadata?: Record<string, string>;
18
+ }): unknown;
19
+ }
20
+ /**
21
+ * Bridge between WeChat messages and the orchestrator.
22
+ *
23
+ * Listens for 'message' events from WeChatService and enqueues them
24
+ * into the orchestrator message queue. Stores context_token per
25
+ * conversation so replies can be routed back through WeChat.
26
+ */
27
+ export declare class WeChatBridge {
28
+ private static instance;
29
+ private readonly logger;
30
+ private messageQueue;
31
+ private contextTokens;
32
+ private initialized;
33
+ private constructor();
34
+ /**
35
+ * Get the singleton instance.
36
+ *
37
+ * @returns WeChatBridge instance
38
+ */
39
+ static getInstance(): WeChatBridge;
40
+ /**
41
+ * Initialize the bridge with the message queue service.
42
+ *
43
+ * @param messageQueue - The orchestrator message queue for enqueuing messages
44
+ */
45
+ initialize(messageQueue: IMessageQueueServiceLike): void;
46
+ /**
47
+ * Send a reply back to WeChat using the stored context token.
48
+ *
49
+ * @param conversationId - The conversation ID to reply to
50
+ * @param text - Reply text
51
+ * @returns True if sent successfully
52
+ */
53
+ sendReply(conversationId: string, text: string): Promise<boolean>;
54
+ /**
55
+ * Get the stored context token for a conversation.
56
+ *
57
+ * @param conversationId - Conversation ID
58
+ * @returns Context token or undefined
59
+ */
60
+ getContextToken(conversationId: string): string | undefined;
61
+ /**
62
+ * Handle an incoming WeChat message by enqueuing it for the orchestrator.
63
+ *
64
+ * @param msg - Incoming WeChat message
65
+ */
66
+ private handleIncomingMessage;
67
+ }
68
+ export {};
69
+ //# sourceMappingURL=wechat-bridge.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-bridge.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wechat/wechat-bridge.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,2EAA2E;AAC3E,UAAU,wBAAwB;IAChC,OAAO,CAAC,KAAK,EAAE;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,QAAQ,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,GAAG,OAAO,CAAC;CACb;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO;IAIP;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,YAAY;IAOlC;;;;OAIG;IACH,UAAU,CAAC,YAAY,EAAE,wBAAwB,GAAG,IAAI;IAgBxD;;;;;;OAMG;IACG,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBvE;;;;;OAKG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ3D;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;CAmC9B"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * WeChat Orchestrator Bridge
3
+ *
4
+ * Routes incoming WeChat messages to the orchestrator message queue
5
+ * and sends orchestrator replies back via WeChat.
6
+ *
7
+ * Similar to SlackOrchestratorBridge but for the WeChat iLink Bot channel.
8
+ *
9
+ * @module services/wechat/wechat-bridge.service
10
+ */
11
+ import { LoggerService } from '../core/logger.service.js';
12
+ import { getWeChatService } from './wechat.service.js';
13
+ /**
14
+ * Bridge between WeChat messages and the orchestrator.
15
+ *
16
+ * Listens for 'message' events from WeChatService and enqueues them
17
+ * into the orchestrator message queue. Stores context_token per
18
+ * conversation so replies can be routed back through WeChat.
19
+ */
20
+ export class WeChatBridge {
21
+ static instance = null;
22
+ logger;
23
+ messageQueue = null;
24
+ contextTokens = new Map();
25
+ initialized = false;
26
+ constructor() {
27
+ this.logger = LoggerService.getInstance().createComponentLogger('WeChatBridge');
28
+ }
29
+ /**
30
+ * Get the singleton instance.
31
+ *
32
+ * @returns WeChatBridge instance
33
+ */
34
+ static getInstance() {
35
+ if (!WeChatBridge.instance) {
36
+ WeChatBridge.instance = new WeChatBridge();
37
+ }
38
+ return WeChatBridge.instance;
39
+ }
40
+ /**
41
+ * Initialize the bridge with the message queue service.
42
+ *
43
+ * @param messageQueue - The orchestrator message queue for enqueuing messages
44
+ */
45
+ initialize(messageQueue) {
46
+ if (this.initialized)
47
+ return;
48
+ this.messageQueue = messageQueue;
49
+ const wechat = getWeChatService();
50
+ wechat.on('message', (msg) => this.handleIncomingMessage(msg));
51
+ wechat.on('disconnected', () => {
52
+ this.logger.info('WeChat disconnected — bridge paused');
53
+ this.contextTokens.clear();
54
+ });
55
+ this.initialized = true;
56
+ this.logger.info('WeChat bridge initialized');
57
+ }
58
+ /**
59
+ * Send a reply back to WeChat using the stored context token.
60
+ *
61
+ * @param conversationId - The conversation ID to reply to
62
+ * @param text - Reply text
63
+ * @returns True if sent successfully
64
+ */
65
+ async sendReply(conversationId, text) {
66
+ const contextToken = this.contextTokens.get(conversationId);
67
+ if (!contextToken) {
68
+ this.logger.warn('No context token for WeChat reply', { conversationId });
69
+ return false;
70
+ }
71
+ try {
72
+ const wechat = getWeChatService();
73
+ await wechat.sendMessage(text, contextToken);
74
+ return true;
75
+ }
76
+ catch (err) {
77
+ this.logger.error('Failed to send WeChat reply', {
78
+ conversationId,
79
+ error: err instanceof Error ? err.message : String(err),
80
+ });
81
+ return false;
82
+ }
83
+ }
84
+ /**
85
+ * Get the stored context token for a conversation.
86
+ *
87
+ * @param conversationId - Conversation ID
88
+ * @returns Context token or undefined
89
+ */
90
+ getContextToken(conversationId) {
91
+ return this.contextTokens.get(conversationId);
92
+ }
93
+ // -------------------------------------------------------------------------
94
+ // Internal
95
+ // -------------------------------------------------------------------------
96
+ /**
97
+ * Handle an incoming WeChat message by enqueuing it for the orchestrator.
98
+ *
99
+ * @param msg - Incoming WeChat message
100
+ */
101
+ handleIncomingMessage(msg) {
102
+ if (!this.messageQueue) {
103
+ this.logger.warn('Message queue not available, dropping WeChat message');
104
+ return;
105
+ }
106
+ // Skip non-text messages
107
+ if (msg.msg_type !== 'text') {
108
+ this.logger.debug('Skipping non-text WeChat message', { msgType: msg.msg_type });
109
+ return;
110
+ }
111
+ // Store context token for reply routing
112
+ const conversationId = `wechat-${msg.from_user}`;
113
+ this.contextTokens.set(conversationId, msg.context_token);
114
+ // Enqueue for orchestrator processing
115
+ this.messageQueue.enqueue({
116
+ content: msg.content,
117
+ conversationId,
118
+ source: 'wechat',
119
+ sourceMetadata: {
120
+ fromUser: msg.from_user,
121
+ fromUserName: msg.from_user_name,
122
+ msgId: msg.msg_id,
123
+ contextToken: msg.context_token,
124
+ },
125
+ });
126
+ this.logger.info('WeChat message enqueued for orchestrator', {
127
+ from: msg.from_user_name,
128
+ conversationId,
129
+ contentLength: msg.content.length,
130
+ });
131
+ }
132
+ }
133
+ //# sourceMappingURL=wechat-bridge.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-bridge.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wechat/wechat-bridge.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * WeChat REST Controller
3
+ *
4
+ * HTTP endpoints for managing the WeChat iLink Bot integration.
5
+ *
6
+ * Routes:
7
+ * - POST /api/wechat/qrcode — Generate login QR code
8
+ * - GET /api/wechat/status — Get connection status
9
+ * - POST /api/wechat/disconnect — Disconnect WeChat
10
+ *
11
+ * @module services/wechat/wechat.controller
12
+ */
13
+ import type { Request, Response, NextFunction } from 'express';
14
+ import { Router } from 'express';
15
+ /**
16
+ * POST /api/wechat/qrcode
17
+ *
18
+ * Generate a WeChat login QR code. The frontend displays this QR code
19
+ * for the user to scan with their WeChat app.
20
+ *
21
+ * @param _req - Express request (no body required)
22
+ * @param res - Response with { success, data: { qrcodeUrl, ticket } }
23
+ * @param next - Next function
24
+ */
25
+ export declare function getQRCode(_req: Request, res: Response, next: NextFunction): Promise<void>;
26
+ /**
27
+ * GET /api/wechat/status
28
+ *
29
+ * Get the current WeChat connection status.
30
+ *
31
+ * @param _req - Express request
32
+ * @param res - Response with { success, data: { state, botName, connectedAt } }
33
+ */
34
+ export declare function getStatus(_req: Request, res: Response): void;
35
+ /**
36
+ * POST /api/wechat/disconnect
37
+ *
38
+ * Disconnect the WeChat bot and clear credentials.
39
+ *
40
+ * @param _req - Express request
41
+ * @param res - Response with { success }
42
+ * @param next - Next function
43
+ */
44
+ export declare function disconnectWeChat(_req: Request, res: Response, next: NextFunction): Promise<void>;
45
+ /**
46
+ * Create the WeChat router with all endpoints.
47
+ *
48
+ * @returns Express router for /api/wechat/*
49
+ */
50
+ export declare function createWeChatRouter(): Router;
51
+ //# sourceMappingURL=wechat.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wechat/wechat.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAMjC;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB/F;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAQ5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CActG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAQ3C"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * WeChat REST Controller
3
+ *
4
+ * HTTP endpoints for managing the WeChat iLink Bot integration.
5
+ *
6
+ * Routes:
7
+ * - POST /api/wechat/qrcode — Generate login QR code
8
+ * - GET /api/wechat/status — Get connection status
9
+ * - POST /api/wechat/disconnect — Disconnect WeChat
10
+ *
11
+ * @module services/wechat/wechat.controller
12
+ */
13
+ import { Router } from 'express';
14
+ import { getWeChatService } from './wechat.service.js';
15
+ import { LoggerService } from '../core/logger.service.js';
16
+ const logger = LoggerService.getInstance().createComponentLogger('WeChatController');
17
+ /**
18
+ * POST /api/wechat/qrcode
19
+ *
20
+ * Generate a WeChat login QR code. The frontend displays this QR code
21
+ * for the user to scan with their WeChat app.
22
+ *
23
+ * @param _req - Express request (no body required)
24
+ * @param res - Response with { success, data: { qrcodeUrl, ticket } }
25
+ * @param next - Next function
26
+ */
27
+ export async function getQRCode(_req, res, next) {
28
+ try {
29
+ const service = getWeChatService();
30
+ const qrData = await service.getQRCode();
31
+ res.json({
32
+ success: true,
33
+ data: {
34
+ qrcodeUrl: qrData.qrcode_url,
35
+ ticket: qrData.qrcode_ticket,
36
+ },
37
+ });
38
+ // Start polling for QR code status in the background
39
+ service.pollQRCodeStatus(qrData.qrcode_ticket).catch((err) => {
40
+ logger.warn('QR code status polling ended', {
41
+ error: err instanceof Error ? err.message : String(err),
42
+ });
43
+ });
44
+ }
45
+ catch (error) {
46
+ logger.error('Failed to generate WeChat QR code', {
47
+ error: error instanceof Error ? error.message : String(error),
48
+ });
49
+ next(error);
50
+ }
51
+ }
52
+ /**
53
+ * GET /api/wechat/status
54
+ *
55
+ * Get the current WeChat connection status.
56
+ *
57
+ * @param _req - Express request
58
+ * @param res - Response with { success, data: { state, botName, connectedAt } }
59
+ */
60
+ export function getStatus(_req, res) {
61
+ const service = getWeChatService();
62
+ const status = service.getStatus();
63
+ res.json({
64
+ success: true,
65
+ data: status,
66
+ });
67
+ }
68
+ /**
69
+ * POST /api/wechat/disconnect
70
+ *
71
+ * Disconnect the WeChat bot and clear credentials.
72
+ *
73
+ * @param _req - Express request
74
+ * @param res - Response with { success }
75
+ * @param next - Next function
76
+ */
77
+ export async function disconnectWeChat(_req, res, next) {
78
+ try {
79
+ const service = getWeChatService();
80
+ service.disconnect();
81
+ await service.removeConfig();
82
+ logger.info('WeChat disconnected');
83
+ res.json({ success: true });
84
+ }
85
+ catch (error) {
86
+ logger.error('Failed to disconnect WeChat', {
87
+ error: error instanceof Error ? error.message : String(error),
88
+ });
89
+ next(error);
90
+ }
91
+ }
92
+ /**
93
+ * Create the WeChat router with all endpoints.
94
+ *
95
+ * @returns Express router for /api/wechat/*
96
+ */
97
+ export function createWeChatRouter() {
98
+ const router = Router();
99
+ router.post('/qrcode', getQRCode);
100
+ router.get('/status', getStatus);
101
+ router.post('/disconnect', disconnectWeChat);
102
+ return router;
103
+ }
104
+ //# sourceMappingURL=wechat.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wechat/wechat.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;AAErF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAa,EAAE,GAAa,EAAE,IAAkB;IAC9E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;QAEzC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,SAAS,EAAE,MAAM,CAAC,UAAU;gBAC5B,MAAM,EAAE,MAAM,CAAC,aAAa;aAC7B;SACF,CAAC,CAAC;QAEH,qDAAqD;QACrD,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3D,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;gBAC1C,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;YAChD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAa,EAAE,GAAa;IACpD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAEnC,GAAG,CAAC,IAAI,CAAC;QACP,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,MAAM;KACb,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa,EAAE,GAAa,EAAE,IAAkB;IACrF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAE7B,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE;YAC1C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAE7C,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * WeChat iLink Bot Service
3
+ *
4
+ * Integrates with the Tencent iLink Bot API for WeChat messaging.
5
+ * Supports QR code login, message polling, and sending replies.
6
+ *
7
+ * API Base: https://ilinkai.weixin.qq.com
8
+ * Auth: Bearer token with AuthorizationType: ilink_bot_token header
9
+ *
10
+ * @module services/wechat/wechat.service
11
+ */
12
+ import { EventEmitter } from 'events';
13
+ /** Persisted WeChat config. */
14
+ export interface WeChatConfig {
15
+ botToken: string;
16
+ connectedAt: string;
17
+ botName?: string;
18
+ }
19
+ /** QR code response from iLink API. */
20
+ export interface QRCodeResponse {
21
+ qrcode_url: string;
22
+ qrcode_ticket: string;
23
+ }
24
+ /** QR code status from iLink API. */
25
+ export interface QRCodeStatus {
26
+ status: 'waiting' | 'scanned' | 'confirmed' | 'expired';
27
+ bot_token?: string;
28
+ bot_name?: string;
29
+ }
30
+ /** Incoming WeChat message from getupdates. */
31
+ export interface WeChatMessage {
32
+ msg_id: string;
33
+ from_user: string;
34
+ from_user_name: string;
35
+ content: string;
36
+ msg_type: string;
37
+ context_token: string;
38
+ timestamp: number;
39
+ }
40
+ /** Service connection state. */
41
+ export type WeChatConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error';
42
+ /**
43
+ * WeChat iLink Bot Service.
44
+ *
45
+ * Singleton service that manages the WeChat bot connection lifecycle:
46
+ * - QR code generation for login
47
+ * - Long-polling for incoming messages
48
+ * - Sending replies
49
+ * - Persisting credentials to disk
50
+ *
51
+ * Events:
52
+ * - `message` — Fired for each incoming WeChat message
53
+ * - `connected` — Fired when QR code scan is confirmed
54
+ * - `disconnected` — Fired when service disconnects
55
+ * - `error` — Fired on unrecoverable errors
56
+ */
57
+ export declare class WeChatService extends EventEmitter {
58
+ private static instance;
59
+ private readonly logger;
60
+ private state;
61
+ private botToken;
62
+ private botName;
63
+ private pollCursor;
64
+ private pollTimer;
65
+ private isPolling;
66
+ private constructor();
67
+ /**
68
+ * Get the singleton instance.
69
+ *
70
+ * @returns WeChatService instance
71
+ */
72
+ static getInstance(): WeChatService;
73
+ /**
74
+ * Reset the singleton (for testing).
75
+ */
76
+ static resetInstance(): void;
77
+ /**
78
+ * Get a QR code for WeChat login.
79
+ *
80
+ * Calls the iLink API to generate a QR code that the user scans
81
+ * with their WeChat app to authorize the bot.
82
+ *
83
+ * @returns QR code URL and ticket for status polling
84
+ * @throws Error if API call fails
85
+ */
86
+ getQRCode(): Promise<QRCodeResponse>;
87
+ /**
88
+ * Poll the QR code status until the user scans and confirms.
89
+ *
90
+ * @param ticket - QR code ticket from getQRCode()
91
+ * @returns Resolved when confirmed, rejected on timeout/error
92
+ */
93
+ pollQRCodeStatus(ticket: string): Promise<{
94
+ botToken: string;
95
+ botName?: string;
96
+ }>;
97
+ /**
98
+ * Send a message via WeChat.
99
+ *
100
+ * @param content - Message text
101
+ * @param contextToken - Context token from the received message (maintains thread)
102
+ * @throws Error if not connected or API call fails
103
+ */
104
+ sendMessage(content: string, contextToken: string): Promise<void>;
105
+ /**
106
+ * Get the current connection state.
107
+ *
108
+ * @returns Connection status object
109
+ */
110
+ getStatus(): {
111
+ state: WeChatConnectionState;
112
+ botName: string | null;
113
+ connectedAt: string | null;
114
+ };
115
+ /**
116
+ * Check if the service is connected.
117
+ *
118
+ * @returns True if connected with a valid bot token
119
+ */
120
+ isConnected(): boolean;
121
+ /**
122
+ * Disconnect and stop message polling.
123
+ */
124
+ disconnect(): void;
125
+ /**
126
+ * Try to restore connection from persisted config.
127
+ *
128
+ * @returns True if config was loaded and connection restored
129
+ */
130
+ tryRestore(): Promise<boolean>;
131
+ /**
132
+ * Start long-polling for incoming messages.
133
+ */
134
+ private startMessagePolling;
135
+ /**
136
+ * Stop message polling.
137
+ */
138
+ private stopMessagePolling;
139
+ /**
140
+ * Long-poll for new messages from the iLink API.
141
+ * Automatically reschedules on completion or error.
142
+ */
143
+ private pollMessages;
144
+ /**
145
+ * Persist bot token to disk.
146
+ */
147
+ private persistConfig;
148
+ /**
149
+ * Load persisted config from disk.
150
+ *
151
+ * @returns Config or null if not found
152
+ */
153
+ private loadConfig;
154
+ /**
155
+ * Remove persisted config from disk.
156
+ */
157
+ removeConfig(): Promise<void>;
158
+ /**
159
+ * Build authorization headers for iLink API.
160
+ *
161
+ * @returns Headers with Bearer token and AuthorizationType
162
+ */
163
+ private authHeaders;
164
+ }
165
+ /**
166
+ * Get the WeChat service singleton.
167
+ *
168
+ * @returns WeChatService instance
169
+ */
170
+ export declare function getWeChatService(): WeChatService;
171
+ //# sourceMappingURL=wechat.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wechat/wechat.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAqCtC,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,gCAAgC;AAChC,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;AAM1F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAKP;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAW5B;;;;;;;;OAQG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IA0B1C;;;;;OAKG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA4DvF;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBvE;;;;OAIG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,qBAAqB,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAQjG;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,UAAU,IAAI,IAAI;IAUlB;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBpC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;OAGG;YACW,YAAY;IAqE1B;;OAEG;YACW,aAAa;IAiB3B;;;;OAIG;YACW,UAAU;IASxB;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAanC;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAOpB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD"}