diff --git a/Notify.js b/Notify.js
deleted file mode 100644
index 661a543..0000000
--- a/Notify.js
+++ /dev/null
@@ -1,1322 +0,0 @@
-const querystring = require('node:querystring');
-const got = require('got');
-const timeout = 15000;
-
-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
-
- // 推送到个人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
-
- // 官方文档:http://www.pushplus.plus/
- PUSH_PLUS_TOKEN: '', // push+ 微信推送的用户令牌
- PUSH_PLUS_USER: '', // push+ 微信推送的群组编码
-
- // 微加机器人,官方网站: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_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
-};
-
-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;
- got.post(url, others).then(
- (res) => {
- let body = res.body;
- try {
- body = JSON.parse(body);
- } catch (error) {}
- callback(null, res, body);
- },
- (err) => {
- callback(err?.response?.body || err);
- },
- );
- },
- get: (params, callback) => {
- const { url, ...others } = params;
- got.get(url, others).then(
- (res) => {
- let body = res.body;
- 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 got.get(url);
- const body = JSON.parse(res.body);
- 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 options = {
- url: PUSH_KEY.includes('SCT')
- ? `https://sctapi.ftqq.com/${PUSH_KEY}.send`
- : `https://sc.ftqq.com/${PUSH_KEY}.send`,
- body: `text=${text}&desp=${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) {
- const 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) {
- const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
- const options = {
- keepAlive: true,
- keepAliveMsecs: 1000,
- maxSockets: 256,
- maxFreeSockets: 256,
- proxy: `http://${TG_PROXY_AUTH}${TG_PROXY_HOST}:${TG_PROXY_PORT}`,
- };
- const httpAgent = new HttpProxyAgent(options);
- const httpsAgent = new HttpsProxyAgent(options);
- const agent = {
- http: httpAgent,
- https: httpsAgent,
- };
- Object.assign(options, { 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_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}`,
- };
- 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(
- `Push+ 发送${
- PUSH_PLUS_USER ? '一对多' : '一对一'
- }通知消息失败😞\n`,
- err,
- );
- } else {
- if (data.code === 200) {
- console.log(
- `Push+ 发送${
- PUSH_PLUS_USER ? '一对多' : '一对一'
- }通知消息完成🎉\n`,
- );
- } else {
- console.log(
- `Push+ 发送${
- 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) {
- const 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 } = push_config;
- if (FSKEY) {
- const options = {
- url: `https://open.feishu.cn/open-apis/bot/v2/hook/${FSKEY}`,
- json: { msg_type: 'text', content: { text: `${text}\n\n${desp}` } },
- 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_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: 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_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('$content', desp),
- );
- const bodyParam = formatBodyFun(WEBHOOK_CONTENT_TYPE, body);
- const options = {
- method: WEBHOOK_METHOD,
- headers,
- allowGetBody: true,
- ...bodyParam,
- timeout,
- retry: 1,
- };
-
- if (WEBHOOK_METHOD) {
- const formatUrl = WEBHOOK_URL.replaceAll(
- '$title',
- encodeURIComponent(text),
- ).replaceAll('$content', encodeURIComponent(desp));
- got(formatUrl, options).then((resp) => {
- try {
- if (resp.statusCode !== 200) {
- console.log(`自定义发送通知消息失败😞 ${resp.body}\n`);
- } else {
- console.log(`自定义发送通知消息成功🎉 ${resp.body}\n`);
- }
- } catch (e) {
- $.logErr(e, resp);
- } finally {
- resolve(resp.body);
- }
- });
- } 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), // 自定义通知
- ]);
-}
-
-module.exports = {
- sendNotify,
-};