mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36: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 webhookUrl: string = '';
|
||||
public webhookMethod: 'GET' | 'POST' | 'PUT' = 'GET';
|
||||
public webhookContentType: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded' = 'application/json';
|
||||
}
|
||||
|
||||
export interface NotificationInfo
|
||||
|
|
|
@ -181,8 +181,7 @@ export default class NotificationService {
|
|||
telegramBotUserId,
|
||||
} = this.params;
|
||||
const authStr = telegramBotProxyAuth ? `${telegramBotProxyAuth}@` : '';
|
||||
const url = `https://${
|
||||
telegramBotApiHost ? telegramBotApiHost : 'api.telegram.org'
|
||||
const url = `https://${telegramBotApiHost ? telegramBotApiHost : 'api.telegram.org'
|
||||
}/bot${telegramBotToken}/sendMessage`;
|
||||
let agent;
|
||||
if (telegramBotProxyHost && telegramBotProxyPort) {
|
||||
|
@ -386,17 +385,32 @@ export default class NotificationService {
|
|||
}
|
||||
|
||||
private async webhook() {
|
||||
const { webhookUrl, webhookBody, webhookHeaders, webhookMethod } =
|
||||
const { webhookUrl, webhookBody, webhookHeaders, webhookMethod, webhookContentType } =
|
||||
this.params;
|
||||
|
||||
const { statusCode } = await got(webhookUrl, {
|
||||
const bodyParam = this.formatBody(webhookContentType, webhookBody);
|
||||
const options = {
|
||||
method: webhookMethod,
|
||||
headers: webhookHeaders,
|
||||
body: webhookBody,
|
||||
timeout: this.timeout,
|
||||
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 { request } from '@/utils/http';
|
||||
import config from '@/utils/config';
|
||||
import { parseBody, parseHeaders } from '@/utils';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
|
@ -12,9 +13,15 @@ const NotificationSetting = ({ data }: any) => {
|
|||
const [form] = Form.useForm();
|
||||
|
||||
const handleOk = (values: any) => {
|
||||
if (values.type == 'closed') {
|
||||
const { type, webhookBody, webhookContentType } = values;
|
||||
if (type == 'closed') {
|
||||
values.type = '';
|
||||
}
|
||||
|
||||
if (type === 'webhook') {
|
||||
values.webhookHeaders = { ...parseHeaders(values.webhookHeaders) };
|
||||
values.webhookBody = parseBody(webhookBody, webhookContentType);
|
||||
}
|
||||
request
|
||||
.put(`${config.apiPrefix}user/notification`, {
|
||||
data: {
|
||||
|
@ -73,10 +80,22 @@ const NotificationSetting = ({ data }: any) => {
|
|||
rules={[{ required: x.required }]}
|
||||
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
|
||||
autoSize={true}
|
||||
placeholder={x.placeholder || `请输入${x.label}`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Form.Item>
|
||||
))}
|
||||
<Button type="primary" htmlType="submit">
|
||||
|
|
|
@ -206,7 +206,7 @@ export default {
|
|||
pushPlus: [
|
||||
{
|
||||
label: 'pushPlusToken',
|
||||
tip: '微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送',
|
||||
tip: '微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
|
@ -228,23 +228,29 @@ export default {
|
|||
label: 'webhookMethod',
|
||||
tip: '请求方法',
|
||||
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',
|
||||
tip: '请求链接',
|
||||
tip: '请求链接以http或者https开头',
|
||||
required: true,
|
||||
placeholder: 'https://xxx.cn/api?query=xxx',
|
||||
placeholder: 'https://xxx.cn/api?query=xxx\n',
|
||||
},
|
||||
{
|
||||
label: 'webhookHeaders',
|
||||
tip: '请求头',
|
||||
placeholder: '{"Custom-Header": "$Header"}',
|
||||
tip: '请求头格式Custom-Header1: Header1,多个换行分割',
|
||||
placeholder: 'Custom-Header1: Header1\nCustom-Header2: Header2',
|
||||
},
|
||||
{
|
||||
label: 'webhookBody',
|
||||
tip: '请求体',
|
||||
placeholder: '{"status": "$STATUS"}',
|
||||
tip: '请求体格式key1: value1,多个换行分割',
|
||||
placeholder: 'key1: value1\nkey2: value2',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -269,3 +269,61 @@ export function depthFirstSearch<
|
|||
console.log(keys);
|
||||
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