From 7e5ea0cee003acda952d922ca70592f1e8a2ed80 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Wed, 27 Nov 2024 09:50:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89webhook=20contextType=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin-notification/webhook/index.ts | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts b/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts index b32cf808..9e38a41c 100644 --- a/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-notification/webhook/index.ts @@ -1,5 +1,5 @@ import { BaseNotification, IsNotification, NotificationBody, NotificationInput } from '@certd/pipeline'; - +import qs from 'qs'; @IsNotification({ name: 'webhook', title: '自定义webhook', @@ -9,7 +9,10 @@ export class WebhookNotification extends BaseNotification { @NotificationInput({ title: 'webhook地址', component: { - placeholder: '', + placeholder: 'https://xxxxx.com/xxxx', + }, + col: { + span: 24, }, required: true, }) @@ -17,13 +20,14 @@ export class WebhookNotification extends BaseNotification { @NotificationInput({ title: '请求方式', - value: 'post', + value: 'POST', component: { name: 'a-select', - placeholder: 'post/put', + placeholder: 'post/put/get', options: [ - { value: 'post', label: 'post' }, - { value: 'put', label: 'put' }, + { value: 'POST', label: 'POST' }, + { value: 'PUT', label: 'PUT' }, + { value: 'GET', label: 'GET' }, ], }, required: true, @@ -32,14 +36,15 @@ export class WebhookNotification extends BaseNotification { @NotificationInput({ title: 'ContentType', - value: 'json', + value: 'application/json', component: { - name: 'a-select', + name: 'a-auto-complete', options: [ - { value: 'application/json', label: 'json' }, - { value: 'application/x-www-form-urlencoded', label: 'x-www-form-urlencoded' }, + { value: 'application/json', label: 'application/json' }, + { value: 'application/x-www-form-urlencoded', label: 'application/x-www-form-urlencoded' }, ], }, + helper: '也可以自定义填写', required: true, }) contentType = ''; @@ -49,9 +54,12 @@ export class WebhookNotification extends BaseNotification { component: { name: 'a-textarea', vModel: 'value', - rows: 3, + rows: 2, }, - helper: '一行一个,格式为key:value', + col: { + span: 24, + }, + helper: '一行一个,格式为key=value', required: false, }) headers = ''; @@ -69,34 +77,66 @@ export class WebhookNotification extends BaseNotification { col: { span: 24, }, - helper: `根据实际的webhook接口,构建一个json对象作为参数,支持变量:{title}、{content}、{url},变量用{}包裹,字符串需要双引号`, + helper: `根据实际的webhook接口,构建一个json对象作为参数,支持变量:{title}、{content}、{url},变量用{}包裹,字符串需要双引号\n如果是get方式,将作为query参数拼接到url上`, required: true, }) template = ''; + replaceTemplate(target: string, body: any, urlEncode = false) { + let bodyStr = target; + const keys = Object.keys(body); + for (const key of keys) { + const value = urlEncode ? encodeURIComponent(body[key]) : body[key]; + bodyStr = bodyStr.replaceAll(`{${key}}`, value); + } + return bodyStr; + } + async send(body: NotificationBody) { if (!this.template) { throw new Error('模版不能为空'); } + if (!this.webhook) { + throw new Error('webhook不能为空'); + } - const bodyStr = this.template.replaceAll('{title}', body.title).replaceAll('{content}', body.content).replaceAll('{url}', body.url); + const replaceBody = { + title: body.title, + content: body.content, + url: body.url, + }; + const bodyStr = this.replaceTemplate(this.template, replaceBody); + let data = JSON.parse(bodyStr); - const data = JSON.parse(bodyStr); + let url = this.webhook; + if (this.method.toLowerCase() === 'get') { + const query = qs.stringify(data); + if (url.includes('?')) { + url = `${url}&${query}`; + } else { + url = `${url}?${query}`; + } + data = null; + } const headers: any = {}; if (this.headers && this.headers.trim()) { this.headers.split('\n').forEach(item => { item = item.trim(); if (item) { - const [key, value] = item.split(':'); - headers[key] = value; + const arr = item.split('='); + if (arr.length !== 2) { + this.logger.warn('header格式错误,请使用=号', item); + return; + } + headers[arr[0]] = arr[1]; } }); } try { await this.http.request({ - url: this.webhook, + url: url, method: this.method, headers: { 'Content-Type': `${this.contentType}; charset=UTF-8`,