From dd25518d94d5d632145c1ccdf9b9527dfa456f75 Mon Sep 17 00:00:00 2001 From: smallfawn <101914820+smallfawn@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:30:39 +0800 Subject: [PATCH] Delete Tools directory --- Tools/env.js | 187 ------ Tools/sendNotify.js | 1542 ------------------------------------------- 2 files changed, 1729 deletions(-) delete mode 100644 Tools/env.js delete mode 100644 Tools/sendNotify.js diff --git a/Tools/env.js b/Tools/env.js deleted file mode 100644 index 06c67d9..0000000 --- a/Tools/env.js +++ /dev/null @@ -1,187 +0,0 @@ -// prettier-ignore -function Env(t, s) { - return new (class { - constructor(t, s) { - this.userIdx = 1; - this.userList = []; - this.userCount = 0; - this.name = t; - this.notifyStr = []; - this.logSeparator = "\n"; - this.startTime = new Date().getTime(); - Object.assign(this, s); - this.log(`\ud83d\udd14${this.name},\u5f00\u59cb!`); - this.bucket = this.bucket || '' - this.fs = require("fs"); - if (this.isNode() && this.bucket) { - try { - if (!this.fs.existsSync(this.bucket)) { - this.fs.writeFileSync(this.bucket, JSON.stringify({}, null, 2)); - this.log(`📁 已创建 bucket 文件: ${this.bucket}`); - } - } catch (e) { - this.log("❌ 初始化 bucket 失败: " + e.message); - } - } - } - async get(key, def = null) { - if (!this.isNode()) return def; - try { - const data = await this.fs.promises.readFile(this.bucket, "utf-8"); - const json = JSON.parse(data); - return json.hasOwnProperty(key) ? json[key] : def; - } catch (e) { - this.log("❌ 读取bucket失败: " + e.message); - return def; - } - } - async set(key, value) { - if (!this.isNode()) return; - try { - const data = await this.fs.promises.readFile(this.bucket, "utf-8"); - const json = JSON.parse(data); - json[key] = value; - await this.fs.promises.writeFile(this.bucket, JSON.stringify(json, null, 2)); - } catch (e) { - this.log("❌ 写入bucket失败: " + e.message); - } - } - checkEnv(ckName) { - const envSplitor = ["&", "\n"]; - let userCookie = (this.isNode() ? process.env[ckName] : "") || ""; - this.userList = userCookie.split(envSplitor.find((o) => userCookie.includes(o)) || "&").filter((n) => n); - this.userCount = this.userList.length; - this.log(`共找到${this.userCount}个账号`); - } - toStr(v) { - if (v instanceof Error) return v.stack || v.message; - if (v && typeof v == "object") try { return JSON.stringify(v) } catch { return "[Complex Object]" } - return String(v); - } - async sendMsg() { - this.log("==============📣Center 通知📣==============") - let message = this.notifyStr.join(this.logSeparator); - if (this.isNode()) { - try { - const { sendNotify } = require("./sendNotify.js") - await sendNotify(this.name, message); - } catch (e) { - console.error(e.code === "MODULE_NOT_FOUND" ? "发送通知失败: 未找到 sendNotify.js 模块" : `发送通知失败: sendNotify.js 内部错误 (${e.message})`); - } - - } - } - isNode() { - return "undefined" != typeof module && !!module.exports; - } - jsonToStr(obj, c = '&', encodeUrl = false) { - let ret = [] - for (let keys of Object.keys(obj).sort()) { - let v = obj[keys] - if (v && encodeUrl) v = encodeURIComponent(v) - ret.push(keys + '=' + v) - } - return ret.join(c); - } - getURLParams(url) { - try { return Object.fromEntries(new URL(url, "http://localhost").searchParams) } catch { return {} } - } - isJSONString(str) { - try { - return JSON.parse(str) && typeof JSON.parse(str) === "object"; - } catch (e) { - return false; - } - } - isJson(obj) { - var isjson = - typeof obj == "object" && - Object.prototype.toString.call(obj).toLowerCase() == - "[object object]" && - !obj.length; - return isjson; - } - - randomNumber(length) { - const characters = "0123456789"; - return Array.from( - { length }, - () => characters[Math.floor(Math.random() * characters.length)] - ).join(""); - } - randomString(length) { - const characters = "abcdefghijklmnopqrstuvwxyz0123456789"; - return Array.from( - { length }, - () => characters[Math.floor(Math.random() * characters.length)] - ).join(""); - } - uuid() { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( - /[xy]/g, - function (c) { - var r = (Math.random() * 16) | 0, - v = c == "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - } - ); - } - time(t) { - let s = { - "M+": new Date().getMonth() + 1, - "d+": new Date().getDate(), - "H+": new Date().getHours(), - "m+": new Date().getMinutes(), - "s+": new Date().getSeconds(), - "q+": Math.floor((new Date().getMonth() + 3) / 3), - S: new Date().getMilliseconds(), - }; - /(y+)/.test(t) && - (t = t.replace( - RegExp.$1, - (new Date().getFullYear() + "").substr(4 - RegExp.$1.length) - )); - for (let e in s) { - new RegExp("(" + e + ")").test(t) && - (t = t.replace( - RegExp.$1, - 1 == RegExp.$1.length - ? s[e] - : ("00" + s[e]).substr(("" + s[e]).length) - )); - } - return t; - } - - log(content) { - this.notifyStr.push(`[${this.time("HH:mm:ss")}]` + " " + this.toStr(content)) - console.log(content) - } - - wait(min, max = null) { - const ms = max == null ? min : Math.random() * (max - min + 1) + min | 0; - ms >= 1000 && this.log(`等待 ${(ms / 1000).toFixed(2)} 秒...`, { notify: false }); - return new Promise(r => setTimeout(r, ms)); - } - async done() { - await this.sendMsg(); - const s = new Date().getTime(), - e = (s - this.startTime) / 1e3; - this.log( - `\ud83d\udd14${this.name},\u7ed3\u675f!\ud83d\udd5b ${e}\u79d2` - ); - if (this.isNode()) { - process.exit(0); - } - } - parseCookie(ck) { - return typeof ck != "string" || !ck ? {} : Object.fromEntries( - ck.split(/;\s*/).filter(v => v.includes("=")).map(v => [v.slice(0, v.indexOf("=")), v.slice(v.indexOf("=") + 1)]) - ); - } - - })(t, s); -} -module.exports = { - Env -} \ No newline at end of file diff --git a/Tools/sendNotify.js b/Tools/sendNotify.js deleted file mode 100644 index 139fda0..0000000 --- a/Tools/sendNotify.js +++ /dev/null @@ -1,1542 +0,0 @@ -const querystring = require('node:querystring'); -const { request: undiciRequest, ProxyAgent, FormData } = require('undici'); -const timeout = 15000; - -async function request(url, options = {}) { - const { json, form, body, headers = {}, ...rest } = options; - - const finalHeaders = { ...headers }; - let finalBody = body; - - if (json) { - finalHeaders['content-type'] = 'application/json'; - finalBody = JSON.stringify(json); - } else if (form) { - finalBody = form; - delete finalHeaders['content-type']; - } - - return undiciRequest(url, { - headers: finalHeaders, - body: finalBody, - ...rest, - }); -} - -function post(url, options = {}) { - return request(url, { ...options, method: 'POST' }); -} - -function get(url, options = {}) { - return request(url, { ...options, method: 'GET' }); -} - -const httpClient = { - request, - post, - get, -}; - -const push_config = { - HITOKOTO: true, // 启用一言(随机句子) - - BARK_PUSH: '', // bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm/ - BARK_ARCHIVE: '', // bark 推送是否存档 - BARK_GROUP: '', // bark 推送分组 - BARK_SOUND: '', // bark 推送声音 - BARK_ICON: '', // bark 推送图标 - BARK_LEVEL: '', // bark 推送时效性 - BARK_URL: '', // bark 推送跳转URL - - DD_BOT_SECRET: '', // 钉钉机器人的 DD_BOT_SECRET - DD_BOT_TOKEN: '', // 钉钉机器人的 DD_BOT_TOKEN - - FSKEY: '', // 飞书机器人的 FSKEY - FSSECRET: '', // 飞书机器人的 FSSECRET,对应安全设置里的签名校验密钥 - - // 推送到个人QQ:http://127.0.0.1/send_private_msg - // 群:http://127.0.0.1/send_group_msg - GOBOT_URL: '', // go-cqhttp - // 推送到个人QQ 填入 user_id=个人QQ - // 群 填入 group_id=QQ群 - GOBOT_QQ: '', // go-cqhttp 的推送群或用户 - GOBOT_TOKEN: '', // go-cqhttp 的 access_token - - GOTIFY_URL: '', // gotify地址,如https://push.example.de:8080 - GOTIFY_TOKEN: '', // gotify的消息应用token - GOTIFY_PRIORITY: 0, // 推送消息优先级,默认为0 - - IGOT_PUSH_KEY: '', // iGot 聚合推送的 IGOT_PUSH_KEY,例如:https://push.hellyw.com/XXXXXXXX - - PUSH_KEY: '', // server 酱的 PUSH_KEY,兼容旧版与 Turbo 版 - - DEER_KEY: '', // PushDeer 的 PUSHDEER_KEY - DEER_URL: '', // PushDeer 的 PUSHDEER_URL - - CHAT_URL: '', // synology chat url - CHAT_TOKEN: '', // synology chat token - - // 官方文档:https://www.pushplus.plus/ - PUSH_PLUS_TOKEN: '', // pushplus 推送的用户令牌 - PUSH_PLUS_USER: '', // pushplus 推送的群组编码 - PUSH_PLUS_TEMPLATE: 'html', // pushplus 发送模板,支持html,txt,json,markdown,cloudMonitor,jenkins,route,pay - PUSH_PLUS_CHANNEL: 'wechat', // pushplus 发送渠道,支持wechat,webhook,cp,mail,sms - PUSH_PLUS_WEBHOOK: '', // pushplus webhook编码,可在pushplus公众号上扩展配置出更多渠道 - PUSH_PLUS_CALLBACKURL: '', // pushplus 发送结果回调地址,会把推送最终结果通知到这个地址上 - PUSH_PLUS_TO: '', // pushplus 好友令牌,微信公众号渠道填写好友令牌,企业微信渠道填写企业微信用户id - - // 微加机器人,官方网站:https://www.weplusbot.com/ - WE_PLUS_BOT_TOKEN: '', // 微加机器人的用户令牌 - WE_PLUS_BOT_RECEIVER: '', // 微加机器人的消息接收人 - WE_PLUS_BOT_VERSION: 'pro', //微加机器人调用版本,pro和personal;为空默认使用pro(专业版),个人版填写:personal - - QMSG_KEY: '', // qmsg 酱的 QMSG_KEY - QMSG_TYPE: '', // qmsg 酱的 QMSG_TYPE - - QYWX_ORIGIN: 'https://qyapi.weixin.qq.com', // 企业微信代理地址 - - /* - 此处填你企业微信应用消息的值(详见文档 https://work.weixin.qq.com/api/doc/90000/90135/90236) - 环境变量名 QYWX_AM依次填入 corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型) - 注意用,号隔开(英文输入法的逗号),例如:wwcff56746d9adwers,B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat - 可选推送消息类型(推荐使用图文消息(mpnews)): - - 文本卡片消息: 0 (数字零) - - 文本消息: 1 (数字一) - - 图文消息(mpnews): 素材库图片id, 可查看此教程(http://note.youdao.com/s/HMiudGkb)或者(https://note.youdao.com/ynoteshare1/index.html?id=1a0c8aff284ad28cbd011b29b3ad0191&type=note) - */ - QYWX_AM: '', // 企业微信应用 - - QYWX_KEY: '', // 企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa - - TG_BOT_TOKEN: '', // tg 机器人的 TG_BOT_TOKEN,例:1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ - TG_USER_ID: '', // tg 机器人的 TG_USER_ID,例:1434078534 - TG_API_HOST: 'https://api.telegram.org', // tg 代理 api - TG_PROXY_AUTH: '', // tg 代理认证参数 - TG_PROXY_HOST: '', // tg 机器人的 TG_PROXY_HOST - TG_PROXY_PORT: '', // tg 机器人的 TG_PROXY_PORT - - AIBOTK_KEY: '', // 智能微秘书 个人中心的apikey 文档地址:http://wechat.aibotk.com/docs/about - AIBOTK_TYPE: '', // 智能微秘书 发送目标 room 或 contact - AIBOTK_NAME: '', // 智能微秘书 发送群名 或者好友昵称和type要对应好 - - SMTP_SERVICE: '', // 邮箱服务名称,比如 126、163、Gmail、QQ 等,支持列表 https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json - SMTP_EMAIL: '', // SMTP 发件邮箱 - SMTP_TO: '', // SMTP 收件邮箱,默认通知将会发给发件邮箱 - SMTP_PASSWORD: '', // SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定 - SMTP_NAME: '', // SMTP 收发件人姓名,可随意填写 - - PUSHME_KEY: '', // 官方文档:https://push.i-i.me,PushMe 酱的 PUSHME_KEY - - // CHRONOCAT API https://chronocat.vercel.app/install/docker/official/ - CHRONOCAT_QQ: '', // 个人: user_id=个人QQ 群则填入 group_id=QQ群 多个用英文;隔开同时支持个人和群 - CHRONOCAT_TOKEN: '', // 填写在CHRONOCAT文件生成的访问密钥 - CHRONOCAT_URL: '', // Red 协议连接地址 例: http://127.0.0.1:16530 - - WEBHOOK_URL: '', // 自定义通知 请求地址 - WEBHOOK_BODY: '', // 自定义通知 请求体 - WEBHOOK_HEADERS: '', // 自定义通知 请求头 - WEBHOOK_METHOD: '', // 自定义通知 请求方法 - WEBHOOK_CONTENT_TYPE: '', // 自定义通知 content-type - - NTFY_URL: '', // ntfy地址,如https://ntfy.sh,默认为https://ntfy.sh - NTFY_TOPIC: '', // ntfy的消息应用topic - NTFY_PRIORITY: '3', // 推送消息优先级,默认为3 - NTFY_TOKEN: '', // 推送token,可选 - NTFY_USERNAME: '', // 推送用户名称,可选 - NTFY_PASSWORD: '', // 推送用户密码,可选 - NTFY_ACTIONS: '', // 推送用户动作,可选 - - // 官方文档: https://wxpusher.zjiecode.com/docs/ - // 管理后台: https://wxpusher.zjiecode.com/admin/ - WXPUSHER_APP_TOKEN: '', // wxpusher 的 appToken - WXPUSHER_TOPIC_IDS: '', // wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行 - WXPUSHER_UIDS: '', // wxpusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行 -}; - -for (const key in push_config) { - const v = process.env[key]; - if (v) { - push_config[key] = v; - } -} - -const $ = { - post: (params, callback) => { - const { url, ...others } = params; - httpClient.post(url, others).then( - async (res) => { - let body = await res.body.text(); - try { - body = JSON.parse(body); - } catch (error) { } - callback(null, res, body); - }, - (err) => { - callback(err?.response?.body || err); - }, - ); - }, - get: (params, callback) => { - const { url, ...others } = params; - httpClient.get(url, others).then( - async (res) => { - let body = await res.body.text(); - try { - body = JSON.parse(body); - } catch (error) { } - callback(null, res, body); - }, - (err) => { - callback(err?.response?.body || err); - }, - ); - }, - logErr: console.log, -}; - -async function one() { - const url = 'https://v1.hitokoto.cn/'; - const res = await httpClient.request(url); - const body = await res.body.json(); - return `${body.hitokoto} ----${body.from}`; -} - -function gotifyNotify(text, desp) { - return new Promise((resolve) => { - const { GOTIFY_URL, GOTIFY_TOKEN, GOTIFY_PRIORITY } = push_config; - if (GOTIFY_URL && GOTIFY_TOKEN) { - const options = { - url: `${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}`, - body: `title=${encodeURIComponent(text)}&message=${encodeURIComponent( - desp, - )}&priority=${GOTIFY_PRIORITY}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Gotify 发送通知调用API失败😞\n', err); - } else { - if (data.id) { - console.log('Gotify 发送通知消息成功🎉\n'); - } else { - console.log(`Gotify 发送通知调用API失败😞 ${data.message}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(); - } - }); - } else { - resolve(); - } - }); -} - -function gobotNotify(text, desp) { - return new Promise((resolve) => { - const { GOBOT_URL, GOBOT_TOKEN, GOBOT_QQ } = push_config; - if (GOBOT_URL) { - const options = { - url: `${GOBOT_URL}?access_token=${GOBOT_TOKEN}&${GOBOT_QQ}`, - json: { message: `${text}\n${desp}` }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Go-cqhttp 通知调用API失败😞\n', err); - } else { - if (data.retcode === 0) { - console.log('Go-cqhttp 发送通知消息成功🎉\n'); - } else if (data.retcode === 100) { - console.log(`Go-cqhttp 发送通知消息异常 ${data.errmsg}\n`); - } else { - console.log(`Go-cqhttp 发送通知消息异常 ${JSON.stringify(data)}`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function serverNotify(text, desp) { - return new Promise((resolve) => { - const { PUSH_KEY } = push_config; - if (PUSH_KEY) { - // 微信server酱推送通知一个\n不会换行,需要两个\n才能换行,故做此替换 - desp = desp.replace(/[\n\r]/g, '\n\n'); - - const matchResult = PUSH_KEY.match(/^sctp(\d+)t/i); - const options = { - url: - matchResult && matchResult[1] - ? `https://${matchResult[1]}.push.ft07.com/send/${PUSH_KEY}.send` - : `https://sctapi.ftqq.com/${PUSH_KEY}.send`, - body: `text=${encodeURIComponent(text)}&desp=${encodeURIComponent( - desp, - )}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Server 酱发送通知调用API失败😞\n', err); - } else { - // server酱和Server酱·Turbo版的返回json格式不太一样 - if (data.errno === 0 || data.data.errno === 0) { - console.log('Server 酱发送通知消息成功🎉\n'); - } else if (data.errno === 1024) { - // 一分钟内发送相同的内容会触发 - console.log(`Server 酱发送通知消息异常 ${data.errmsg}\n`); - } else { - console.log(`Server 酱发送通知消息异常 ${JSON.stringify(data)}`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function pushDeerNotify(text, desp) { - return new Promise((resolve) => { - const { DEER_KEY, DEER_URL } = push_config; - if (DEER_KEY) { - // PushDeer 建议对消息内容进行 urlencode - desp = encodeURI(desp); - const options = { - url: DEER_URL || `https://api2.pushdeer.com/message/push`, - body: `pushkey=${DEER_KEY}&text=${text}&desp=${desp}&type=markdown`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('PushDeer 通知调用API失败😞\n', err); - } else { - // 通过返回的result的长度来判断是否成功 - if ( - data.content.result.length !== undefined && - data.content.result.length > 0 - ) { - console.log('PushDeer 发送通知消息成功🎉\n'); - } else { - console.log( - `PushDeer 发送通知消息异常😞 ${JSON.stringify(data)}`, - ); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function chatNotify(text, desp) { - return new Promise((resolve) => { - const { CHAT_URL, CHAT_TOKEN } = push_config; - if (CHAT_URL && CHAT_TOKEN) { - // 对消息内容进行 urlencode - desp = encodeURI(desp); - const options = { - url: `${CHAT_URL}${CHAT_TOKEN}`, - body: `payload={"text":"${text}\n${desp}"}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Chat 发送通知调用API失败😞\n', err); - } else { - if (data.success) { - console.log('Chat 发送通知消息成功🎉\n'); - } else { - console.log(`Chat 发送通知消息异常 ${JSON.stringify(data)}`); - } - } - } catch (e) { - $.logErr(e); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function barkNotify(text, desp, params = {}) { - return new Promise((resolve) => { - let { - BARK_PUSH, - BARK_ICON, - BARK_SOUND, - BARK_GROUP, - BARK_LEVEL, - BARK_ARCHIVE, - BARK_URL, - } = push_config; - if (BARK_PUSH) { - // 兼容BARK本地用户只填写设备码的情况 - if (!BARK_PUSH.startsWith('http')) { - BARK_PUSH = `https://api.day.app/${BARK_PUSH}`; - } - const options = { - url: `${BARK_PUSH}`, - json: { - title: text, - body: desp, - icon: BARK_ICON, - sound: BARK_SOUND, - group: BARK_GROUP, - isArchive: BARK_ARCHIVE, - level: BARK_LEVEL, - url: BARK_URL, - ...params, - }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Bark APP 发送通知调用API失败😞\n', err); - } else { - if (data.code === 200) { - console.log('Bark APP 发送通知消息成功🎉\n'); - } else { - console.log(`Bark APP 发送通知消息异常 ${data.message}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(); - } - }); - } else { - resolve(); - } - }); -} - -function tgBotNotify(text, desp) { - return new Promise((resolve) => { - const { - TG_BOT_TOKEN, - TG_USER_ID, - TG_PROXY_HOST, - TG_PROXY_PORT, - TG_API_HOST, - TG_PROXY_AUTH, - } = push_config; - if (TG_BOT_TOKEN && TG_USER_ID) { - let options = { - url: `${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`, - json: { - chat_id: `${TG_USER_ID}`, - text: `${text}\n\n${desp}`, - disable_web_page_preview: true, - }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - if (TG_PROXY_HOST && TG_PROXY_PORT) { - let proxyHost = TG_PROXY_HOST; - if (TG_PROXY_AUTH && !TG_PROXY_HOST.includes('@')) { - proxyHost = `${TG_PROXY_AUTH}@${TG_PROXY_HOST}`; - } - let agent; - agent = new ProxyAgent({ - uri: `http://${proxyHost}:${TG_PROXY_PORT}`, - }); - options.dispatcher = agent; - } - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Telegram 发送通知消息失败😞\n', err); - } else { - if (data.ok) { - console.log('Telegram 发送通知消息成功🎉。\n'); - } else if (data.error_code === 400) { - console.log( - '请主动给bot发送一条消息并检查接收用户ID是否正确。\n', - ); - } else if (data.error_code === 401) { - console.log('Telegram bot token 填写错误。\n'); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} -function ddBotNotify(text, desp) { - return new Promise((resolve) => { - const { DD_BOT_TOKEN, DD_BOT_SECRET } = push_config; - const options = { - url: `https://oapi.dingtalk.com/robot/send?access_token=${DD_BOT_TOKEN}`, - json: { - msgtype: 'text', - text: { - content: `${text}\n\n${desp}`, - }, - }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - if (DD_BOT_TOKEN && DD_BOT_SECRET) { - const crypto = require('crypto'); - const dateNow = Date.now(); - const hmac = crypto.createHmac('sha256', DD_BOT_SECRET); - hmac.update(`${dateNow}\n${DD_BOT_SECRET}`); - const result = encodeURIComponent(hmac.digest('base64')); - options.url = `${options.url}×tamp=${dateNow}&sign=${result}`; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('钉钉发送通知消息失败😞\n', err); - } else { - if (data.errcode === 0) { - console.log('钉钉发送通知消息成功🎉\n'); - } else { - console.log(`钉钉发送通知消息异常 ${data.errmsg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else if (DD_BOT_TOKEN) { - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('钉钉发送通知消息失败😞\n', err); - } else { - if (data.errcode === 0) { - console.log('钉钉发送通知消息成功🎉\n'); - } else { - console.log(`钉钉发送通知消息异常 ${data.errmsg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function qywxBotNotify(text, desp) { - return new Promise((resolve) => { - const { QYWX_ORIGIN, QYWX_KEY } = push_config; - const options = { - url: `${QYWX_ORIGIN}/cgi-bin/webhook/send?key=${QYWX_KEY}`, - json: { - msgtype: 'text', - text: { - content: `${text}\n\n${desp}`, - }, - }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - if (QYWX_KEY) { - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('企业微信发送通知消息失败😞\n', err); - } else { - if (data.errcode === 0) { - console.log('企业微信发送通知消息成功🎉。\n'); - } else { - console.log(`企业微信发送通知消息异常 ${data.errmsg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function ChangeUserId(desp) { - const { QYWX_AM } = push_config; - const QYWX_AM_AY = QYWX_AM.split(','); - if (QYWX_AM_AY[2]) { - const userIdTmp = QYWX_AM_AY[2].split('|'); - let userId = ''; - for (let i = 0; i < userIdTmp.length; i++) { - const count = '账号' + (i + 1); - const count2 = '签到号 ' + (i + 1); - if (desp.match(count2)) { - userId = userIdTmp[i]; - } - } - if (!userId) userId = QYWX_AM_AY[2]; - return userId; - } else { - return '@all'; - } -} - -async function qywxamNotify(text, desp) { - const MAX_LENGTH = 900; - if (desp.length > MAX_LENGTH) { - let d = desp.substr(0, MAX_LENGTH) + '\n==More=='; - await do_qywxamNotify(text, d); - await qywxamNotify(text, desp.substr(MAX_LENGTH)); - } else { - return await do_qywxamNotify(text, desp); - } -} - -function do_qywxamNotify(text, desp) { - return new Promise((resolve) => { - const { QYWX_AM, QYWX_ORIGIN } = push_config; - if (QYWX_AM) { - const QYWX_AM_AY = QYWX_AM.split(','); - const options_accesstoken = { - url: `${QYWX_ORIGIN}/cgi-bin/gettoken`, - json: { - corpid: `${QYWX_AM_AY[0]}`, - corpsecret: `${QYWX_AM_AY[1]}`, - }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options_accesstoken, (err, resp, json) => { - let html = desp.replace(/\n/g, '
'); - let accesstoken = json.access_token; - let options; - - switch (QYWX_AM_AY[4]) { - case '0': - options = { - msgtype: 'textcard', - textcard: { - title: `${text}`, - description: `${desp}`, - url: 'https://github.com/whyour/qinglong', - btntxt: '更多', - }, - }; - break; - - case '1': - options = { - msgtype: 'text', - text: { - content: `${text}\n\n${desp}`, - }, - }; - break; - - default: - options = { - msgtype: 'mpnews', - mpnews: { - articles: [ - { - title: `${text}`, - thumb_media_id: `${QYWX_AM_AY[4]}`, - author: `智能助手`, - content_source_url: ``, - content: `${html}`, - digest: `${desp}`, - }, - ], - }, - }; - } - if (!QYWX_AM_AY[4]) { - // 如不提供第四个参数,则默认进行文本消息类型推送 - options = { - msgtype: 'text', - text: { - content: `${text}\n\n${desp}`, - }, - }; - } - options = { - url: `${QYWX_ORIGIN}/cgi-bin/message/send?access_token=${accesstoken}`, - json: { - touser: `${ChangeUserId(desp)}`, - agentid: `${QYWX_AM_AY[3]}`, - safe: '0', - ...options, - }, - headers: { - 'Content-Type': 'application/json', - }, - }; - - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log( - '成员ID:' + - ChangeUserId(desp) + - '企业微信应用消息发送通知消息失败😞\n', - err, - ); - } else { - if (data.errcode === 0) { - console.log( - '成员ID:' + - ChangeUserId(desp) + - '企业微信应用消息发送通知消息成功🎉。\n', - ); - } else { - console.log( - `企业微信应用消息发送通知消息异常 ${data.errmsg}\n`, - ); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - }); - } else { - resolve(); - } - }); -} - -function iGotNotify(text, desp, params = {}) { - return new Promise((resolve) => { - const { IGOT_PUSH_KEY } = push_config; - if (IGOT_PUSH_KEY) { - // 校验传入的IGOT_PUSH_KEY是否有效 - const IGOT_PUSH_KEY_REGX = new RegExp('^[a-zA-Z0-9]{24}$'); - if (!IGOT_PUSH_KEY_REGX.test(IGOT_PUSH_KEY)) { - console.log('您所提供的 IGOT_PUSH_KEY 无效\n'); - resolve(); - return; - } - const options = { - url: `https://push.hellyw.com/${IGOT_PUSH_KEY.toLowerCase()}`, - body: `title=${text}&content=${desp}&${querystring.stringify(params)}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('IGot 发送通知调用API失败😞\n', err); - } else { - if (data.ret === 0) { - console.log('IGot 发送通知消息成功🎉\n'); - } else { - console.log(`IGot 发送通知消息异常 ${data.errMsg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function pushPlusNotify(text, desp) { - return new Promise((resolve) => { - const { - PUSH_PLUS_TOKEN, - PUSH_PLUS_USER, - PUSH_PLUS_TEMPLATE, - PUSH_PLUS_CHANNEL, - PUSH_PLUS_WEBHOOK, - PUSH_PLUS_CALLBACKURL, - PUSH_PLUS_TO, - } = push_config; - if (PUSH_PLUS_TOKEN) { - desp = desp.replace(/[\n\r]/g, '
'); // 默认为html, 不支持plaintext - const body = { - token: `${PUSH_PLUS_TOKEN}`, - title: `${text}`, - content: `${desp}`, - topic: `${PUSH_PLUS_USER}`, - template: `${PUSH_PLUS_TEMPLATE}`, - channel: `${PUSH_PLUS_CHANNEL}`, - webhook: `${PUSH_PLUS_WEBHOOK}`, - callbackUrl: `${PUSH_PLUS_CALLBACKURL}`, - to: `${PUSH_PLUS_TO}`, - }; - const options = { - url: `https://www.pushplus.plus/send`, - body: JSON.stringify(body), - headers: { - 'Content-Type': ' application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log( - `pushplus 发送${PUSH_PLUS_USER ? '一对多' : '一对一' - }通知消息失败😞\n`, - err, - ); - } else { - if (data.code === 200) { - console.log( - `pushplus 发送${PUSH_PLUS_USER ? '一对多' : '一对一' - }通知请求成功🎉,可根据流水号查询推送结果:${data.data - }\n注意:请求成功并不代表推送成功,如未收到消息,请到pushplus官网使用流水号查询推送最终结果`, - ); - } else { - console.log( - `pushplus 发送${PUSH_PLUS_USER ? '一对多' : '一对一' - }通知消息异常 ${data.msg}\n`, - ); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function wePlusBotNotify(text, desp) { - return new Promise((resolve) => { - const { WE_PLUS_BOT_TOKEN, WE_PLUS_BOT_RECEIVER, WE_PLUS_BOT_VERSION } = - push_config; - if (WE_PLUS_BOT_TOKEN) { - let template = 'txt'; - if (desp.length > 800) { - desp = desp.replace(/[\n\r]/g, '
'); - template = 'html'; - } - const body = { - token: `${WE_PLUS_BOT_TOKEN}`, - title: `${text}`, - content: `${desp}`, - template: `${template}`, - receiver: `${WE_PLUS_BOT_RECEIVER}`, - version: `${WE_PLUS_BOT_VERSION}`, - }; - const options = { - url: `https://www.weplusbot.com/send`, - body: JSON.stringify(body), - headers: { - 'Content-Type': ' application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log(`微加机器人发送通知消息失败😞\n`, err); - } else { - if (data.code === 200) { - console.log(`微加机器人发送通知消息完成🎉\n`); - } else { - console.log(`微加机器人发送通知消息异常 ${data.msg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function aibotkNotify(text, desp) { - return new Promise((resolve) => { - const { AIBOTK_KEY, AIBOTK_TYPE, AIBOTK_NAME } = push_config; - if (AIBOTK_KEY && AIBOTK_TYPE && AIBOTK_NAME) { - let json = {}; - let url = ''; - switch (AIBOTK_TYPE) { - case 'room': - url = 'https://api-bot.aibotk.com/openapi/v1/chat/room'; - json = { - apiKey: `${AIBOTK_KEY}`, - roomName: `${AIBOTK_NAME}`, - message: { - type: 1, - content: `【青龙快讯】\n\n${text}\n${desp}`, - }, - }; - break; - case 'contact': - url = 'https://api-bot.aibotk.com/openapi/v1/chat/contact'; - json = { - apiKey: `${AIBOTK_KEY}`, - name: `${AIBOTK_NAME}`, - message: { - type: 1, - content: `【青龙快讯】\n\n${text}\n${desp}`, - }, - }; - break; - } - const options = { - url: url, - json, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('智能微秘书发送通知消息失败😞\n', err); - } else { - if (data.code === 0) { - console.log('智能微秘书发送通知消息成功🎉。\n'); - } else { - console.log(`智能微秘书发送通知消息异常 ${data.error}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function fsBotNotify(text, desp) { - return new Promise((resolve) => { - const { FSKEY, FSSECRET } = push_config; - if (FSKEY) { - const body = { - msg_type: 'text', - content: { text: `${text}\n\n${desp}` }, - }; - - // Add signature if secret is provided - // Note: Feishu's signature algorithm uses timestamp+"\n"+secret as the HMAC key - // and signs an empty message, which differs from typical HMAC usage - if (FSSECRET) { - const crypto = require('crypto'); - const timestamp = Math.floor(Date.now() / 1000).toString(); - const stringToSign = `${timestamp}\n${FSSECRET}`; - const hmac = crypto.createHmac('sha256', stringToSign); - const sign = hmac.digest('base64'); - body.timestamp = timestamp; - body.sign = sign; - } - - const options = { - url: `https://open.feishu.cn/open-apis/bot/v2/hook/${FSKEY}`, - json: body, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('飞书发送通知调用API失败😞\n', err); - } else { - if (data.StatusCode === 0 || data.code === 0) { - console.log('飞书发送通知消息成功🎉\n'); - } else { - console.log(`飞书发送通知消息异常 ${data.msg}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -async function smtpNotify(text, desp) { - const { SMTP_EMAIL, SMTP_TO, SMTP_PASSWORD, SMTP_SERVICE, SMTP_NAME } = - push_config; - if (![SMTP_EMAIL, SMTP_PASSWORD].every(Boolean) || !SMTP_SERVICE) { - return; - } - - try { - const nodemailer = require('nodemailer'); - const transporter = nodemailer.createTransport({ - service: SMTP_SERVICE, - auth: { - user: SMTP_EMAIL, - pass: SMTP_PASSWORD, - }, - }); - - const addr = SMTP_NAME ? `"${SMTP_NAME}" <${SMTP_EMAIL}>` : SMTP_EMAIL; - const info = await transporter.sendMail({ - from: addr, - to: SMTP_TO ? SMTP_TO.split(';') : addr, - subject: text, - html: `${desp.replace(/\n/g, '
')}`, - }); - - transporter.close(); - - if (info.messageId) { - console.log('SMTP 发送通知消息成功🎉\n'); - return true; - } - console.log('SMTP 发送通知消息失败😞\n'); - } catch (e) { - console.log('SMTP 发送通知消息出现异常😞\n', e); - } -} - -function pushMeNotify(text, desp, params = {}) { - return new Promise((resolve) => { - const { PUSHME_KEY, PUSHME_URL } = push_config; - if (PUSHME_KEY) { - const options = { - url: PUSHME_URL || 'https://push.i-i.me', - json: { push_key: PUSHME_KEY, title: text, content: desp, ...params }, - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('PushMe 发送通知调用API失败😞\n', err); - } else { - if (data === 'success') { - console.log('PushMe 发送通知消息成功🎉\n'); - } else { - console.log(`PushMe 发送通知消息异常 ${data}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function chronocatNotify(title, desp) { - return new Promise((resolve) => { - const { CHRONOCAT_TOKEN, CHRONOCAT_QQ, CHRONOCAT_URL } = push_config; - if (!CHRONOCAT_TOKEN || !CHRONOCAT_QQ || !CHRONOCAT_URL) { - resolve(); - return; - } - - const user_ids = CHRONOCAT_QQ.match(/user_id=(\d+)/g)?.map( - (match) => match.split('=')[1], - ); - const group_ids = CHRONOCAT_QQ.match(/group_id=(\d+)/g)?.map( - (match) => match.split('=')[1], - ); - - const url = `${CHRONOCAT_URL}/api/message/send`; - const headers = { - 'Content-Type': 'application/json', - Authorization: `Bearer ${CHRONOCAT_TOKEN}`, - }; - - for (const [chat_type, ids] of [ - [1, user_ids], - [2, group_ids], - ]) { - if (!ids) { - continue; - } - for (const chat_id of ids) { - const data = { - peer: { - chatType: chat_type, - peerUin: chat_id, - }, - elements: [ - { - elementType: 1, - textElement: { - content: `${title}\n\n${desp}`, - }, - }, - ], - }; - const options = { - url: url, - json: data, - headers, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Chronocat 发送QQ通知消息失败😞\n', err); - } else { - if (chat_type === 1) { - console.log(`Chronocat 个人消息 ${ids}推送成功🎉`); - } else { - console.log(`Chronocat 群消息 ${ids}推送成功🎉`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } - } - }); -} - -function qmsgNotify(text, desp) { - return new Promise((resolve) => { - const { QMSG_KEY, QMSG_TYPE } = push_config; - if (QMSG_KEY && QMSG_TYPE) { - const options = { - url: `https://qmsg.zendee.cn/${QMSG_TYPE}/${QMSG_KEY}`, - body: `msg=${text}\n\n${desp.replace('----', '-')}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - timeout, - }; - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Qmsg 发送通知调用API失败😞\n', err); - } else { - if (data.code === 0) { - console.log('Qmsg 发送通知消息成功🎉\n'); - } else { - console.log(`Qmsg 发送通知消息异常 ${data}\n`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function webhookNotify(text, desp) { - return new Promise((resolve) => { - const { - WEBHOOK_URL, - WEBHOOK_BODY, - WEBHOOK_HEADERS, - WEBHOOK_CONTENT_TYPE, - WEBHOOK_METHOD, - } = push_config; - if ( - !WEBHOOK_METHOD || - !WEBHOOK_URL || - (!WEBHOOK_URL.includes('$title') && !WEBHOOK_BODY.includes('$title')) - ) { - resolve(); - return; - } - - const headers = parseHeaders(WEBHOOK_HEADERS); - const body = parseBody(WEBHOOK_BODY, WEBHOOK_CONTENT_TYPE, (v) => - v - ?.replaceAll('$title', text?.replaceAll('\n', '\\n')) - ?.replaceAll('$content', desp?.replaceAll('\n', '\\n')), - ); - const bodyParam = formatBodyFun(WEBHOOK_CONTENT_TYPE, body); - const options = { - method: WEBHOOK_METHOD, - headers, - allowGetBody: true, - ...bodyParam, - timeout, - retry: 1, - }; - - const formatUrl = WEBHOOK_URL.replaceAll( - '$title', - encodeURIComponent(text), - ).replaceAll('$content', encodeURIComponent(desp)); - httpClient.request(formatUrl, options).then(async (resp) => { - const body = await resp.body.text(); - try { - if (resp.statusCode !== 200) { - console.log(`自定义发送通知消息失败😞 ${body}\n`); - } else { - console.log(`自定义发送通知消息成功🎉 ${body}\n`); - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(body); - } - }); - }); -} - -function ntfyNotify(text, desp) { - function encodeRFC2047(text) { - const encodedBase64 = Buffer.from(text).toString('base64'); - return `=?utf-8?B?${encodedBase64}?=`; - } - - return new Promise((resolve) => { - const { - NTFY_URL, - NTFY_TOPIC, - NTFY_PRIORITY, - NTFY_TOKEN, - NTFY_USERNAME, - NTFY_PASSWORD, - NTFY_ACTIONS, - } = push_config; - if (NTFY_TOPIC) { - const options = { - url: `${NTFY_URL || 'https://ntfy.sh'}/${NTFY_TOPIC}`, - body: `${desp}`, - headers: { - Title: `${encodeRFC2047(text)}`, - Priority: NTFY_PRIORITY || '3', - Icon: 'https://qn.whyour.cn/logo.png', - }, - timeout, - }; - if (NTFY_TOKEN) { - options.headers['Authorization'] = `Bearer ${NTFY_TOKEN}`; - } else if (NTFY_USERNAME && NTFY_PASSWORD) { - options.headers['Authorization'] = - `Basic ${Buffer.from(`${NTFY_USERNAME}:${NTFY_PASSWORD}`).toString('base64')}`; - } - if (NTFY_ACTIONS) { - options.headers['Actions'] = encodeRFC2047(NTFY_ACTIONS); - } - - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('Ntfy 通知调用API失败😞\n', err); - } else { - if (data.id) { - console.log('Ntfy 发送通知消息成功🎉\n'); - } else { - console.log(`Ntfy 发送通知消息异常 ${JSON.stringify(data)}`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function wxPusherNotify(text, desp) { - return new Promise((resolve) => { - const { WXPUSHER_APP_TOKEN, WXPUSHER_TOPIC_IDS, WXPUSHER_UIDS } = - push_config; - if (WXPUSHER_APP_TOKEN) { - // 处理topic_ids,将分号分隔的字符串转为数组 - const topicIds = WXPUSHER_TOPIC_IDS - ? WXPUSHER_TOPIC_IDS.split(';') - .map((id) => id.trim()) - .filter((id) => id) - .map((id) => parseInt(id)) - : []; - - // 处理uids,将分号分隔的字符串转为数组 - const uids = WXPUSHER_UIDS - ? WXPUSHER_UIDS.split(';') - .map((uid) => uid.trim()) - .filter((uid) => uid) - : []; - - // topic_ids uids 至少有一个 - if (!topicIds.length && !uids.length) { - console.log( - 'wxpusher 服务的 WXPUSHER_TOPIC_IDS 和 WXPUSHER_UIDS 至少设置一个!!', - ); - return resolve(); - } - - const body = { - appToken: WXPUSHER_APP_TOKEN, - content: `

${text}


${desp}
`, - summary: text, - contentType: 2, - topicIds: topicIds, - uids: uids, - verifyPayType: 0, - }; - - const options = { - url: 'https://wxpusher.zjiecode.com/api/send/message', - body: JSON.stringify(body), - headers: { - 'Content-Type': 'application/json', - }, - timeout, - }; - - $.post(options, (err, resp, data) => { - try { - if (err) { - console.log('wxpusher发送通知消息失败!\n', err); - } else { - if (data.code === 1000) { - console.log('wxpusher发送通知消息完成!'); - } else { - console.log(`wxpusher发送通知消息异常:${data.msg}`); - } - } - } catch (e) { - $.logErr(e, resp); - } finally { - resolve(data); - } - }); - } else { - resolve(); - } - }); -} - -function parseString(input, valueFormatFn) { - const regex = /(\w+):\s*((?:(?!\n\w+:).)*)/g; - const matches = {}; - - let match; - while ((match = regex.exec(input)) !== null) { - const [, key, value] = match; - const _key = key.trim(); - if (!_key || matches[_key]) { - continue; - } - - let _value = value.trim(); - - try { - _value = valueFormatFn ? valueFormatFn(_value) : _value; - const jsonValue = JSON.parse(_value); - matches[_key] = jsonValue; - } catch (error) { - matches[_key] = _value; - } - } - - return matches; -} - -function parseHeaders(headers) { - if (!headers) return {}; - - const parsed = {}; - let key; - let val; - let i; - - headers && - headers.split('\n').forEach(function parser(line) { - i = line.indexOf(':'); - key = line.substring(0, i).trim().toLowerCase(); - val = line.substring(i + 1).trim(); - - if (!key) { - return; - } - - parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; - }); - - return parsed; -} - -function parseBody(body, contentType, valueFormatFn) { - if (contentType === 'text/plain' || !body) { - return valueFormatFn && body ? valueFormatFn(body) : body; - } - - const parsed = parseString(body, valueFormatFn); - - switch (contentType) { - case 'multipart/form-data': - return Object.keys(parsed).reduce((p, c) => { - p.append(c, parsed[c]); - return p; - }, new FormData()); - case 'application/x-www-form-urlencoded': - return Object.keys(parsed).reduce((p, c) => { - return p ? `${p}&${c}=${parsed[c]}` : `${c}=${parsed[c]}`; - }); - } - - return parsed; -} - -function formatBodyFun(contentType, body) { - if (!body) return {}; - switch (contentType) { - case 'application/json': - return { json: body }; - case 'multipart/form-data': - return { form: body }; - case 'application/x-www-form-urlencoded': - case 'text/plain': - return { body }; - } - return {}; -} - -/** - * sendNotify 推送通知功能 - * @param text 通知头 - * @param desp 通知体 - * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } - * @returns {Promise} - */ -async function sendNotify(text, desp, params = {}) { - // 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔 - let skipTitle = process.env.SKIP_PUSH_TITLE; - if (skipTitle) { - if (skipTitle.split('\n').includes(text)) { - console.info(text + '在 SKIP_PUSH_TITLE 环境变量内,跳过推送'); - return; - } - } - - if (push_config.HITOKOTO !== 'false') { - desp += '\n\n' + (await one()); - } - - await Promise.all([ - serverNotify(text, desp), // 微信server酱 - pushPlusNotify(text, desp), // pushplus - wePlusBotNotify(text, desp), // 微加机器人 - barkNotify(text, desp, params), // iOS Bark APP - tgBotNotify(text, desp), // telegram 机器人 - ddBotNotify(text, desp), // 钉钉机器人 - qywxBotNotify(text, desp), // 企业微信机器人 - qywxamNotify(text, desp), // 企业微信应用消息推送 - iGotNotify(text, desp, params), // iGot - gobotNotify(text, desp), // go-cqhttp - gotifyNotify(text, desp), // gotify - chatNotify(text, desp), // synolog chat - pushDeerNotify(text, desp), // PushDeer - aibotkNotify(text, desp), // 智能微秘书 - fsBotNotify(text, desp), // 飞书机器人 - smtpNotify(text, desp), // SMTP 邮件 - pushMeNotify(text, desp, params), // PushMe - chronocatNotify(text, desp), // Chronocat - webhookNotify(text, desp), // 自定义通知 - qmsgNotify(text, desp), // 自定义通知 - ntfyNotify(text, desp), // Ntfy - wxPusherNotify(text, desp), // wxpusher - ]); -} - -module.exports = { - sendNotify, -}; \ No newline at end of file