Skip to content

Commit ccddfb0

Browse files
authored
Add Mattermost as a notification channel destination (#416)
Signed-off-by: Craig Perkins <cwperx@amazon.com>
1 parent 828cd9d commit ccddfb0

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

common/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const BACKEND_CHANNEL_TYPE = Object.freeze({
55
MICROSOFT_TEAMS: 'microsoft_teams',
66
CUSTOM_WEBHOOK: 'webhook',
77
SNS: 'sns',
8+
MATTERMOST: 'mattermost',
89
});
910
export const CHANNEL_TYPE = Object.freeze({
1011
[BACKEND_CHANNEL_TYPE.SLACK]: 'Slack',
@@ -13,11 +14,13 @@ export const CHANNEL_TYPE = Object.freeze({
1314
[BACKEND_CHANNEL_TYPE.MICROSOFT_TEAMS]: 'Microsoft Teams',
1415
[BACKEND_CHANNEL_TYPE.CUSTOM_WEBHOOK]: 'Custom webhook',
1516
[BACKEND_CHANNEL_TYPE.SNS]: 'Amazon SNS',
17+
[BACKEND_CHANNEL_TYPE.MATTERMOST]: 'Mattermost',
1618
}) as {
1719
slack: string;
1820
email: string;
1921
chime: string;
2022
microsoft_teams: string;
2123
webhook: string;
2224
sns: string;
25+
mattermost: string;
2326
};

models/interfaces.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export interface ChannelItemType extends ConfigType {
3636
slack?: {
3737
url: string;
3838
};
39+
mattermost?: {
40+
url: string;
41+
};
3942
chime?: {
4043
url: string;
4144
};

public/pages/CreateChannel/CreateChannel.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { MicrosoftTeamsSettings } from './components/MicrosoftTeamsSettings';
3939
import { CustomWebhookSettings } from './components/CustomWebhookSettings';
4040
import { EmailSettings } from './components/EmailSettings';
4141
import { SlackSettings } from './components/SlackSettings';
42+
import { MattermostSettings } from './components/MattermostSettings';
4243
import { SNSSettings } from './components/SNSSettings';
4344
import {
4445
constructEmailObject,
@@ -95,6 +96,7 @@ export function CreateChannel(props: CreateChannelsProps) {
9596
const [channelType, setChannelType] = useState(channelTypeOptions[0].value);
9697

9798
const [slackWebhook, setSlackWebhook] = useState('');
99+
const [mattermostWebhook, setMattermostWebhook] = useState('');
98100
const [chimeWebhook, setChimeWebhook] = useState('');
99101
const [microsoftTeamsWebhook, setMicrosoftTeamsWebhook] = useState('');
100102

@@ -130,6 +132,7 @@ export function CreateChannel(props: CreateChannelsProps) {
130132
const [inputErrors, setInputErrors] = useState<InputErrorsType>({
131133
name: [],
132134
slackWebhook: [],
135+
mattermostWebhook: [],
133136
chimeWebhook: [],
134137
microsoftTeamsWebhook: [],
135138
smtpSender: [],
@@ -197,6 +200,8 @@ export function CreateChannel(props: CreateChannelsProps) {
197200

198201
if (type === BACKEND_CHANNEL_TYPE.SLACK) {
199202
setSlackWebhook(response.slack?.url || '');
203+
} else if (type === BACKEND_CHANNEL_TYPE.MATTERMOST) {
204+
setMattermostWebhook(response.mattermost?.url || '');
200205
} else if (type === BACKEND_CHANNEL_TYPE.CHIME) {
201206
setChimeWebhook(response.chime?.url || '');
202207
} else if (type === BACKEND_CHANNEL_TYPE.MICROSOFT_TEAMS) {
@@ -249,6 +254,8 @@ export function CreateChannel(props: CreateChannelsProps) {
249254
};
250255
if (channelType === BACKEND_CHANNEL_TYPE.SLACK) {
251256
errors.slackWebhook = validateWebhookURL(slackWebhook);
257+
} else if (channelType === BACKEND_CHANNEL_TYPE.MATTERMOST) {
258+
errors.mattermostWebhook = validateWebhookURL(mattermostWebhook);
252259
} else if (channelType === BACKEND_CHANNEL_TYPE.CHIME) {
253260
errors.chimeWebhook = validateWebhookURL(chimeWebhook);
254261
} else if (channelType === BACKEND_CHANNEL_TYPE.MICROSOFT_TEAMS) {
@@ -288,6 +295,8 @@ export function CreateChannel(props: CreateChannelsProps) {
288295
};
289296
if (channelType === BACKEND_CHANNEL_TYPE.SLACK) {
290297
config.slack = { url: slackWebhook };
298+
} else if (channelType === BACKEND_CHANNEL_TYPE.MATTERMOST) {
299+
config.mattermost = { url: mattermostWebhook };
291300
} else if (channelType === BACKEND_CHANNEL_TYPE.CHIME) {
292301
config.chime = { url: chimeWebhook };
293302
} else if (channelType === BACKEND_CHANNEL_TYPE.MICROSOFT_TEAMS) {
@@ -422,6 +431,11 @@ export function CreateChannel(props: CreateChannelsProps) {
422431
slackWebhook={slackWebhook}
423432
setSlackWebhook={setSlackWebhook}
424433
/>
434+
) : channelType === BACKEND_CHANNEL_TYPE.MATTERMOST ? (
435+
<MattermostSettings
436+
mattermostWebhook={mattermostWebhook}
437+
setMattermostWebhook={setMattermostWebhook}
438+
/>
425439
) : channelType === BACKEND_CHANNEL_TYPE.CHIME ? (
426440
<ChimeSettings
427441
chimeWebhook={chimeWebhook}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { EuiCompressedFieldText, EuiCompressedFormRow } from '@elastic/eui';
7+
import React, { useContext } from 'react';
8+
import { CreateChannelContext } from '../CreateChannel';
9+
import { validateWebhookURL } from '../utils/validationHelper';
10+
11+
interface MattermostSettingsProps {
12+
mattermostWebhook: string;
13+
setMattermostWebhook: (url: string) => void;
14+
}
15+
16+
export function MattermostSettings(props: MattermostSettingsProps) {
17+
const context = useContext(CreateChannelContext)!;
18+
19+
return (
20+
<EuiCompressedFormRow
21+
label="Mattermost webhook URL"
22+
style={{ maxWidth: '700px' }}
23+
error={context.inputErrors.mattermostWebhook.join(' ')}
24+
isInvalid={context.inputErrors.mattermostWebhook.length > 0}
25+
>
26+
<EuiCompressedFieldText
27+
fullWidth
28+
data-test-subj="create-channel-mattermost-webhook-input"
29+
placeholder="https://your-mattermost-server.com/hooks/xxx-generatedkey-xxx"
30+
value={props.mattermostWebhook}
31+
onChange={(e) => props.setMattermostWebhook(e.target.value)}
32+
isInvalid={context.inputErrors.mattermostWebhook.length > 0}
33+
onBlur={() => {
34+
context.setInputErrors({
35+
...context.inputErrors,
36+
mattermostWebhook: validateWebhookURL(props.mattermostWebhook),
37+
});
38+
}}
39+
/>
40+
</EuiCompressedFormRow>
41+
);
42+
}

0 commit comments

Comments
 (0)