webhook 通知 body 增加 text/plain 类型,修复多定时任务服务重启未初始化

This commit is contained in:
whyour 2023-11-22 22:43:48 +08:00
parent f056b611a4
commit de9e9ce627
7 changed files with 29 additions and 19 deletions

View File

@ -61,7 +61,8 @@ export async function getNetIp(req: any) {
...req.ips, ...req.ips,
req.socket.remoteAddress, req.socket.remoteAddress,
]), ]),
]; ].filter(Boolean);
let ip = ipArray[0]; let ip = ipArray[0];
if (ipArray.length > 1) { if (ipArray.length > 1) {
@ -82,6 +83,7 @@ export async function getNetIp(req: any) {
break; break;
} }
} }
ip = ip.substr(ip.lastIndexOf(':') + 1, ip.length); ip = ip.substr(ip.lastIndexOf(':') + 1, ip.length);
if (ip.includes('127.0') || ip.includes('192.168') || ip.includes('10.7')) { if (ip.includes('127.0') || ip.includes('192.168') || ip.includes('10.7')) {
ip = ''; ip = '';
@ -347,9 +349,12 @@ export function parseBody(
contentType: contentType:
| 'application/json' | 'application/json'
| 'multipart/form-data' | 'multipart/form-data'
| 'application/x-www-form-urlencoded', | 'application/x-www-form-urlencoded'
| 'text/plain',
) { ) {
if (!body) return ''; if (contentType === 'text/plain' || !body) {
return body;
}
const parsed: any = {}; const parsed: any = {};
let key; let key;

View File

@ -26,9 +26,9 @@ import omit from 'lodash/omit';
export default class CronService { export default class CronService {
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
private isSixCron(cron: Crontab) { private isNodeCron(cron: Crontab) {
const { schedule } = cron; const { schedule, extra_schedules } = cron;
if (Number(schedule?.split(/ +/).length) > 5) { if (Number(schedule?.split(/ +/).length) > 5 || extra_schedules?.length) {
return true; return true;
} }
return false; return false;
@ -38,7 +38,7 @@ export default class CronService {
const tab = new Crontab(payload); const tab = new Crontab(payload);
tab.saved = false; tab.saved = false;
const doc = await this.insert(tab); const doc = await this.insert(tab);
if (this.isSixCron(doc) || doc.extra_schedules?.length) { if (this.isNodeCron(doc)) {
await cronClient.addCron([ await cronClient.addCron([
{ {
name: doc.name || '', name: doc.name || '',
@ -65,10 +65,10 @@ export default class CronService {
if (doc.isDisabled === 1) { if (doc.isDisabled === 1) {
return newDoc; return newDoc;
} }
if (this.isSixCron(doc) || doc.extra_schedules?.length) { if (this.isNodeCron(doc)) {
await cronClient.delCron([String(doc.id)]); await cronClient.delCron([String(doc.id)]);
} }
if (this.isSixCron(newDoc) || newDoc.extra_schedules?.length) { if (this.isNodeCron(newDoc)) {
await cronClient.addCron([ await cronClient.addCron([
{ {
name: doc.name || '', name: doc.name || '',
@ -472,7 +472,7 @@ export default class CronService {
await CrontabModel.update({ isDisabled: 0 }, { where: { id: ids } }); await CrontabModel.update({ isDisabled: 0 }, { where: { id: ids } });
const docs = await CrontabModel.findAll({ where: { id: ids } }); const docs = await CrontabModel.findAll({ where: { id: ids } });
const sixCron = docs const sixCron = docs
.filter((x) => this.isSixCron(x)) .filter((x) => this.isNodeCron(x))
.map((doc) => ({ .map((doc) => ({
name: doc.name || '', name: doc.name || '',
id: String(doc.id), id: String(doc.id),
@ -613,7 +613,7 @@ export default class CronService {
this.set_crontab(tabs); this.set_crontab(tabs);
const sixCron = tabs.data const sixCron = tabs.data
.filter((x) => this.isSixCron(x) && x.isDisabled !== 1) .filter((x) => this.isNodeCron(x) && x.isDisabled !== 1)
.map((doc) => ({ .map((doc) => ({
name: doc.name || '', name: doc.name || '',
id: String(doc.id), id: String(doc.id),

View File

@ -659,9 +659,11 @@ export default class NotificationService {
webhookUrl, webhookUrl,
webhookBody, webhookBody,
); );
if (!formatUrl && !formatBody) { if (!formatUrl && !formatBody) {
return false; throw new Error('Url 或者 Body 中必须包含 $title')
} }
const headers = parseHeaders(webhookHeaders); const headers = parseHeaders(webhookHeaders);
const body = parseBody(formatBody, webhookContentType); const body = parseBody(formatBody, webhookContentType);
const bodyParam = this.formatBody(webhookContentType, body); const bodyParam = this.formatBody(webhookContentType, body);
@ -692,6 +694,7 @@ export default class NotificationService {
case 'multipart/form-data': case 'multipart/form-data':
return { form: body }; return { form: body };
case 'application/x-www-form-urlencoded': case 'application/x-www-form-urlencoded':
case 'text/plain':
return { body }; return { body };
} }
return {}; return {};

View File

@ -21,8 +21,7 @@ DiskWarn=90
## 设置定时任务执行的超时时间例如1h后缀"s"代表秒(默认值), "m"代表分, "h"代表小时, "d"代表天 ## 设置定时任务执行的超时时间例如1h后缀"s"代表秒(默认值), "m"代表分, "h"代表小时, "d"代表天
CommandTimeoutTime="" CommandTimeoutTime=""
## 在运行 task 命令时,随机延迟启动任务的最大延迟时间 ## 在运行 task 命令时,随机延迟启动任务的最大延迟时间,如 RandomDelay="300" ,表示任务将在 1-300 秒内随机延迟一个秒数,然后再运行,取消延迟赋值为空
## 默认给javascript任务加随机延迟如 RandomDelay="300" ,表示任务将在 1-300 秒内随机延迟一个秒数,然后再运行,取消延迟赋值为空
RandomDelay="" RandomDelay=""
## 需要随机延迟运行任务的文件后缀,直接写后缀名即可,多个后缀用空格分开,例如: js py ts ## 需要随机延迟运行任务的文件后缀,直接写后缀名即可,多个后缀用空格分开,例如: js py ts
@ -33,8 +32,8 @@ RandomDelayFileExtensions=""
## 默认是第0分钟和第30分钟例如21:00或21:30分的任务将会准点运行。不需要准点运行赋值为空 ## 默认是第0分钟和第30分钟例如21:00或21:30分的任务将会准点运行。不需要准点运行赋值为空
RandomDelayIgnoredMinutes="" RandomDelayIgnoredMinutes=""
## 如果你自己会写shell脚本并且希望在每次运行 ql update 命令时,额外运行你的 shell 脚本,请赋值为 "true"默认为true ## 如果你自己会写shell脚本并且希望在每次容器启动时,额外运行你的 shell 脚本,请赋值为 "true"
EnableExtraShell="true" EnableExtraShell=""
## 是否自动启动bot默认不启动设置为true时自动启动目前需要自行克隆bot仓库所需代码存到ql/repo目录下文件夹命名为dockerbot ## 是否自动启动bot默认不启动设置为true时自动启动目前需要自行克隆bot仓库所需代码存到ql/repo目录下文件夹命名为dockerbot
AutoStartBot="" AutoStartBot=""

View File

@ -1350,7 +1350,9 @@ function parseHeaders(headers) {
} }
function parseBody(body, contentType) { function parseBody(body, contentType) {
if (!body) return ''; if (contentType === 'text/plain' || !body) {
return body;
}
const parsed = {}; const parsed = {};
let key; let key;

View File

@ -749,8 +749,8 @@ def parse_headers(headers):
def parse_body(body, content_type): def parse_body(body, content_type):
if not body: if not body or content_type == "text/plain":
return "" return body
parsed = {} parsed = {}
lines = body.split("\n") lines = body.split("\n")

View File

@ -369,6 +369,7 @@ export default {
tip: intl.get('请求头Content-Type'), tip: intl.get('请求头Content-Type'),
required: true, required: true,
items: [ items: [
{ value: 'text/plain' },
{ value: 'application/json' }, { value: 'application/json' },
{ value: 'multipart/form-data' }, { value: 'multipart/form-data' },
{ value: 'application/x-www-form-urlencoded' }, { value: 'application/x-www-form-urlencoded' },