mirror of
https://github.com/whyour/qinglong.git
synced 2025-07-13 09:46:06 +08:00
修复自定义通知
This commit is contained in:
parent
5168b044a3
commit
1ebcfd8001
|
@ -95,6 +95,7 @@ export class WebhookNotification extends NotificationBaseInfo {
|
||||||
public webhookBody: any = {};
|
public webhookBody: any = {};
|
||||||
public webhookUrl: string = '';
|
public webhookUrl: string = '';
|
||||||
public webhookMethod: 'GET' | 'POST' | 'PUT' = 'GET';
|
public webhookMethod: 'GET' | 'POST' | 'PUT' = 'GET';
|
||||||
|
public webhookContentType: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded' = 'application/json';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationInfo
|
export interface NotificationInfo
|
||||||
|
|
|
@ -181,8 +181,7 @@ export default class NotificationService {
|
||||||
telegramBotUserId,
|
telegramBotUserId,
|
||||||
} = this.params;
|
} = this.params;
|
||||||
const authStr = telegramBotProxyAuth ? `${telegramBotProxyAuth}@` : '';
|
const authStr = telegramBotProxyAuth ? `${telegramBotProxyAuth}@` : '';
|
||||||
const url = `https://${
|
const url = `https://${telegramBotApiHost ? telegramBotApiHost : 'api.telegram.org'
|
||||||
telegramBotApiHost ? telegramBotApiHost : 'api.telegram.org'
|
|
||||||
}/bot${telegramBotToken}/sendMessage`;
|
}/bot${telegramBotToken}/sendMessage`;
|
||||||
let agent;
|
let agent;
|
||||||
if (telegramBotProxyHost && telegramBotProxyPort) {
|
if (telegramBotProxyHost && telegramBotProxyPort) {
|
||||||
|
@ -386,17 +385,32 @@ export default class NotificationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async webhook() {
|
private async webhook() {
|
||||||
const { webhookUrl, webhookBody, webhookHeaders, webhookMethod } =
|
const { webhookUrl, webhookBody, webhookHeaders, webhookMethod, webhookContentType } =
|
||||||
this.params;
|
this.params;
|
||||||
|
|
||||||
const { statusCode } = await got(webhookUrl, {
|
const bodyParam = this.formatBody(webhookContentType, webhookBody);
|
||||||
|
const options = {
|
||||||
method: webhookMethod,
|
method: webhookMethod,
|
||||||
headers: webhookHeaders,
|
headers: webhookHeaders,
|
||||||
body: webhookBody,
|
|
||||||
timeout: this.timeout,
|
timeout: this.timeout,
|
||||||
retry: 0,
|
retry: 0,
|
||||||
});
|
allowGetBody: true,
|
||||||
|
...bodyParam
|
||||||
|
}
|
||||||
|
const res = await got(webhookUrl, options);
|
||||||
|
return String(res.statusCode).startsWith('20');
|
||||||
|
}
|
||||||
|
|
||||||
return String(statusCode).includes('20');
|
private formatBody(contentType: string, body: any): object {
|
||||||
|
if (!body) return {};
|
||||||
|
switch (contentType) {
|
||||||
|
case 'application/json':
|
||||||
|
return { json: body };
|
||||||
|
case 'multipart/form-data':
|
||||||
|
return { form: body };
|
||||||
|
case 'application/x-www-form-urlencoded':
|
||||||
|
return { body };
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||||
import { Typography, Input, Form, Button, Select, message } from 'antd';
|
import { Typography, Input, Form, Button, Select, message } from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
|
import { parseBody, parseHeaders } from '@/utils';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
@ -12,9 +13,15 @@ const NotificationSetting = ({ data }: any) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const handleOk = (values: any) => {
|
const handleOk = (values: any) => {
|
||||||
if (values.type == 'closed') {
|
const { type, webhookBody, webhookContentType } = values;
|
||||||
|
if (type == 'closed') {
|
||||||
values.type = '';
|
values.type = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'webhook') {
|
||||||
|
values.webhookHeaders = { ...parseHeaders(values.webhookHeaders) };
|
||||||
|
values.webhookBody = parseBody(webhookBody, webhookContentType);
|
||||||
|
}
|
||||||
request
|
request
|
||||||
.put(`${config.apiPrefix}user/notification`, {
|
.put(`${config.apiPrefix}user/notification`, {
|
||||||
data: {
|
data: {
|
||||||
|
@ -73,10 +80,22 @@ const NotificationSetting = ({ data }: any) => {
|
||||||
rules={[{ required: x.required }]}
|
rules={[{ required: x.required }]}
|
||||||
style={{ maxWidth: 400 }}
|
style={{ maxWidth: 400 }}
|
||||||
>
|
>
|
||||||
|
{
|
||||||
|
x.items ? (
|
||||||
|
<Select placeholder={x.placeholder || `请选择${x.label}`}>
|
||||||
|
{x.items.map((y) => (
|
||||||
|
<Option key={y.value} value={y.value}>
|
||||||
|
{y.label || y.value}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
) : (
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
autoSize={true}
|
autoSize={true}
|
||||||
placeholder={x.placeholder || `请输入${x.label}`}
|
placeholder={x.placeholder || `请输入${x.label}`}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
))}
|
))}
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type="primary" htmlType="submit">
|
||||||
|
|
|
@ -206,7 +206,7 @@ export default {
|
||||||
pushPlus: [
|
pushPlus: [
|
||||||
{
|
{
|
||||||
label: 'pushPlusToken',
|
label: 'pushPlusToken',
|
||||||
tip: '微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送',
|
tip: '微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -228,23 +228,29 @@ export default {
|
||||||
label: 'webhookMethod',
|
label: 'webhookMethod',
|
||||||
tip: '请求方法',
|
tip: '请求方法',
|
||||||
required: true,
|
required: true,
|
||||||
placeholder: '请输入 GET/POST/PUT',
|
items: [{ value: 'GET' }, { value: 'POST' }, { value: 'PUT' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'webhookContentType',
|
||||||
|
tip: '请求头Content-Type',
|
||||||
|
required: true,
|
||||||
|
items: [{ value: 'application/json' }, { value: 'multipart/form-data' }, { value: 'application/x-www-form-urlencoded' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'webhookUrl',
|
label: 'webhookUrl',
|
||||||
tip: '请求链接',
|
tip: '请求链接以http或者https开头',
|
||||||
required: true,
|
required: true,
|
||||||
placeholder: 'https://xxx.cn/api?query=xxx',
|
placeholder: 'https://xxx.cn/api?query=xxx\n',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'webhookHeaders',
|
label: 'webhookHeaders',
|
||||||
tip: '请求头',
|
tip: '请求头格式Custom-Header1: Header1,多个换行分割',
|
||||||
placeholder: '{"Custom-Header": "$Header"}',
|
placeholder: 'Custom-Header1: Header1\nCustom-Header2: Header2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'webhookBody',
|
label: 'webhookBody',
|
||||||
tip: '请求体',
|
tip: '请求体格式key1: value1,多个换行分割',
|
||||||
placeholder: '{"status": "$STATUS"}',
|
placeholder: 'key1: value1\nkey2: value2',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -269,3 +269,61 @@ export function depthFirstSearch<
|
||||||
console.log(keys);
|
console.log(keys);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseHeaders(headers: string) {
|
||||||
|
if (!headers) return {};
|
||||||
|
|
||||||
|
const parsed: any = {};
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function parseBody(body: string, contentType: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded') {
|
||||||
|
if (!body) return '';
|
||||||
|
|
||||||
|
const parsed: any = {};
|
||||||
|
let key;
|
||||||
|
let val;
|
||||||
|
let i;
|
||||||
|
|
||||||
|
body && body.split('\n').forEach(function parser(line) {
|
||||||
|
i = line.indexOf(':');
|
||||||
|
key = line.substring(0, i).trim().toLowerCase();
|
||||||
|
val = line.substring(i + 1).trim();
|
||||||
|
|
||||||
|
if (!key || parsed[key]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed[key] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user