mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Feat: webhook markdown (#7658)
Add ability to format format event as Markdown in generic webhooks, similar to Datadog integration. Closes https://github.com/Unleash/unleash/issues/7646 Co-authored-by: Nuno Góis <github@nunogois.com>
This commit is contained in:
parent
245c3e119d
commit
369518cd7d
@ -2,6 +2,7 @@ import { TextField, Typography } from '@mui/material';
|
||||
import type { AddonParameterSchema, AddonSchema } from 'openapi';
|
||||
import type { ChangeEventHandler } from 'react';
|
||||
import { styled } from '@mui/material';
|
||||
import { Markdown } from 'component/common/Markdown/Markdown';
|
||||
|
||||
const MASKED_VALUE = '*****';
|
||||
|
||||
@ -62,7 +63,11 @@ export const IntegrationParameterTextField = ({
|
||||
error={Boolean(error)}
|
||||
onChange={setParameterValue(definition.name)}
|
||||
variant='outlined'
|
||||
helperText={definition.description}
|
||||
helperText={
|
||||
definition.description ? (
|
||||
<Markdown>{definition.description}</Markdown>
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -188,6 +188,7 @@
|
||||
"@types/make-fetch-happen": "10.0.4",
|
||||
"@types/memoizee": "0.4.11",
|
||||
"@types/mime": "3.0.4",
|
||||
"@types/mustache": "^4.2.5",
|
||||
"@types/node": "20.14.10",
|
||||
"@types/nodemailer": "6.4.15",
|
||||
"@types/owasp-password-strength-test": "1.3.2",
|
||||
|
8
src/lib/addons/__snapshots__/webhook.test.ts.snap
Normal file
8
src/lib/addons/__snapshots__/webhook.test.ts.snap
Normal file
@ -0,0 +1,8 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Webhook integration should allow for eventJson and eventMarkdown in bodyTemplate 1`] = `
|
||||
"{
|
||||
"json": "{\\"id\\":1,\\"createdAt\\":\\"2024-07-24T00:00:00.000Z\\",\\"createdByUserId\\":-1337,\\"type\\":\\"feature-created\\",\\"createdBy\\":\\"some@user.com\\",\\"featureName\\":\\"some-toggle\\",\\"project\\":\\"default\\",\\"data\\":{\\"name\\":\\"some-toggle\\",\\"enabled\\":false,\\"strategies\\":[{\\"name\\":\\"default\\"}]}}",
|
||||
"markdown": "*some@user.com* created *[some-toggle](http://some-url.com/projects/default/features/some-toggle)* in project *[default](http://some-url.com/projects/default)*"
|
||||
}"
|
||||
`;
|
@ -91,7 +91,7 @@ const webhookDefinition: IAddonDefinition = {
|
||||
"json": {{{eventJson}}}
|
||||
}`,
|
||||
description:
|
||||
"(Optional) You may format the body using a mustache template. If you don't specify anything, the format will similar to the events format (https://docs.getunleash.io/reference/api/legacy/unleash/admin/events). You can use {{{eventJson}}} to include entire serialized event.",
|
||||
'(Optional) You may format the body using a mustache template. If you don\'t specify anything, the format will be similar to the [events format](https://docs.getunleash.io/reference/api/legacy/unleash/admin/events). You can use `{{{eventJson}}}` to include the entire serialized event, or `"{{eventMarkdown}}"` for the formatted description.',
|
||||
type: 'textfield',
|
||||
required: false,
|
||||
sensitive: false,
|
||||
|
@ -112,6 +112,41 @@ describe('Webhook integration', () => {
|
||||
expect(call.options.body).toBe('feature-created on toggle some-toggle');
|
||||
});
|
||||
|
||||
test('should allow for eventJson and eventMarkdown in bodyTemplate', async () => {
|
||||
const addon = new WebhookAddon(ARGS);
|
||||
const event: IEvent = {
|
||||
id: 1,
|
||||
createdAt: new Date('2024-07-24T00:00:00.000Z'),
|
||||
createdByUserId: SYSTEM_USER_ID,
|
||||
type: FEATURE_CREATED,
|
||||
createdBy: 'some@user.com',
|
||||
featureName: 'some-toggle',
|
||||
project: 'default',
|
||||
data: {
|
||||
name: 'some-toggle',
|
||||
enabled: false,
|
||||
strategies: [{ name: 'default' }],
|
||||
},
|
||||
};
|
||||
|
||||
const parameters = {
|
||||
url: 'http://test.webhook.com/plain',
|
||||
bodyTemplate:
|
||||
'{\n "json": {{{eventJson}}},\n "markdown": "{{eventMarkdown}}"\n}',
|
||||
contentType: 'text/plain',
|
||||
};
|
||||
|
||||
addon.handleEvent(event, parameters, INTEGRATION_ID);
|
||||
const call = fetchRetryCalls[0];
|
||||
expect(fetchRetryCalls.length).toBe(1);
|
||||
expect(call.url).toBe(parameters.url);
|
||||
expect(call.options.headers['Content-Type']).toBe('text/plain');
|
||||
expect(call.options.body).toMatchSnapshot();
|
||||
expect(JSON.parse(JSON.parse(call.options.body).json)).toEqual(
|
||||
serializeDates(event),
|
||||
);
|
||||
});
|
||||
|
||||
test('Should format event with "authorization"', () => {
|
||||
const addon = new WebhookAddon(ARGS);
|
||||
const event: IEvent = {
|
||||
|
@ -4,6 +4,11 @@ import definition from './webhook-definition';
|
||||
import type { IEvent } from '../types/events';
|
||||
import { type IAddonConfig, serializeDates } from '../types';
|
||||
import type { IntegrationEventState } from '../features/integration-events/integration-events-store';
|
||||
import {
|
||||
type FeatureEventFormatter,
|
||||
FeatureEventFormatterMd,
|
||||
LinkStyle,
|
||||
} from './feature-event-formatter-md';
|
||||
|
||||
interface IParameters {
|
||||
url: string;
|
||||
@ -14,8 +19,14 @@ interface IParameters {
|
||||
}
|
||||
|
||||
export default class Webhook extends Addon {
|
||||
private msgFormatter: FeatureEventFormatter;
|
||||
|
||||
constructor(args: IAddonConfig) {
|
||||
super(definition, args);
|
||||
this.msgFormatter = new FeatureEventFormatterMd(
|
||||
args.unleashUrl,
|
||||
LinkStyle.MD,
|
||||
);
|
||||
}
|
||||
|
||||
async handleEvent(
|
||||
@ -37,6 +48,7 @@ export default class Webhook extends Addon {
|
||||
event,
|
||||
// Stringify twice to avoid escaping in Mustache
|
||||
eventJson: JSON.stringify(JSON.stringify(event)),
|
||||
eventMarkdown: this.msgFormatter.format(event).text,
|
||||
};
|
||||
|
||||
let body: string | undefined;
|
||||
|
@ -2085,6 +2085,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/mustache@npm:^4.2.5":
|
||||
version: 4.2.5
|
||||
resolution: "@types/mustache@npm:4.2.5"
|
||||
checksum: 10c0/624975c39068d47407eadb89628aaff5ef60f3b7a71eef92a254310896a4e90518a01dcf71d95779ab2c986034a6ca5403d22fea237c67ff87f2e2b3fb794ea6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node-fetch@npm:*":
|
||||
version: 2.6.2
|
||||
resolution: "@types/node-fetch@npm:2.6.2"
|
||||
@ -9759,6 +9766,7 @@ __metadata:
|
||||
"@types/make-fetch-happen": "npm:10.0.4"
|
||||
"@types/memoizee": "npm:0.4.11"
|
||||
"@types/mime": "npm:3.0.4"
|
||||
"@types/mustache": "npm:^4.2.5"
|
||||
"@types/node": "npm:20.14.10"
|
||||
"@types/nodemailer": "npm:6.4.15"
|
||||
"@types/owasp-password-strength-test": "npm:1.3.2"
|
||||
|
Loading…
Reference in New Issue
Block a user