crewly 1.4.69 → 1.4.71
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/dist/backend/backend/src/constants.d.ts +1 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +1 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +4 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
- package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts +17 -9
- package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts.map +1 -1
- package/dist/backend/backend/src/middleware/require-auth.middleware.js +60 -10
- package/dist/backend/backend/src/middleware/require-auth.middleware.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +6 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js +14 -2
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.d.ts +47 -0
- package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.js +69 -0
- package/dist/backend/backend/src/services/messaging/adapters/wechat-messenger.adapter.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/response-router.service.d.ts +21 -3
- package/dist/backend/backend/src/services/messaging/response-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/response-router.service.js +68 -5
- package/dist/backend/backend/src/services/messaging/response-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/wechat/wechat-bridge.service.d.ts +69 -0
- package/dist/backend/backend/src/services/wechat/wechat-bridge.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wechat/wechat-bridge.service.js +133 -0
- package/dist/backend/backend/src/services/wechat/wechat-bridge.service.js.map +1 -0
- package/dist/backend/backend/src/services/wechat/wechat.controller.d.ts +51 -0
- package/dist/backend/backend/src/services/wechat/wechat.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wechat/wechat.controller.js +104 -0
- package/dist/backend/backend/src/services/wechat/wechat.controller.js.map +1 -0
- package/dist/backend/backend/src/services/wechat/wechat.service.d.ts +171 -0
- package/dist/backend/backend/src/services/wechat/wechat.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wechat/wechat.service.js +411 -0
- package/dist/backend/backend/src/services/wechat/wechat.service.js.map +1 -0
- package/dist/cli/backend/src/constants.d.ts +1 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +1 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- 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;
|
|
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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Routes orchestrator responses back to the correct source.
|
|
5
5
|
* - Web chat: no-op (existing TerminalGateway -> ChatGateway -> WebSocket pipeline handles it)
|
|
6
|
-
* - Slack: resolves
|
|
6
|
+
* - Slack: resolves via slackResolve callback, or falls back to direct Slack API reply
|
|
7
7
|
*
|
|
8
8
|
* @module services/messaging/response-router
|
|
9
9
|
*/
|
|
@@ -38,13 +38,31 @@ export declare class ResponseRouterService {
|
|
|
38
38
|
*/
|
|
39
39
|
private routeToWebChat;
|
|
40
40
|
/**
|
|
41
|
-
* Route response to Slack
|
|
42
|
-
*
|
|
41
|
+
* Route response to Slack.
|
|
42
|
+
*
|
|
43
|
+
* First tries the slackResolve callback (blocking promise pattern).
|
|
44
|
+
* If no callback exists (fire-and-forget orchestrator path), falls back
|
|
45
|
+
* to sending directly via the Slack API using channelId/threadTs from
|
|
46
|
+
* sourceMetadata. This ensures orchestrator replies always reach Slack
|
|
47
|
+
* even when the fire-and-forget enqueue pattern is used.
|
|
43
48
|
*
|
|
44
49
|
* @param message - The completed QueuedMessage
|
|
45
50
|
* @param response - The response content
|
|
46
51
|
*/
|
|
47
52
|
private routeToSlack;
|
|
53
|
+
/**
|
|
54
|
+
* Send a reply directly to Slack using the Slack API.
|
|
55
|
+
*
|
|
56
|
+
* Used as a fallback when the fire-and-forget enqueue pattern
|
|
57
|
+
* doesn't include a slackResolve callback. Dynamically imports
|
|
58
|
+
* SlackService to avoid circular dependencies.
|
|
59
|
+
*
|
|
60
|
+
* @param messageId - Message ID for logging
|
|
61
|
+
* @param channelId - Slack channel to reply in
|
|
62
|
+
* @param text - Reply text
|
|
63
|
+
* @param threadTs - Optional thread timestamp for threaded reply
|
|
64
|
+
*/
|
|
65
|
+
private sendSlackDirectReply;
|
|
48
66
|
/**
|
|
49
67
|
* Route response to Google Chat by calling the googleChatResolve callback.
|
|
50
68
|
* This unblocks the promise that sends the reply back to the Chat thread.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-router.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/response-router.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEpE;;;;;;;;;GASG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAkB;;IAMhC;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA2B7D;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAQtB
|
|
1
|
+
{"version":3,"file":"response-router.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/response-router.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEpE;;;;;;;;;GASG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAkB;;IAMhC;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA2B7D;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,YAAY;IA2BpB;;;;;;;;;;;OAWG;YACW,oBAAoB;IA0BlC;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CA8BxD"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Routes orchestrator responses back to the correct source.
|
|
5
5
|
* - Web chat: no-op (existing TerminalGateway -> ChatGateway -> WebSocket pipeline handles it)
|
|
6
|
-
* - Slack: resolves
|
|
6
|
+
* - Slack: resolves via slackResolve callback, or falls back to direct Slack API reply
|
|
7
7
|
*
|
|
8
8
|
* @module services/messaging/response-router
|
|
9
9
|
*/
|
|
@@ -72,14 +72,77 @@ export class ResponseRouterService {
|
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
* Route response to Slack
|
|
76
|
-
*
|
|
75
|
+
* Route response to Slack.
|
|
76
|
+
*
|
|
77
|
+
* First tries the slackResolve callback (blocking promise pattern).
|
|
78
|
+
* If no callback exists (fire-and-forget orchestrator path), falls back
|
|
79
|
+
* to sending directly via the Slack API using channelId/threadTs from
|
|
80
|
+
* sourceMetadata. This ensures orchestrator replies always reach Slack
|
|
81
|
+
* even when the fire-and-forget enqueue pattern is used.
|
|
77
82
|
*
|
|
78
83
|
* @param message - The completed QueuedMessage
|
|
79
84
|
* @param response - The response content
|
|
80
85
|
*/
|
|
81
86
|
routeToSlack(message, response) {
|
|
82
|
-
|
|
87
|
+
const resolve = message.sourceMetadata?.['slackResolve'];
|
|
88
|
+
if (typeof resolve === 'function') {
|
|
89
|
+
this.resolveCallback(message, response, 'slackResolve', 'Slack');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Fallback: send directly via Slack API using channelId + threadTs
|
|
93
|
+
const channelId = message.sourceMetadata?.['channelId'];
|
|
94
|
+
const threadTs = message.sourceMetadata?.['threadTs'];
|
|
95
|
+
if (channelId) {
|
|
96
|
+
this.sendSlackDirectReply(message.id, channelId, response, threadTs).catch((err) => {
|
|
97
|
+
this.logger.error('Failed to send direct Slack reply fallback', {
|
|
98
|
+
messageId: message.id,
|
|
99
|
+
channelId,
|
|
100
|
+
error: formatError(err),
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.logger.warn('Slack message has no slackResolve callback and no channelId for fallback', {
|
|
106
|
+
messageId: message.id,
|
|
107
|
+
conversationId: message.conversationId,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Send a reply directly to Slack using the Slack API.
|
|
113
|
+
*
|
|
114
|
+
* Used as a fallback when the fire-and-forget enqueue pattern
|
|
115
|
+
* doesn't include a slackResolve callback. Dynamically imports
|
|
116
|
+
* SlackService to avoid circular dependencies.
|
|
117
|
+
*
|
|
118
|
+
* @param messageId - Message ID for logging
|
|
119
|
+
* @param channelId - Slack channel to reply in
|
|
120
|
+
* @param text - Reply text
|
|
121
|
+
* @param threadTs - Optional thread timestamp for threaded reply
|
|
122
|
+
*/
|
|
123
|
+
async sendSlackDirectReply(messageId, channelId, text, threadTs) {
|
|
124
|
+
try {
|
|
125
|
+
const { getSlackService } = await import('../slack/index.js');
|
|
126
|
+
const slackService = getSlackService();
|
|
127
|
+
if (!slackService?.isConnected()) {
|
|
128
|
+
this.logger.warn('Slack not connected, cannot send direct reply', { messageId });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
await slackService.sendMessage({ channelId, text, threadTs });
|
|
132
|
+
this.logger.info('Slack direct reply sent (fallback)', {
|
|
133
|
+
messageId,
|
|
134
|
+
channelId,
|
|
135
|
+
responseLength: text.length,
|
|
136
|
+
threaded: !!threadTs,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
this.logger.error('Slack direct reply failed', {
|
|
141
|
+
messageId,
|
|
142
|
+
channelId,
|
|
143
|
+
error: formatError(error),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
83
146
|
}
|
|
84
147
|
/**
|
|
85
148
|
* Route response to Google Chat by calling the googleChatResolve callback.
|
|
@@ -152,7 +215,7 @@ export class ResponseRouterService {
|
|
|
152
215
|
});
|
|
153
216
|
break;
|
|
154
217
|
case 'slack':
|
|
155
|
-
this.
|
|
218
|
+
this.routeToSlack(message, `Error: ${error}`);
|
|
156
219
|
break;
|
|
157
220
|
case 'google_chat':
|
|
158
221
|
this.resolveCallback(message, `Error: ${error}`, 'googleChatResolve', 'Google Chat');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-router.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/response-router.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAmB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;;;;;;;;GASG;AACH,MAAM,OAAO,qBAAqB;IACxB,MAAM,CAAkB;IAEhC;QACE,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACpF,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,OAAsB,EAAE,QAAgB;QACpD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,UAAU;gBACb,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAC1C,MAAM;YACR,KAAK,UAAU;gBACb,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACxC,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE;oBACxD,SAAS,EAAE,OAAO,CAAC,EAAE;iBACtB,CAAC,CAAC;gBACH,MAAM;YACR;gBACE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;oBACrD,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,cAAc,CAAC,OAAsB,EAAE,QAAgB;QAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4DAA4D,EAAE;YAC9E,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,cAAc,EAAE,QAAQ,CAAC,MAAM;SAChC,CAAC,CAAC;IACL,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"response-router.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/response-router.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|