Skip to content

Commit

Permalink
增加chronocat无头模式的QQNT推送 用于无法使go-cqhttp的接替 (#2141)
Browse files Browse the repository at this point in the history
* 增加chronocat无头模式的QQNT推送

* Chronocat发送时没有配置群号或个人消息号发送出错

* 增加系统通知、去除注释

* 增加系统通知

---------

Co-authored-by: child <[email protected]>
  • Loading branch information
youfak and child authored Oct 14, 2023
1 parent 9f7beb9 commit 5055045
Show file tree
Hide file tree
Showing 6 changed files with 295 additions and 26 deletions.
9 changes: 9 additions & 0 deletions back/data/notify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum NotificationMode {
'pushMe' = 'pushMe',
'feishu' = 'feishu',
'webhook' = 'webhook',
'chronocat' = 'Chronocat',
}

abstract class NotificationBaseInfo {
Expand Down Expand Up @@ -108,6 +109,12 @@ export class PushMeNotification extends NotificationBaseInfo {
public pushMeKey: string = '';
}

export class ChronocatNotification extends NotificationBaseInfo {
public chronocatURL: string = '';
public chronocatQQ: string = '';
public chronocatToekn: string = '';
}

export class WebhookNotification extends NotificationBaseInfo {
public webhookHeaders: string = '';
public webhookBody: string = '';
Expand Down Expand Up @@ -140,4 +147,6 @@ export interface NotificationInfo
EmailNotification,
PushMeNotification,
WebhookNotification,
ChronocatNotification,
LarkNotification {}

73 changes: 66 additions & 7 deletions back/services/notify.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { NotificationInfo } from '../data/notify';
import { Service, Inject } from 'typedi';
import winston from 'winston';
import UserService from './user';
import got from 'got';
import nodemailer from 'nodemailer';
import crypto from 'crypto';
import got from 'got';
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
import nodemailer from 'nodemailer';
import { Inject, Service } from 'typedi';
import winston from 'winston';
import { parseBody, parseHeaders } from '../config/util';
import { NotificationInfo } from '../data/notify';
import UserService from './user';

@Service()
export default class NotificationService {
Expand All @@ -31,6 +31,7 @@ export default class NotificationService {
['pushMe', this.pushMe],
['webhook', this.webhook],
['lark', this.lark],
['chronocat', this.chronocat],
]);

private title = '';
Expand Down Expand Up @@ -195,7 +196,8 @@ export default class NotificationService {
}

private async bark() {
let { barkPush, barkIcon, barkSound, barkGroup, barkLevel, barkUrl } = this.params;
let { barkPush, barkIcon, barkSound, barkGroup, barkLevel, barkUrl } =
this.params;
if (!barkPush.startsWith('http')) {
barkPush = `https://api.day.app/${barkPush}`;
}
Expand Down Expand Up @@ -588,6 +590,63 @@ export default class NotificationService {
}
}

private async chronocat() {
const { chronocatURL, chronocatQQ, chronocatToekn } = this.params;
try {
const user_ids = chronocatQQ
.match(/user_id=(\d+)/g)
?.map((match: any) => match.split('=')[1]);
const group_ids = chronocatQQ
.match(/group_id=(\d+)/g)
?.map((match: any) => match.split('=')[1]);

const url = `${chronocatURL}/api/message/send`;
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${chronocatToekn}`,
};

for (const [chat_type, ids] of [
[1, user_ids],
[2, group_ids],
]) {
if (!ids) {
continue;
}
let _ids: any = ids;
for (const chat_id of _ids) {
const data = {
peer: {
chatType: chat_type,
peerUin: chat_id,
},
elements: [
{
elementType: 1,
textElement: {
content: `${this.title}\n\n${this.content}`,
},
},
],
};
const res: any = await got.post(url, {
...this.gotOption,
json: data,
headers,
});
if (res.body === 'success') {
return true;
} else {
throw new Error(res.body);
}
}
}
return false;
} catch (error: any) {
throw new Error(error.response ? error.response.body : error);
}
}

private async webhook() {
const {
webhookUrl,
Expand Down
9 changes: 9 additions & 0 deletions sample/config.sample.sh
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,13 @@ export SMTP_NAME=""
## PUSHME_KEY (必填)填写PushMe APP上获取的push_key
export PUSHME_KEY=""

## 13. CHRONOCAT
## CHRONOCAT_URL 推送 http://127.0.0.1:16530
## CHRONOCAT_TOKEN 填写在CHRONOCAT文件生成的访问密钥
## CHRONOCAT_QQ 个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx
## CHRONOCAT相关API https://chronocat.vercel.app/install/docker/official/
export CHRONOCAT_URL=""
export CHRONOCAT_QQ="" #
export CHRONOCAT_TOKEN=""

## 其他需要的变量,脚本中需要的变量使用 export 变量名= 声明即可
95 changes: 95 additions & 0 deletions sample/notify.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ let SMTP_NAME = '';
//此处填你的PushMe KEY.
let PUSHME_KEY = '';

// =======================================CHRONOCAT通知设置区域===========================================
// CHRONOCAT_URL Red协议连接地址 例: http://127.0.0.1:16530
// CHRONOCAT_TOKEN 填写在CHRONOCAT文件生成的访问密钥
// CHRONOCAT_QQ 个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群
// CHRONOCAT相关API https://chronocat.vercel.app/install/docker/official/
let CHRONOCAT_URL = ''; // CHRONOCAT Red协议连接地址
let CHRONOCAT_TOKEN = ''; //CHRONOCAT 生成的访问密钥
let CHRONOCAT_QQ = ''; // 个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx

//==========================云端环境变量的判断与接收=========================
if (process.env.GOTIFY_URL) {
GOTIFY_URL = process.env.GOTIFY_URL;
Expand Down Expand Up @@ -306,6 +315,16 @@ if (process.env.SMTP_NAME) {
if (process.env.PUSHME_KEY) {
PUSHME_KEY = process.env.PUSHME_KEY;
}

if (process.env.CHRONOCAT_URL) {
CHRONOCAT_URL = process.env.CHRONOCAT_URL;
}
if (process.env.CHRONOCAT_QQ) {
CHRONOCAT_QQ = process.env.CHRONOCAT_QQ;
}
if (process.env.CHRONOCAT_TOKEN) {
CHRONOCAT_TOKEN = process.env.CHRONOCAT_TOKEN;
}
//==========================云端环境变量的判断与接收=========================

/**
Expand Down Expand Up @@ -355,6 +374,7 @@ async function sendNotify(
fsBotNotify(text, desp), //飞书机器人
smtpNotify(text, desp), //SMTP 邮件
PushMeNotify(text, desp, params), //PushMe
ChronocatNotify(text, desp), // Chronocat
]);
}

Expand Down Expand Up @@ -1171,6 +1191,81 @@ function PushMeNotify(text, desp, params = {}) {
});
}

function ChronocatNotify(title, desp) {
return new Promise((resolve) => {
if (!CHRONOCAT_TOKEN || !CHRONOCAT_QQ || !CHRONOCAT_URL) {
console.log(
'CHRONOCAT 服务的 CHRONOCAT_URL 或 CHRONOCAT_QQ 未设置!!\n取消推送',
);
return;
}

console.log('CHRONOCAT 服务启动');
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');
console.log(err);
} else {
data = JSON.parse(data);
if (chat_type === 1) {
console.log(`QQ个人消息:${ids}推送成功!`);
} else {
console.log(`QQ群消息:${ids}推送成功!`);
}
}
} catch (e) {
$.logErr(e, resp);
} finally {
resolve(data);
}
});
}
}
});
}

module.exports = {
sendNotify,
BARK_PUSH,
Expand Down
54 changes: 54 additions & 0 deletions sample/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ def print(text, *args, **kw):
'SMTP_NAME': '', # SMTP 收发件人姓名,可随意填写

'PUSHME_KEY': '', # PushMe 酱的 PUSHME_KEY
'CHRONOCAT_QQ': '', # qq号
'CHRONOCAT_TOKEN': '', # CHRONOCAT 的token
'CHRONOCAT_URL': '' # CHRONOCAT的url地址
}
notify_function = []
# fmt: on
Expand Down Expand Up @@ -664,6 +667,57 @@ def pushme(title: str, content: str) -> None:
else:
print(f"PushMe 推送失败!{response.status_code} {response.text}")

def chronocat(title: str, content: str) -> None:
"""
使用 CHRONOCAT 推送消息。
"""
if not push_config.get("CHRONOCAT_URL") or not push_config.get("CHRONOCAT_QQ") or not push_config.get(
"CHRONOCAT_TOKEN"):
print("CHRONOCAT 服务的 CHRONOCAT_URL 或 CHRONOCAT_QQ 未设置!!\n取消推送")
return

print("CHRONOCAT 服务启动")

user_ids = re.findall(r"user_id=(\d+)", push_config.get("CHRONOCAT_QQ"))
group_ids = re.findall(r"group_id=(\d+)", push_config.get("CHRONOCAT_QQ"))

url = f'{push_config.get("CHRONOCAT_URL")}/api/message/send'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {push_config.get("CHRONOCAT_TOKEN")}'
}

for chat_type, ids in [(1, user_ids), (2, group_ids)]:
if not ids:
continue
for chat_id in ids:
data = {
"peer": {
"chatType": chat_type,
"peerUin": chat_id
},
"elements": [
{
"elementType": 1,
"textElement": {
"content": f'{title}\n\n{content}'
}
}
]
}
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
if chat_type == 1:
print(f'QQ个人消息:{ids}推送成功!')
else:
print(f'QQ群消息:{ids}推送成功!')
else:
if chat_type == 1:
print(f'QQ个人消息:{ids}推送失败!')
else:
print(f'QQ群消息:{ids}推送失败!')



def one() -> str:
"""
Expand Down
Loading

0 comments on commit 5055045

Please sign in to comment.