Update sendNotify.js

This commit is contained in:
smallfawn
2023-07-14 09:17:33 +08:00
committed by GitHub
parent 34471b1d71
commit 2fae1f9fc2

View File

@@ -8,8 +8,6 @@
* @param desp 通知体 * @param desp 通知体
* @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' }
* @param author 作者仓库等信息 例:`本通知 Byhttps://github.com/whyour/qinglong` * @param author 作者仓库等信息 例:`本通知 Byhttps://github.com/whyour/qinglong`
* @魔改smallfawn https://github.com/smallfawn/QLScriptPublic 参考ccwav https://github.com/ccwav/QLScript2
* @魔改位置 sendNotify函数 黑白名单模式
*/ */
const querystring = require('querystring'); const querystring = require('querystring');
@@ -36,12 +34,23 @@ let GOBOT_QQ = ''; // 如果GOBOT_URL设置 /send_private_msg 则需要填入 us
//(环境变量名 PUSH_KEY) //(环境变量名 PUSH_KEY)
let SCKEY = ''; let SCKEY = '';
// =======================================PushDeer通知设置区域===========================================
//此处填你申请的PushDeer KEY.
//(环境变量名 DEER_KEY)
let PUSHDEER_KEY = '';
let PUSHDEER_URL = '';
// =======================================Synology Chat通知设置区域===========================================
//此处填你申请的CHAT_URL与CHAT_TOKEN
//(环境变量名 CHAT_URL CHAT_TOKEN)
let CHAT_URL = '';
let CHAT_TOKEN = '';
// =======================================Bark App通知设置区域=========================================== // =======================================Bark App通知设置区域===========================================
//此处填你BarkAPP的信息(IP/设备码例如https://api.day.app/XXXXXXXX) //此处填你BarkAPP的信息(IP/设备码例如https://api.day.app/XXXXXXXX)
let BARK_PUSH = ''; let BARK_PUSH = '';
//BARK app推送图标,自定义推送图标(需iOS15或以上) //BARK app推送图标,自定义推送图标(需iOS15或以上)
let BARK_ICON = let BARK_ICON = 'https://qn.whyour.cn/logo.png';
'https://img.gejiba.com/images/a3f551e09ac19add4c49ec16228729c5.png';
//BARK app推送铃声,铃声列表去APP查看复制填写 //BARK app推送铃声,铃声列表去APP查看复制填写
let BARK_SOUND = ''; let BARK_SOUND = '';
//BARK app推送消息的分组, 默认为"QingLong" //BARK app推送消息的分组, 默认为"QingLong"
@@ -67,6 +76,10 @@ let DD_BOT_TOKEN = '';
//密钥机器人安全设置页面加签一栏下面显示的SEC开头的字符串 //密钥机器人安全设置页面加签一栏下面显示的SEC开头的字符串
let DD_BOT_SECRET = ''; let DD_BOT_SECRET = '';
// =======================================企业微信基础设置===========================================
// 企业微信反向代理地址
//(环境变量名 QYWX_ORIGIN)
let QYWX_ORIGIN = '';
// =======================================企业微信机器人通知设置区域=========================================== // =======================================企业微信机器人通知设置区域===========================================
//此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770)例如693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa //此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770)例如693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
//(环境变量名 QYWX_KEY) //(环境变量名 QYWX_KEY)
@@ -95,6 +108,39 @@ let IGOT_PUSH_KEY = '';
let PUSH_PLUS_TOKEN = ''; let PUSH_PLUS_TOKEN = '';
let PUSH_PLUS_USER = ''; let PUSH_PLUS_USER = '';
// =======================================Cool Push设置区域=======================================
//官方文档https://cp.xuthus.cc/docs
//QQ_SKEY: Cool Push登录授权后推送消息的调用代码Skey
//QQ_MODE: 推送模式详情请登录获取QQ_SKEY后见https://cp.xuthus.cc/feat
let QQ_SKEY = '';
let QQ_MODE = '';
// =======================================智能微秘书设置区域=======================================
//官方文档http://wechat.aibotk.com/docs/about
//AIBOTK_KEY 填写智能微秘书个人中心的apikey
//AIBOTK_TYPE填写发送的目标 room 或 contact, 填其他的不生效
//AIBOTK_NAME: 填写群名或用户昵称和上面的type类型要对应
let AIBOTK_KEY = '';
let AIBOTK_TYPE = '';
let AIBOTK_NAME = '';
// =======================================飞书机器人设置区域=======================================
//官方文档https://www.feishu.cn/hc/zh-CN/articles/360024984973
//FSKEY 飞书机器人的 FSKEY
let FSKEY = '';
// =======================================SMTP 邮件设置区域=======================================
// SMTP_SERVER: 填写 SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465
// SMTP_SSL: 填写 SMTP 发送邮件服务器是否使用 SSL内容应为 true 或 false
// SMTP_EMAIL: 填写 SMTP 收发件邮箱,通知将会由自己发给自己
// SMTP_PASSWORD: 填写 SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
// SMTP_NAME: 填写 SMTP 收发件人姓名,可随意填写
let SMTP_SERVER = '';
let SMTP_SSL = 'false';
let SMTP_EMAIL = '';
let SMTP_PASSWORD = '';
let SMTP_NAME = '';
//==========================云端环境变量的判断与接收========================= //==========================云端环境变量的判断与接收=========================
if (process.env.GOTIFY_URL) { if (process.env.GOTIFY_URL) {
GOTIFY_URL = process.env.GOTIFY_URL; GOTIFY_URL = process.env.GOTIFY_URL;
@@ -120,6 +166,19 @@ if (process.env.PUSH_KEY) {
SCKEY = process.env.PUSH_KEY; SCKEY = process.env.PUSH_KEY;
} }
if (process.env.DEER_KEY) {
PUSHDEER_KEY = process.env.DEER_KEY;
PUSHDEER_URL = process.env.DEER_URL;
}
if (process.env.CHAT_URL) {
CHAT_URL = process.env.CHAT_URL;
}
if (process.env.CHAT_TOKEN) {
CHAT_TOKEN = process.env.CHAT_TOKEN;
}
if (process.env.QQ_SKEY) { if (process.env.QQ_SKEY) {
QQ_SKEY = process.env.QQ_SKEY; QQ_SKEY = process.env.QQ_SKEY;
} }
@@ -175,6 +234,12 @@ if (process.env.DD_BOT_TOKEN) {
} }
} }
if (process.env.QYWX_ORIGIN) {
QYWX_ORIGIN = process.env.QYWX_ORIGIN;
} else {
QYWX_ORIGIN = 'https://qyapi.weixin.qq.com';
}
if (process.env.QYWX_KEY) { if (process.env.QYWX_KEY) {
QYWX_KEY = process.env.QYWX_KEY; QYWX_KEY = process.env.QYWX_KEY;
} }
@@ -193,12 +258,40 @@ if (process.env.PUSH_PLUS_TOKEN) {
if (process.env.PUSH_PLUS_USER) { if (process.env.PUSH_PLUS_USER) {
PUSH_PLUS_USER = process.env.PUSH_PLUS_USER; PUSH_PLUS_USER = process.env.PUSH_PLUS_USER;
} }
if (process.env.AIBOTK_KEY) {
AIBOTK_KEY = process.env.AIBOTK_KEY;
}
if (process.env.AIBOTK_TYPE) {
AIBOTK_TYPE = process.env.AIBOTK_TYPE;
}
if (process.env.AIBOTK_NAME) {
AIBOTK_NAME = process.env.AIBOTK_NAME;
}
if (process.env.FSKEY) {
FSKEY = process.env.FSKEY;
}
if (process.env.SMTP_SERVER) {
SMTP_SERVER = process.env.SMTP_SERVER;
}
if (process.env.SMTP_SSL) {
SMTP_SSL = process.env.SMTP_SSL;
}
if (process.env.SMTP_EMAIL) {
SMTP_EMAIL = process.env.SMTP_EMAIL;
}
if (process.env.SMTP_PASSWORD) {
SMTP_PASSWORD = process.env.SMTP_PASSWORD;
}
if (process.env.SMTP_NAME) {
SMTP_NAME = process.env.SMTP_NAME;
}
//==========================云端环境变量的判断与接收========================= //==========================云端环境变量的判断与接收=========================
/** /**
* sendNotify 推送通知功能 * sendNotify 推送通知功能
* 魔改smallfawn https://github.com/smallfawn 增加黑白名单模式
* 变量值 smallfawnPushWhite白名单 smallfawnPushBlack黑名单 不写默认通知 黑白名单二选一
* @param text 通知头 * @param text 通知头
* @param desp 通知体 * @param desp 通知体
* @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' }
@@ -281,6 +374,16 @@ async function sendNotify(
async function push() { async function push() {
//提供6种通知 //提供6种通知
desp += author; //增加作者信息,防止被贩卖等 desp += author; //增加作者信息,防止被贩卖等
// 根据标题跳过一些消息推送环境变量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;
}
}
await Promise.all([ await Promise.all([
serverNotify(text, desp), //微信server酱 serverNotify(text, desp), //微信server酱
pushPlusNotify(text, desp), //pushplus(推送加) pushPlusNotify(text, desp), //pushplus(推送加)
@@ -296,14 +399,14 @@ async function sendNotify(
iGotNotify(text, desp, params), //iGot iGotNotify(text, desp, params), //iGot
gobotNotify(text, desp), //go-cqhttp gobotNotify(text, desp), //go-cqhttp
gotifyNotify(text, desp), //gotify gotifyNotify(text, desp), //gotify
ChatNotify(text, desp), //synolog chat
PushDeerNotify(text, desp), //PushDeer
aibotkNotify(text, desp), //智能微秘书
fsBotNotify(text, desp), //飞书机器人
smtpNotify(text, desp), //SMTP 邮件
]); ]);
} }
} }
function gotifyNotify(text, desp) { function gotifyNotify(text, desp) {
@@ -343,7 +446,7 @@ function gotifyNotify(text, desp) {
}); });
} }
function gobotNotify(text, desp, time = 2100) { function gobotNotify(text, desp) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (GOBOT_URL) { if (GOBOT_URL) {
const options = { const options = {
@@ -354,7 +457,6 @@ function gobotNotify(text, desp, time = 2100) {
}, },
timeout, timeout,
}; };
setTimeout(() => {
$.post(options, (err, resp, data) => { $.post(options, (err, resp, data) => {
try { try {
if (err) { if (err) {
@@ -367,9 +469,7 @@ function gobotNotify(text, desp, time = 2100) {
} else if (data.retcode === 100) { } else if (data.retcode === 100) {
console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`); console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`);
} else { } else {
console.log( console.log(`go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`);
`go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`,
);
} }
} }
} catch (e) { } catch (e) {
@@ -378,14 +478,13 @@ function gobotNotify(text, desp, time = 2100) {
resolve(data); resolve(data);
} }
}); });
}, time);
} else { } else {
resolve(); resolve();
} }
}); });
} }
function serverNotify(text, desp, time = 2100) { function serverNotify(text, desp) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (SCKEY) { if (SCKEY) {
//微信server酱推送通知一个\n不会换行需要两个\n才能换行故做此替换 //微信server酱推送通知一个\n不会换行需要两个\n才能换行故做此替换
@@ -400,7 +499,6 @@ function serverNotify(text, desp, time = 2100) {
}, },
timeout, timeout,
}; };
setTimeout(() => {
$.post(options, (err, resp, data) => { $.post(options, (err, resp, data) => {
try { try {
if (err) { if (err) {
@@ -415,9 +513,7 @@ function serverNotify(text, desp, time = 2100) {
// 一分钟内发送相同的内容会触发 // 一分钟内发送相同的内容会触发
console.log(`server酱发送通知消息异常: ${data.errmsg}\n`); console.log(`server酱发送通知消息异常: ${data.errmsg}\n`);
} else { } else {
console.log( console.log(`server酱发送通知消息异常\n${JSON.stringify(data)}`);
`server酱发送通知消息异常\n${JSON.stringify(data)}`,
);
} }
} }
} catch (e) { } catch (e) {
@@ -426,75 +522,40 @@ function serverNotify(text, desp, time = 2100) {
resolve(data); resolve(data);
} }
}); });
}, time);
} else { } else {
resolve(); resolve();
} }
}); });
} }
function CoolPush(text, desp) { function PushDeerNotify(text, desp) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (QQ_SKEY) { if (PUSHDEER_KEY) {
let options = { // PushDeer 建议对消息内容进行 urlencode
url: `https://push.xuthus.cc/${QQ_MODE}/${QQ_SKEY}`, desp = encodeURI(desp);
const options = {
url: PUSHDEER_URL || `https://api2.pushdeer.com/message/push`,
body: `pushkey=${PUSHDEER_KEY}&text=${text}&desp=${desp}&type=markdown`,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded',
}, },
timeout,
}; };
// 已知敏感词
text = text.replace(/京豆/g, '豆豆');
desp = desp.replace(/京豆/g, '');
desp = desp.replace(/🐶/g, '');
desp = desp.replace(/红包/g, 'H包');
switch (QQ_MODE) {
case 'email':
options.json = {
t: text,
c: desp,
};
break;
default:
options.body = `${text}\n\n${desp}`;
}
let pushMode = function (t) {
switch (t) {
case 'send':
return '个人';
case 'group':
return 'QQ群';
case 'wx':
return '微信';
case 'ww':
return '企业微信';
case 'email':
return '邮件';
default:
return '未知方式';
}
};
$.post(options, (err, resp, data) => { $.post(options, (err, resp, data) => {
try { try {
if (err) { if (err) {
console.log(`发送${pushMode(QQ_MODE)}通知调用API失败\n`); console.log('发送通知调用API失败\n');
console.log(err); console.log(err);
} else { } else {
data = JSON.parse(data); data = JSON.parse(data);
if (data.code === 200) { // 通过返回的result的长度来判断是否成功
console.log(`酷推发送${pushMode(QQ_MODE)}通知消息成功🎉\n`); if (
} else if (data.code === 400) { data.content.result.length !== undefined &&
console.log( data.content.result.length > 0
`QQ酷推(Cool Push)发送${pushMode(QQ_MODE)}推送失败:${data.msg ) {
}\n`, console.log('PushDeer发送通知消息成功🎉\n');
);
} else if (data.code === 503) {
console.log(`QQ酷推出错${data.message}${data.data}\n`);
} else { } else {
console.log(`酷推推送异常: ${JSON.stringify(data)}`); console.log(`PushDeer发送通知消息异常\n${JSON.stringify(data)}`);
} }
} }
} catch (e) { } catch (e) {
@@ -509,13 +570,50 @@ function CoolPush(text, desp) {
}); });
} }
function ChatNotify(text, desp) {
return new Promise((resolve) => {
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('发送通知调用API失败\n');
console.log(err);
} else {
data = JSON.parse(data);
if (data.success) {
console.log('Chat发送通知消息成功🎉\n');
} else {
console.log(`Chat发送通知消息异常\n${JSON.stringify(data)}`);
}
}
} catch (e) {
$.logErr(e);
} finally {
resolve(data);
}
});
} else {
resolve();
}
});
}
function BarkNotify(text, desp, params = {}) { function BarkNotify(text, desp, params = {}) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (BARK_PUSH) { if (BARK_PUSH) {
const options = { const options = {
url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent( url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent(
desp, desp,
)}?icon=${BARK_ICON}?sound=${BARK_SOUND}&group=${BARK_GROUP}&${querystring.stringify( )}?icon=${BARK_ICON}&sound=${BARK_SOUND}&group=${BARK_GROUP}&${querystring.stringify(
params, params,
)}`, )}`,
headers: { headers: {
@@ -553,9 +651,13 @@ function tgBotNotify(text, desp) {
if (TG_BOT_TOKEN && TG_USER_ID) { if (TG_BOT_TOKEN && TG_USER_ID) {
const options = { const options = {
url: `https://${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`, url: `https://${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`,
body: `chat_id=${TG_USER_ID}&text=${text}\n\n${desp}&disable_web_page_preview=true`, json: {
chat_id: `${TG_USER_ID}`,
text: `${text}\n\n${desp}`,
disable_web_page_preview: true,
},
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/json',
}, },
timeout, timeout,
}; };
@@ -670,7 +772,7 @@ function ddBotNotify(text, desp) {
function qywxBotNotify(text, desp) { function qywxBotNotify(text, desp) {
return new Promise((resolve) => { return new Promise((resolve) => {
const options = { const options = {
url: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`, url: `${QYWX_ORIGIN}/cgi-bin/webhook/send?key=${QYWX_KEY}`,
json: { json: {
msgtype: 'text', msgtype: 'text',
text: { text: {
@@ -732,7 +834,7 @@ function qywxamNotify(text, desp) {
if (QYWX_AM) { if (QYWX_AM) {
const QYWX_AM_AY = QYWX_AM.split(','); const QYWX_AM_AY = QYWX_AM.split(',');
const options_accesstoken = { const options_accesstoken = {
url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`, url: `${QYWX_ORIGIN}/cgi-bin/gettoken`,
json: { json: {
corpid: `${QYWX_AM_AY[0]}`, corpid: `${QYWX_AM_AY[0]}`,
corpsecret: `${QYWX_AM_AY[1]}`, corpsecret: `${QYWX_AM_AY[1]}`,
@@ -743,9 +845,9 @@ function qywxamNotify(text, desp) {
timeout, timeout,
}; };
$.post(options_accesstoken, (err, resp, data) => { $.post(options_accesstoken, (err, resp, data) => {
html = desp.replace(/\n/g, '<br/>'); let html = desp.replace(/\n/g, '<br/>');
var json = JSON.parse(data); let json = JSON.parse(data);
accesstoken = json.access_token; let accesstoken = json.access_token;
let options; let options;
switch (QYWX_AM_AY[4]) { switch (QYWX_AM_AY[4]) {
@@ -797,7 +899,7 @@ function qywxamNotify(text, desp) {
}; };
} }
options = { options = {
url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accesstoken}`, url: `${QYWX_ORIGIN}/cgi-bin/message/send?access_token=${accesstoken}`,
json: { json: {
touser: `${ChangeUserId(desp)}`, touser: `${ChangeUserId(desp)}`,
agentid: `${QYWX_AM_AY[3]}`, agentid: `${QYWX_AM_AY[3]}`,
@@ -938,6 +1040,150 @@ function pushPlusNotify(text, desp) {
}); });
} }
function aibotkNotify(text, desp) {
return new Promise((resolve) => {
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');
console.log(err);
} else {
data = JSON.parse(data);
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) => {
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');
console.log(err);
} else {
data = JSON.parse(data);
if (data.StatusCode === 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) {
if (![SMTP_SERVER, SMTP_EMAIL, SMTP_PASSWORD].every(Boolean)) {
return;
}
try {
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport(
`${SMTP_SSL === 'true' ? 'smtps:' : 'smtp:'}//${SMTP_SERVER}`,
{
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,
text: desp,
});
if (!!info.messageId) {
console.log('SMTP发送通知消息成功🎉\n');
return true;
}
console.log('SMTP发送通知消息失败\n');
} catch (e) {
console.log('SMTP发送通知消息出现错误\n');
console.log(e);
}
}
function smtpNotify(text, desp) {
return new Promise((resolve) => {
if (SMTP_SERVER && SMTP_SSL && SMTP_EMAIL && SMTP_PASSWORD && SMTP_NAME) {
// todo: Node.js并没有内置的 smtp 实现,需要调用外部库,因为不清楚这个文件的模块依赖情况,所以留给有缘人实现
} else {
resolve();
}
});
}
module.exports = { module.exports = {
sendNotify, sendNotify,
BARK_PUSH, BARK_PUSH,