feat: v1.1.4
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
.prettierignore
|
||||||
|
.prettierrc.js
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
.env
|
6
.prettierignore
Normal file
6
.prettierignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ignore artifacts:
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Ignore all HTML files:
|
||||||
|
*.html
|
26
.prettierrc.js
Normal file
26
.prettierrc.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//此处的规则供参考,其中多半其实都是默认值,可以根据个人习惯改写
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 80, //单行长度
|
||||||
|
tabWidth: 2, //缩进长度
|
||||||
|
useTabs: false, //使用空格代替tab缩进
|
||||||
|
semi: true, //句末使用分号
|
||||||
|
singleQuote: true, //使用单引号
|
||||||
|
quoteProps: 'as-needed', //仅在必需时为对象的key添加引号
|
||||||
|
jsxSingleQuote: true, // jsx中使用单引号
|
||||||
|
trailingComma: 'all', //多行时尽可能打印尾随逗号
|
||||||
|
bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar }
|
||||||
|
jsxBracketSameLine: true, //多属性html标签的‘>’折行放置
|
||||||
|
arrowParens: 'always', //单参数箭头函数参数周围使用圆括号-eg: (x) => x
|
||||||
|
requirePragma: false, //无需顶部注释即可格式化
|
||||||
|
insertPragma: false, //在已被preitter格式化的文件顶部加上标注
|
||||||
|
proseWrap: 'preserve', //不知道怎么翻译
|
||||||
|
htmlWhitespaceSensitivity: 'ignore', //对HTML全局空白不敏感
|
||||||
|
vueIndentScriptAndStyle: false, //不对vue中的script及style标签缩进
|
||||||
|
endOfLine: 'lf', //结束行形式
|
||||||
|
embeddedLanguageFormatting: 'auto', //对引用代码进行格式化
|
||||||
|
};
|
||||||
|
|
||||||
|
// 作者:星始流年
|
||||||
|
// 链接:https://juejin.cn/post/6938687606687432740
|
||||||
|
// 来源:稀土掘金
|
||||||
|
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM node:18-bullseye as dep-builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD [ "node", "app.js" ]
|
54
app.js
Normal file
54
app.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { join } = require('path');
|
||||||
|
const CreateBot = require('./bot');
|
||||||
|
const CreateWebhookServer = require('./http');
|
||||||
|
const logger = require('./utils/logger');
|
||||||
|
|
||||||
|
let retryCount = 0;
|
||||||
|
|
||||||
|
(async function start(port) {
|
||||||
|
if (retryCount >= 5) {
|
||||||
|
logger.warning('重试次数已达上限,请联系管理员重新启动本服务');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger('start server!!');
|
||||||
|
const bot = new CreateBot();
|
||||||
|
|
||||||
|
logger('bot 连接中...');
|
||||||
|
await bot
|
||||||
|
.open({
|
||||||
|
baseUrl: process.env.MIRAI_HTTP_API_HOST,
|
||||||
|
verifyKey: process.env.MIRAI_HTTP_API_VERIFY_KEY,
|
||||||
|
qq: process.env.QQ,
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
retryCount++;
|
||||||
|
logger.error(`bot 连接失败,${e}。正在重试, 重试次数 ${retryCount}`);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
start();
|
||||||
|
}, 5000);
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
logger('bot 连接成功!!');
|
||||||
|
|
||||||
|
logger('开启 webhook 服务器');
|
||||||
|
const webhook = new CreateWebhookServer();
|
||||||
|
|
||||||
|
logger('开始引入handler函数');
|
||||||
|
const files = fs.readdirSync('./handlers');
|
||||||
|
const handlers = files
|
||||||
|
.filter((it) => /\.js$/.test(it))
|
||||||
|
.map((it) => {
|
||||||
|
let fPath = join(__dirname, './handlers', it);
|
||||||
|
return {
|
||||||
|
event: it.split('.').slice(0, -1).join('.'),
|
||||||
|
handler: require(fPath).bind(this, bot),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
webhook.registerHanlder(handlers);
|
||||||
|
|
||||||
|
webhook.startListen(port);
|
||||||
|
logger(`开始监听端口: ${port}`);
|
||||||
|
})(process.env.WEB_HOOK_PORT);
|
56
bot/index.js
Normal file
56
bot/index.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const { Bot } = require('mirai-js');
|
||||||
|
const Queue = require('../utils/queue');
|
||||||
|
const logger = require('../utils/logger');
|
||||||
|
|
||||||
|
class CreateBot {
|
||||||
|
constructor() {
|
||||||
|
this.bot = new Bot();
|
||||||
|
this.queue = new Queue();
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async open(config) {
|
||||||
|
logger(`开始连接 mirai: host: ${config.baseUrl}, qq: ${config.qq}`);
|
||||||
|
await this.bot.open({
|
||||||
|
baseUrl: config.baseUrl,
|
||||||
|
verifyKey: config.verifyKey,
|
||||||
|
qq: config.qq,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendMessageToFriend(qq, message) {
|
||||||
|
logger(`发送好友[${qq}]消息进入消息队列`);
|
||||||
|
return this.queue
|
||||||
|
.addMethod(this.bot.sendMessage.bind(this.bot, { friend: qq, message }))
|
||||||
|
.then(
|
||||||
|
(res) => {
|
||||||
|
logger(`发送好友[${qq}]消息成功 ${res}`);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
logger.warning(`发送好友[${qq}]消息失败,错误信息${e}`);
|
||||||
|
return Promise.reject(e);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendMessageToGroup(groupId, message) {
|
||||||
|
logger(`发送群[${groupId}]消息进入消息队列`);
|
||||||
|
return this.queue
|
||||||
|
.addMethod(
|
||||||
|
this.bot.sendMessage.bind(this.bot, { group: groupId, message }),
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(res) => {
|
||||||
|
logger(`发送群[${groupId}]消息成功 ${res}`);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
logger.warning(`发送群[${groupId}]消息失败,错误信息${e}`);
|
||||||
|
return Promise.reject(e);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CreateBot;
|
10
config/index.js
Normal file
10
config/index.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
defaultSubs: {
|
||||||
|
groups: process.env.DEFAULT_SUB_GROUPS
|
||||||
|
? process.env.DEFAULT_SUB_GROUPS.split(',')
|
||||||
|
: [],
|
||||||
|
users: process.env.DEFAULT_SUB_USERS
|
||||||
|
? process.env.DEFAULT_SUB_USERS.split(',')
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
};
|
64
handlers/sendForwardMessage.js
Normal file
64
handlers/sendForwardMessage.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
const { Message } = require('mirai-js');
|
||||||
|
const { defaultSubs } = require('../config');
|
||||||
|
const logger = require('../utils/logger');
|
||||||
|
|
||||||
|
module.exports = function sendForwardMessage(bot, data) {
|
||||||
|
logger('开始执行handler: sendForwardMessage');
|
||||||
|
const { from, messages, subs } = data;
|
||||||
|
const subscriptions = subs || defaultSubs;
|
||||||
|
const { groups, users } = subscriptions;
|
||||||
|
|
||||||
|
// 创建转发信息
|
||||||
|
const forwardMsgContent = Message.createForwardMessage();
|
||||||
|
for (let i = 0; i < messages.length; i++) {
|
||||||
|
const { message, imgUrls, originUrl } = messages[i];
|
||||||
|
const msgContent = new Message();
|
||||||
|
// 依次添加文本消息
|
||||||
|
if (message) {
|
||||||
|
Array.isArray(message)
|
||||||
|
? message.forEach((message) => msgContent.addText(`${message}\n`))
|
||||||
|
: msgContent.addText(`${message}\n`);
|
||||||
|
}
|
||||||
|
// 添加图片消息
|
||||||
|
if (imgUrls) {
|
||||||
|
Array.isArray(imgUrls)
|
||||||
|
? imgUrls
|
||||||
|
.slice(0, process.env.IMG_NUMBER_IN_ONE_MESSAGE || 1)
|
||||||
|
.forEach((url) => msgContent.addImageUrl(url))
|
||||||
|
: msgContent.addImageUrl(imgUrls);
|
||||||
|
}
|
||||||
|
// 添加来源地址
|
||||||
|
if (originUrl) {
|
||||||
|
msgContent.addText(`\n点击查看详情:${originUrl}`);
|
||||||
|
}
|
||||||
|
forwardMsgContent.addForwardNode({
|
||||||
|
senderId: process.env.QQ,
|
||||||
|
time: 0,
|
||||||
|
senderName: process.env.FORWARD_SENDER_NAME || '莉娜·模儿',
|
||||||
|
messageChain: msgContent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.isArray(groups) &&
|
||||||
|
groups.forEach((groupId) => {
|
||||||
|
// 添加消息来源
|
||||||
|
if (from) {
|
||||||
|
bot.sendMessageToGroup(
|
||||||
|
groupId,
|
||||||
|
new Message().addText(`${from}更新啦!快来看吧。`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
bot.sendMessageToGroup(groupId, forwardMsgContent);
|
||||||
|
});
|
||||||
|
Array.isArray(users) &&
|
||||||
|
users.forEach((qq) => {
|
||||||
|
// 添加消息来源
|
||||||
|
if (from) {
|
||||||
|
bot.sendMessageToFriend(
|
||||||
|
qq,
|
||||||
|
new Message().addText(`${from}更新啦!快来看吧。`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
bot.sendMessageToFriend(qq, forwardMsgContent);
|
||||||
|
});
|
||||||
|
};
|
22
handlers/sendMessage.js
Normal file
22
handlers/sendMessage.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const { Message } = require('mirai-js');
|
||||||
|
const { defaultSubs } = require('../config');
|
||||||
|
const logger = require('../utils/logger');
|
||||||
|
|
||||||
|
// 方法已废弃
|
||||||
|
module.exports = function sendMessage(bot, data) {
|
||||||
|
logger('开始执行handler: sendMessage');
|
||||||
|
const { message, imgUrl } = data;
|
||||||
|
const subscriptions = defaultSubs;
|
||||||
|
const { groups, users } = subscriptions;
|
||||||
|
const msg = new Message().addText(message);
|
||||||
|
if (imgUrl) {
|
||||||
|
msg.addImageUrl(imgUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.forEach((groupId) => {
|
||||||
|
bot.sendMessageToGroup(groupId, msg);
|
||||||
|
});
|
||||||
|
users.forEach((qq) => {
|
||||||
|
bot.sendMessageToFriend(qq, msg);
|
||||||
|
});
|
||||||
|
};
|
49
handlers/sendMessage2.js
Normal file
49
handlers/sendMessage2.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
const { Message } = require('mirai-js');
|
||||||
|
const logger = require('../utils/logger');
|
||||||
|
|
||||||
|
module.exports = function sendMessage2(bot, data) {
|
||||||
|
logger('开始执行handler: sendMessage2');
|
||||||
|
const { from, messages, imgUrls, subs, originUrl, at } = data;
|
||||||
|
const subscriptions = subs || defaultSubs;
|
||||||
|
const { groups, users } = subscriptions;
|
||||||
|
const msgContent = new Message();
|
||||||
|
// 添加@信息
|
||||||
|
if (at) {
|
||||||
|
if (at === 'all') {
|
||||||
|
msgContent.addAtAll();
|
||||||
|
} else if (Array.isArray(at)) {
|
||||||
|
at.forEach((qq) => msgContent.addAt(qq));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 添加消息来源
|
||||||
|
if (from) {
|
||||||
|
msgContent.addText(`${from}\n`);
|
||||||
|
}
|
||||||
|
// 依次添加文本消息
|
||||||
|
if (messages) {
|
||||||
|
Array.isArray(messages)
|
||||||
|
? messages.forEach((message) => msgContent.addText(`${message}\n`))
|
||||||
|
: msgContent.addText(messages);
|
||||||
|
}
|
||||||
|
// 添加图片消息
|
||||||
|
if (imgUrls) {
|
||||||
|
Array.isArray(imgUrls)
|
||||||
|
? imgUrls
|
||||||
|
.slice(0, process.env.IMG_NUMBER_IN_ONE_MESSAGE || 1)
|
||||||
|
.forEach((url) => msgContent.addImageUrl(url))
|
||||||
|
: msgContent.addImageUrl(imgUrls);
|
||||||
|
}
|
||||||
|
// 添加来源地址
|
||||||
|
if (originUrl) {
|
||||||
|
msgContent.addText(`点击查看详情:${originUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.isArray(groups) &&
|
||||||
|
groups.forEach((groupId) => {
|
||||||
|
bot.sendMessageToGroup(groupId, msgContent);
|
||||||
|
});
|
||||||
|
Array.isArray(users) &&
|
||||||
|
users.forEach((qq) => {
|
||||||
|
bot.sendMessageToFriend(qq, msgContent);
|
||||||
|
});
|
||||||
|
};
|
60
http/index.js
Normal file
60
http/index.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const http = require('http');
|
||||||
|
const logger = require('../utils/logger');
|
||||||
|
|
||||||
|
class CreateWebhookServer {
|
||||||
|
constructor() {
|
||||||
|
this.http = null;
|
||||||
|
this.handlers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
startListen(port) {
|
||||||
|
this.http = http
|
||||||
|
.createServer((request, response) => {
|
||||||
|
const { url, method } = request;
|
||||||
|
logger(`监听到请求:${url}, 方法: ${method}`);
|
||||||
|
if (method.toLowerCase() !== 'post') return;
|
||||||
|
let body = '';
|
||||||
|
request
|
||||||
|
.on('error', (err) => {
|
||||||
|
console.error(err);
|
||||||
|
})
|
||||||
|
.on('data', (chunk) => {
|
||||||
|
body += chunk;
|
||||||
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
try {
|
||||||
|
const jsonData = JSON.parse(body);
|
||||||
|
Promise.all(
|
||||||
|
this.handlers.map((val) =>
|
||||||
|
jsonData.event === val.event
|
||||||
|
? val.handler(jsonData)
|
||||||
|
: Promise.resolve(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||||
|
response.write('Hello World');
|
||||||
|
response.end();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
response.writeHead(405, { 'Content-Type': 'text/plain' });
|
||||||
|
response.write(e);
|
||||||
|
response.end();
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
response.writeHead(405, { 'Content-Type': 'text/plain' });
|
||||||
|
response.write(e);
|
||||||
|
response.end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.listen(port || 8080);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerHanlder(handlers) {
|
||||||
|
logger(`${handlers.map((item) => item.event).join('、')}函数已引入`);
|
||||||
|
this.handlers.push(...handlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CreateWebhookServer;
|
149
package-lock.json
generated
Normal file
149
package-lock.json
generated
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
{
|
||||||
|
"name": "mirai-middle-server",
|
||||||
|
"version": "1.1.4",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "mirai-middle-server",
|
||||||
|
"version": "1.1.4",
|
||||||
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.7",
|
||||||
|
"mirai-js": "^2.8.11"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"dotenv": "^16.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "0.24.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||||
|
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.14.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
|
||||||
|
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||||
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.1.tgz",
|
||||||
|
"integrity": "sha512-UGmzIqXU/4b6Vb3R1Vrfd/4vGgVlB+mO+vEixOdfRhLeppkyW2BMhuK7TL8d0el+q9c4lW9qK2wZYhNLFhXYLA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||||
|
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mirai-js": {
|
||||||
|
"version": "2.8.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/mirai-js/-/mirai-js-2.8.11.tgz",
|
||||||
|
"integrity": "sha512-oon2wxi3EEFyGG45ss/Zhx24wv+6WcFQJ3Hx0MAQFj8dZTrf+v39Nm4+KCvjDAllogPJmRVmF21laCh/ISdLmw==",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.24.0",
|
||||||
|
"form-data": "^3.0.1",
|
||||||
|
"ws": "^8.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||||
|
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "mirai-middle-server",
|
||||||
|
"version": "1.1.4",
|
||||||
|
"description": "使用miraijs开发,用于连接kuginn等外部服务与mirai通信的中转服务器",
|
||||||
|
"author": "mol",
|
||||||
|
"main": "app.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node start.js",
|
||||||
|
"start": "node app.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.7",
|
||||||
|
"mirai-js": "^2.8.11"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"dotenv": "^16.1.1"
|
||||||
|
}
|
||||||
|
}
|
4
start.js
Normal file
4
start.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
const dotenv = require('dotenv');
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
require('./app');
|
25
utils/logger.js
Normal file
25
utils/logger.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const dayjs = require('dayjs');
|
||||||
|
|
||||||
|
function info(message) {
|
||||||
|
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【消息】${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function warning(message) {
|
||||||
|
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【警告】${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(message) {
|
||||||
|
console.log(`${dayjs().format('YYYY-MM-DD hh:mm:ss')}【错误】${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logger(message) {
|
||||||
|
info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.prototype.warning = warning;
|
||||||
|
|
||||||
|
logger.prototype.info = info;
|
||||||
|
|
||||||
|
logger.prototype.error = error;
|
||||||
|
|
||||||
|
module.exports = logger;
|
34
utils/queue.js
Normal file
34
utils/queue.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module.exports = class Queue {
|
||||||
|
constructor() {
|
||||||
|
this.queue = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
addMethod(method) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.queue.push({ method, resolve, reject });
|
||||||
|
|
||||||
|
if (this.queue.length === 1) {
|
||||||
|
this.executeNext();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async executeNext() {
|
||||||
|
const { method, resolve, reject } = this.queue[0];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await method();
|
||||||
|
resolve(result);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.queue.shift();
|
||||||
|
|
||||||
|
if (this.queue.length > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.executeNext();
|
||||||
|
}, Math.random() * 1000 + 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user