wechaty-web-panel 1.6.112 → 1.6.113

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 (109) hide show
  1. package/dist/bot/chatgpt/index.js +235 -0
  2. package/dist/bot/coze/sdk/index.js +110 -0
  3. package/dist/bot/dify/sdk/index.js +461 -0
  4. package/dist/bot/dify/sdk/office.js +319 -0
  5. package/dist/bot/fastgpt/index.js +98 -0
  6. package/dist/bot/qanything/index.js +136 -0
  7. package/dist/botInstance/coze.js +167 -0
  8. package/dist/botInstance/cozev3.js +157 -0
  9. package/dist/botInstance/dify.js +160 -0
  10. package/dist/botInstance/fastgpt.js +130 -0
  11. package/dist/botInstance/gpt4v.js +95 -0
  12. package/dist/botInstance/officialOpenAi.js +186 -0
  13. package/dist/botInstance/qany.js +144 -0
  14. package/dist/botInstance/sdk/chatGPT4V.js +89 -0
  15. package/dist/botInstance/sdk/coze.js +200 -0
  16. package/dist/botInstance/sdk/difyClient.js +354 -0
  17. package/dist/botInstance/sdk/pTimeout.js +97 -0
  18. package/dist/botInstance/sdk/qanything.js +137 -0
  19. package/dist/botInstance/sdk/quick-lru.js +237 -0
  20. package/dist/common/hook.js +66 -0
  21. package/dist/common/index.js +513 -0
  22. package/dist/common/multiReply.js +158 -0
  23. package/dist/common/reply.js +23 -0
  24. package/dist/const/puppet-type.js +71 -0
  25. package/dist/db/aiDb.js +27 -0
  26. package/dist/db/aichatDb.js +84 -0
  27. package/dist/db/chatHistory.js +137 -0
  28. package/dist/db/configDb.js +97 -0
  29. package/dist/db/global.js +62 -0
  30. package/dist/db/gptConfig.js +85 -0
  31. package/dist/db/nedb.js +88 -0
  32. package/dist/db/puppetDb.js +58 -0
  33. package/dist/db/roomDb.js +83 -0
  34. package/dist/db/rssConfig.js +82 -0
  35. package/dist/db/rssHistory.js +88 -0
  36. package/dist/db/userDb.js +27 -0
  37. package/dist/handlers/on-callback-message.js +183 -0
  38. package/dist/handlers/on-error.js +5 -0
  39. package/dist/handlers/on-friend.js +62 -0
  40. package/dist/handlers/on-heartbeat.js +20 -0
  41. package/dist/handlers/on-login.js +58 -0
  42. package/dist/handlers/on-logout.js +17 -0
  43. package/dist/handlers/on-message.js +644 -0
  44. package/dist/handlers/on-ready.js +36 -0
  45. package/dist/handlers/on-record-message.js +56 -0
  46. package/dist/handlers/on-roomjoin.js +42 -0
  47. package/dist/handlers/on-roomleave.js +12 -0
  48. package/dist/handlers/on-roomtopic.js +16 -0
  49. package/dist/handlers/on-scan.js +64 -0
  50. package/dist/handlers/on-verifycode.js +42 -0
  51. package/dist/index.js +81 -69306
  52. package/dist/lib/contentCensor.js +23 -0
  53. package/dist/lib/index.js +562 -0
  54. package/dist/lib/oss.js +43 -0
  55. package/dist/lib/s3oss.js +33 -0
  56. package/dist/mcp/mcp-server.js +26 -0
  57. package/dist/mcp/src/config/database.js +51 -0
  58. package/dist/mcp/src/index.js +238 -0
  59. package/dist/mcp/src/mcp/schemas.js +178 -0
  60. package/dist/mcp/src/mcp/server.js +421 -0
  61. package/dist/mcp/src/mcp/streamable-server.js +690 -0
  62. package/dist/mcp/src/models/ChatMessage.js +151 -0
  63. package/dist/mcp/src/models/Friend.js +64 -0
  64. package/dist/mcp/src/models/Group.js +55 -0
  65. package/dist/mcp/src/models/GroupMember.js +67 -0
  66. package/dist/mcp/src/models/index.js +27 -0
  67. package/dist/mcp/src/scripts/migrate.js +21 -0
  68. package/dist/mcp/src/services/ChatDataService.js +284 -0
  69. package/dist/mcp/src/services/McpService.js +521 -0
  70. package/dist/mcp/src/services/McpTools.js +504 -0
  71. package/dist/mcp/streamable-examples.js +283 -0
  72. package/dist/mcp/streamable-server.js +79 -0
  73. package/dist/mcp/test-mcp.js +64 -0
  74. package/dist/mcp/test-streamable-server.js +86 -0
  75. package/dist/package-json.js +89 -0
  76. package/dist/proxy/aibotk.js +829 -0
  77. package/dist/proxy/api.js +431 -0
  78. package/dist/proxy/apib.js +587 -0
  79. package/dist/proxy/bot/chatgpt.js +38 -0
  80. package/dist/proxy/bot/coze.js +38 -0
  81. package/dist/proxy/bot/cozev3.js +38 -0
  82. package/dist/proxy/bot/dify.js +38 -0
  83. package/dist/proxy/bot/dispatch.js +81 -0
  84. package/dist/proxy/bot/fastgpt.js +27 -0
  85. package/dist/proxy/bot/qany.js +27 -0
  86. package/dist/proxy/config.js +14 -0
  87. package/dist/proxy/cozeAi.js +60 -0
  88. package/dist/proxy/cozeV3Ai.js +60 -0
  89. package/dist/proxy/difyAi.js +58 -0
  90. package/dist/proxy/fastgpt.js +55 -0
  91. package/dist/proxy/mqtt.js +275 -0
  92. package/dist/proxy/multimodal.js +122 -0
  93. package/dist/proxy/openAi.js +63 -0
  94. package/dist/proxy/outapi.js +62 -0
  95. package/dist/proxy/qAnyAi.js +57 -0
  96. package/dist/proxy/superagent.js +200 -0
  97. package/dist/proxy/tencent-open.js +255 -0
  98. package/dist/service/event-dispatch-service.js +309 -0
  99. package/dist/service/gpt4vService.js +45 -0
  100. package/dist/service/msg-filter-service.js +121 -0
  101. package/dist/service/msg-filters.js +645 -0
  102. package/dist/service/room-async-service.js +455 -0
  103. package/dist/task/index.js +535 -0
  104. package/dist/task/rss.js +174 -0
  105. package/package.json +2 -2
  106. package/src/package-json.js +2 -2
  107. package/tsconfig.json +3 -12
  108. package/dist/index.d.ts +0 -9
  109. package/tsconfig.cjs.json +0 -12
@@ -0,0 +1,200 @@
1
+ import superagent from 'superagent';
2
+ import { getFormatQuery } from '../lib/index.js';
3
+ import { getAibotConfig } from '../db/aiDb.js';
4
+ import { AIBOTK, TXHOST } from './config.js';
5
+ import { allConfig } from '../db/configDb.js';
6
+ import axios from 'axios';
7
+ const service = axios.create({
8
+ // 定义统一的请求头部
9
+ headers: {
10
+ 'Content-Type': 'application/json',
11
+ },
12
+ // 配置请求超时时间
13
+ timeout: 60000,
14
+ // 如果用的JSONP,可以配置此参数带上cookie凭证,如果是代理和CORS不用设置
15
+ withCredentials: false,
16
+ });
17
+ // 请求拦截
18
+ service.interceptors.request.use((config) => {
19
+ return config;
20
+ });
21
+ // 返回拦截
22
+ service.interceptors.response.use((response) => {
23
+ if (response.status === 200) {
24
+ // 获取接口返回结果
25
+ const res = response.data;
26
+ // code为0,直接把结果返回回去,这样前端代码就不用在获取一次data.
27
+ if (res.code === 200) {
28
+ if (Array.isArray(res.data)) {
29
+ return Promise.resolve(res.data);
30
+ }
31
+ else {
32
+ const result = [{ type: 1, content: '回调函数返回参数错误:' + JSON.stringify(res.data) }];
33
+ return Promise.resolve(result);
34
+ }
35
+ }
36
+ else {
37
+ const result = [{ type: 1, content: res.msg }];
38
+ return Promise.resolve(result);
39
+ }
40
+ }
41
+ console.log(`回调接口网络错误:${response.status}`);
42
+ const res = [{ type: 1, content: '' }];
43
+ return Promise.resolve(res);
44
+ }, (err) => {
45
+ console.log('回调接口网络错误:', err);
46
+ const res = [{ type: 1, content: '' }];
47
+ return Promise.resolve(res);
48
+ });
49
+ /**
50
+ * 封装get请求
51
+ * @param {*} url 地址
52
+ * @param {*} params 参数
53
+ * @param {*} contentType 发送请求数据类型
54
+ */
55
+ function get({ url, params, contentType = 'application/json', platform = 'tx', authorization = '', spider = false, timeout }) {
56
+ const time = timeout || 1000 * 100;
57
+ return new Promise((resolve, reject) => {
58
+ superagent
59
+ .get(url)
60
+ .timeout(time)
61
+ .query(params)
62
+ .set('Content-Type', contentType)
63
+ .set('Authorization', authorization)
64
+ .end((err, res) => {
65
+ if (err) {
66
+ console.log('请求出错', err);
67
+ reject(err);
68
+ }
69
+ else {
70
+ if (spider) {
71
+ // 如果是爬取内容,直接返回页面html
72
+ resolve(res.text);
73
+ }
74
+ else {
75
+ // 如果是非爬虫,返回格式化后的内容
76
+ res = res && res.text && JSON.parse(res.text) || {};
77
+ if (platform !== 'chuan') {
78
+ if ((res.code !== 200 && platform === 'tx') || (res.code !== 200 && platform === 'aibot') || (res.code !== 0 && platform === 'qi') || (res.code !== 100000 && platform === 'tl')) {
79
+ console.error(`接口${url}请求失败`, res.msg || res.text);
80
+ }
81
+ }
82
+ resolve(res);
83
+ }
84
+ }
85
+ });
86
+ });
87
+ }
88
+ /**
89
+ * 封装post请求
90
+ * @param {*} url 地址
91
+ * @param {*} params 参数
92
+ * @param {*} contentType 发送请求数据类型
93
+ * @param authorization
94
+ */
95
+ function post({ url, params, contentType = 'application/json', authorization = '', platform = 'tx', spider = false, skipCheck = false, timeout }) {
96
+ const time = timeout || 1000 * 100;
97
+ return new Promise((resolve, reject) => {
98
+ superagent
99
+ .post(url)
100
+ .timeout(time)
101
+ .send(params)
102
+ .set('Content-Type', contentType)
103
+ .set('Authorization', authorization)
104
+ .end((err, res) => {
105
+ if (err) {
106
+ console.log('请求出错', err);
107
+ reject(err);
108
+ }
109
+ else {
110
+ if (spider) {
111
+ // 如果是爬取内容,直接返回页面html
112
+ resolve(res.text);
113
+ }
114
+ else {
115
+ // 如果是非爬虫,返回格式化后的内容
116
+ try {
117
+ res = res && res.text && JSON.parse(res.text) || {};
118
+ }
119
+ catch (e) {
120
+ console.error(`接口请求失败${url}`, res.msg || res.text || res.error);
121
+ reject(res.text);
122
+ return;
123
+ }
124
+ if (platform !== 'chuan') {
125
+ if ((res.code !== 200 && platform === 'tx') || (res.code !== 200 && platform === 'aibot') || (res.code !== 100000 && platform === 'tl')) {
126
+ console.error(`接口请求失败${url}`, res.msg || res.text || res.error);
127
+ }
128
+ }
129
+ resolve(res);
130
+ }
131
+ }
132
+ });
133
+ });
134
+ }
135
+ function req(option) {
136
+ if (!option)
137
+ return;
138
+ if (option.method === 'POST') {
139
+ return post(option);
140
+ }
141
+ else {
142
+ return get(option);
143
+ }
144
+ }
145
+ async function txReq(option) {
146
+ const config = await allConfig();
147
+ if (!option)
148
+ return;
149
+ const params = {
150
+ key: config.txApiKey,
151
+ ...option.params,
152
+ };
153
+ if (option.method === 'POST') {
154
+ return post({ url: TXHOST + option.url, params, contentType: option.contentType, timeout: option.timeout || 1000 * 100 });
155
+ }
156
+ else {
157
+ return get({ url: TXHOST + option.url, params, contentType: option.contentType, timeout: option.timeout || 1000 * 100 });
158
+ }
159
+ }
160
+ async function aiBotReq(option) {
161
+ const env = await getAibotConfig();
162
+ const { apiKey, apiSecret } = env;
163
+ if (!option)
164
+ return;
165
+ if (!apiKey || !apiSecret) {
166
+ console.warn('未设置apikey或apiSecret,请登录https://wechat.aibotk.com 获取后重试');
167
+ return;
168
+ }
169
+ let params = getFormatQuery(apiKey, apiSecret, option.params);
170
+ if (option.method === 'POST') {
171
+ return post({ url: AIBOTK + option.url, params, contentType: 'application/json;charset=utf-8', platform: option.platform || 'aibot', timeout: option?.timeout || 100 * 1000 });
172
+ }
173
+ else {
174
+ return get({ url: AIBOTK + option.url, params, contentType: option.contentType, platform: option.platform || 'aibot', timeout: option?.timeout || 100 * 1000 });
175
+ }
176
+ }
177
+ async function callbackAibotApi(url, data, timeout = 60) {
178
+ const env = await getAibotConfig();
179
+ const { apiKey, apiSecret } = env;
180
+ if (!apiKey || !apiSecret) {
181
+ console.warn('未设置apikey或apiSecret,请登录https://wechat.aibotk.com 获取后重试');
182
+ return [];
183
+ }
184
+ data = getFormatQuery(apiKey, apiSecret, data);
185
+ let res = await service.post(url, data, { timeout: timeout * 1000 });
186
+ return res;
187
+ }
188
+ export { req };
189
+ export { txReq };
190
+ export { aiBotReq };
191
+ export { service };
192
+ export { callbackAibotApi };
193
+ export default {
194
+ req,
195
+ txReq,
196
+ aiBotReq,
197
+ service,
198
+ callbackAibotApi,
199
+ };
200
+ //# sourceMappingURL=superagent.js.map
@@ -0,0 +1,255 @@
1
+ import jwt from "jsonwebtoken";
2
+ import { allConfig } from "../db/configDb.js";
3
+ import axios from "axios";
4
+ import { getPuppetEol, isNotWebPuppet } from "../const/puppet-type.js";
5
+ async function getSignature(id, encodingAESKey) {
6
+ const token = jwt.sign({
7
+ userid: id
8
+ }, encodingAESKey, { algorithm: "HS256" });
9
+ return token;
10
+ }
11
+ function checkType(answer) {
12
+ var i = "";
13
+ i = "[object Object]" === Object.prototype.toString.call(answer) ? JSON.stringify(answer) : answer;
14
+ var s = "text";
15
+ return (/{\s*"miniprogrampage"\s*:/.test(i)
16
+ ? (s = "miniprogrampage")
17
+ : /{\s*"image"\s*:/.test(i)
18
+ ? (s = "image")
19
+ : /{\s*"file"\s*:/.test(i)
20
+ ? (s = "file")
21
+ : /{\s*"mpnews"\s*:/.test(i)
22
+ ? (s = "mpnews")
23
+ : /{\s*"news"\s*:/.test(i)
24
+ ? (s = "news")
25
+ : /{\s*"video"\s*:/.test(i)
26
+ ? (s = "video")
27
+ : /{\s*"voice"\s*:/.test(i)
28
+ ? (s = "voice")
29
+ : /{\s*"callback"\s*:/.test(i)
30
+ ? (s = "callback")
31
+ : /weather_ans_detail/.test(i)
32
+ ? (s = "weather")
33
+ : /{\s*"json"\s*:/.test(i)
34
+ ? (s = "json")
35
+ : /^\[({.*:.*})*\]$/.test(i) && (s = "nndialog"),
36
+ s);
37
+ }
38
+ /**
39
+ * 判断是不是多个回复
40
+ * @param answer
41
+ * @returns {boolean}
42
+ */
43
+ function isMultiple(answer) {
44
+ return /{\s*"multimsg"\s*:/.test(answer);
45
+ }
46
+ /**
47
+ * 对多重回复的处理
48
+ * @param answer
49
+ */
50
+ function getMultiList(answer) {
51
+ const multiList = JSON.parse(answer).multimsg;
52
+ const res = multiList.map(function (item, index) {
53
+ if ("[object Object]" === Object.prototype.toString.call(item)) {
54
+ return JSON.stringify(item);
55
+ }
56
+ else {
57
+ return item;
58
+ }
59
+ });
60
+ return res;
61
+ }
62
+ /**
63
+ * 格式化开放平台回复内容
64
+ * @param answer
65
+ * @param options
66
+ * @param userInfo
67
+ * @returns {*[]}
68
+ */
69
+ async function getFormatReply(answer, options = [], userInfo) {
70
+ const eol = await getPuppetEol();
71
+ const isNotWeb = await isNotWebPuppet();
72
+ const answerType = checkType(answer);
73
+ if (answerType !== "text") {
74
+ answer = JSON.parse(answer);
75
+ }
76
+ let replys = [];
77
+ let reply = {};
78
+ switch (answerType) {
79
+ case "text":
80
+ reply = {
81
+ type: 1,
82
+ content: answer
83
+ };
84
+ if (options && options.length) {
85
+ options.forEach((item) => {
86
+ reply.content = reply.content + `(请输入完整的文字和序号,可以拷贝)${eol}` + item.title;
87
+ });
88
+ }
89
+ replys = [reply];
90
+ break;
91
+ case "image":
92
+ if (Array.isArray(answer.image)) {
93
+ replys = answer.image.map((item) => {
94
+ return {
95
+ type: 2,
96
+ url: item.image.url
97
+ };
98
+ });
99
+ break;
100
+ }
101
+ else {
102
+ replys = [{ type: 2, url: answer.image.url }];
103
+ break;
104
+ }
105
+ case "video":
106
+ if (answer.video && (answer.video.url || answer.video.cover_url)) {
107
+ replys = [{ type: 2, url: answer.video.url ? answer.video.url : answer.video.cover_url }];
108
+ break;
109
+ }
110
+ break;
111
+ case "news":
112
+ if (!isNotWeb) {
113
+ replys = [
114
+ {
115
+ type: 1,
116
+ content: `【标题】${answer.news.articles[0].title}${eol}【描述】${answer.news.articles[0].description}${eol}【访问地址】${answer.news.articles[0].url}${eol} 【缩略图】正在路上...`
117
+ },
118
+ { type: 2, url: answer.news.articles[0].picurl }
119
+ ];
120
+ }
121
+ else {
122
+ replys = [{
123
+ type: 4,
124
+ url: answer.news.articles[0].url,
125
+ title: answer.news.articles[0].title,
126
+ thumbUrl: answer.news.articles[0].picurl,
127
+ description: answer.news.articles[0].description
128
+ }];
129
+ }
130
+ break;
131
+ case "mpnews":
132
+ if (!isNotWeb) {
133
+ replys = [
134
+ { type: 1, content: `【标题】${answer.mpnews.title}${eol}【内容】${answer.mpnews.digest}${eol}【缩略图】正在路上...` },
135
+ { type: 2, url: answer.mpnews.imgurl }
136
+ ];
137
+ }
138
+ else {
139
+ replys = [{
140
+ type: 4,
141
+ url: answer.mpnews.imgurl,
142
+ title: answer.mpnews.title,
143
+ thumbUrl: answer.mpnews.imgurl,
144
+ description: answer.mpnews.digest
145
+ }];
146
+ }
147
+ break;
148
+ case "voice":
149
+ if (answer.voice && answer.voice.url) {
150
+ replys = [{ type: 2, url: answer.voice.url }];
151
+ break;
152
+ }
153
+ break;
154
+ case "json":
155
+ if (answer.json) {
156
+ replys = [{ type: 1, content: JSON.stringify(answer.json) }];
157
+ break;
158
+ }
159
+ break;
160
+ case "miniprogrampage":
161
+ if (!isNotWeb) {
162
+ replys = [{ type: 1, content: "收到了一个小程序,但是小秘书还没学会展示😭,等等我回去再修炼五百年💪" }];
163
+ }
164
+ else {
165
+ replys = [{
166
+ type: 5,
167
+ appid: answer.miniprogrampage.appid,
168
+ title: answer.miniprogrampage.title,
169
+ pagePath: answer.miniprogrampage.pagepath,
170
+ description: answer.miniprogrampage.title,
171
+ thumbUrl: answer.miniprogrampage.thumb_url,
172
+ thumbKey: undefined,
173
+ username: answer.miniprogrampage.appid
174
+ }];
175
+ }
176
+ break;
177
+ default:
178
+ break;
179
+ }
180
+ return replys;
181
+ }
182
+ async function getTencentOpenReply({ msg, id, userInfo }) {
183
+ const config = await allConfig();
184
+ const isNotWeb = await isNotWebPuppet();
185
+ const eol = await getPuppetEol();
186
+ if (!config.tencentAESKey || !config.tencentToken) {
187
+ console.log("请到智能微秘书平台配置AESKey 和token 参数方可使用");
188
+ return [{ type: 1, content: "请到平台配置AESKey 和token 参数方可使用" }];
189
+ }
190
+ try {
191
+ const signature = await getSignature(id, config.tencentAESKey);
192
+ const data = {
193
+ signature,
194
+ query: msg
195
+ };
196
+ const res = await axios.post(`https://openai.weixin.qq.com/openapi/aibot/${config.tencentToken}`, data, {});
197
+ const resData = res.data;
198
+ if (!resData.errcode) {
199
+ let answer = resData.answer; // 存放回答
200
+ if (resData.answer_type === "music") {
201
+ // web 端协议以文字和图片的形式发送
202
+ if (isNotWeb) {
203
+ const res = JSON.parse(resData.answer);
204
+ const music = res.news.articles[0];
205
+ const musicContent = `【歌名】:《${music && music.title}》${eol}【听歌地址】:${music && music.url}`;
206
+ const musicPic = music && music.picurl;
207
+ return [
208
+ {
209
+ type: 1,
210
+ content: musicContent
211
+ },
212
+ {
213
+ type: 2,
214
+ url: musicPic
215
+ }
216
+ ];
217
+ }
218
+ else {
219
+ // 其他协议可以发链接的用H5卡片发送
220
+ const music = resData.msg[0];
221
+ return [
222
+ { type: 4, url: music.url, title: music.title, thumbUrl: music.picurl, description: music.description }
223
+ ];
224
+ }
225
+ }
226
+ else {
227
+ if (isMultiple(answer)) {
228
+ const multiList = getMultiList(answer);
229
+ const replys = [];
230
+ for (let item of multiList) {
231
+ item = item.replace(/<\/?.+?\/?>/g, "");
232
+ const reply = await getFormatReply(item, resData.options || [], userInfo, config.puppetType);
233
+ replys.push(...reply);
234
+ }
235
+ return replys;
236
+ }
237
+ else {
238
+ const replys = getFormatReply(answer, resData.options, userInfo, config.puppetType);
239
+ return replys;
240
+ }
241
+ }
242
+ }
243
+ else {
244
+ console.log("微信开放对话平台报错:", resData.errcode + resData.errmsg);
245
+ }
246
+ }
247
+ catch (e) {
248
+ console.log("error", e);
249
+ }
250
+ }
251
+ export { getTencentOpenReply };
252
+ export default {
253
+ getTencentOpenReply
254
+ };
255
+ //# sourceMappingURL=tencent-open.js.map