Microsoft Team automated notifications
Вопрос: насколько сложно\просто настроить автоматизированые уведомления в Microsoft Teams по сравнению со Slack?
Как по мне так это killer feature которая ну очень user friendly, т.к. по сути даже не нужны никакие скрипты и даже человек отдаленный от инженерии, поковырять рулы в почте сможет что то автоматизировать
Создав канал в teams кликаем по троеточию и выбираем get channel email
В появившемся окошке забираем почтовый адрес этого канала
Идем в почту и отправляем самое обычное письмо на этот адрес - профит
Имхо это очень даже крутой подход, в отрыве от всех притязаний к teams, нужно отдать должное
WebHook
Второй способ чуть ближе к тому с чем сталкиваемся в том же слаке, но при этом и тут он по своему проще
Идем в настройки канала
В самом низу кликаем кнопку Edit в разделе Connections
В появившемся попапе в поиске вводим WebHook и кликаем add или configure
Вводим название, опционально логотип и давим create
Чутка подумав оно обновит страничку и покажет сам webhook
Так же в самом канале появиться уведомление о том что был подключен вебхук
Так, ну и осталось отправить сообщение, с первого попавшегося в сети примера все завелось
curl -X POST 'https://ruaup.webhook.office.com/webhookb2/1893ca41-23b0-4307-b1e7-2f74c899e5fb@695e64b5-2d13-4ea8-bb11-a6fda2d60c41/IncomingWebhook/177657ef132b424cbb6bae18416f8361/57434352-42b0-4090-9d36-9561ae89c607' -H 'Content-Type: application/json' -d '{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Message Text"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
}
]
}'Formatting
Скидываю заготовку пример которой поделился Бартек
curl -X POST 'https://ruaup.webhook.office.com/webhookb2/1893ca41-23b0-4307-b1e7-2f74c899e5fb@695e64b5-2d13-4ea8-bb11-a6fda2d60c41/IncomingWebhook/177657ef132b424cbb6bae18416f8361/57434352-42b0-4090-9d36-9561ae89c607' -H 'Content-Type: application/json' -d '{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0076D7",
"title": "Title goes here",
"text": "Text goes here",
"sections": [
{
"activityTitle": "Section title goes here",
"activitySubtitle": "section subtitle goes here",
"facts": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
},
{
"name": "key3",
"value": "val3"
}
]
}
]
}'Mention
Тут трохи мудреное, по концовке, самый простой и рабочий способ
curl -s -i -X POST 'https://ruaup.webhook.office.com/webhookb2/1893ca41-23b0-4307-b1e7-2f74c899e5fb@695e64b5-2d13-4ea8-bb11-a6fda2d60c41/IncomingWebhook/177657ef132b424cbb6bae18416f8361/57434352-42b0-4090-9d36-9561ae89c607' -H 'Content-Type: application/json' -d '{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Hello <at>alexandrm@rabota.ua</at>"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"msteams": {
"entities": [
{
"type": "mention",
"text": "<at>alexandrm@rabota.ua</at>",
"mentioned": {
"id": "alexandrm@rabota.ua",
"name": "alexandrm@rabota.ua"
}
}
]
}
}
}
]
}'Designer
https://adaptivecards.io/designer/
https://adaptivecards.io/samples/
Эдакий WYSIWYG тул для сообщений Teams
Alertmanager
Пример на что может быть похоже уведомление от alertmanager
const body = {
receiver: "default",
status: "firing",
alerts: [
{
status: "firing",
labels: {
alertname: "demo2",
component: "bar",
severity: "info",
},
annotations: {},
startsAt: "2024-05-13T06:11:03.188793747Z",
endsAt: "0001-01-01T00:00:00Z",
generatorURL: "",
fingerprint: "c8002adfd87cf31c",
},
{
status: "firing",
labels: {
alertname: "demo2",
component: "foo",
severity: "info",
},
annotations: {},
startsAt: "2024-05-13T06:11:03.177669584Z",
endsAt: "0001-01-01T00:00:00Z",
generatorURL: "",
fingerprint: "d31cdf353f33ac5b",
},
],
groupLabels: { alertname: "demo2", severity: "info" },
commonLabels: { alertname: "demo2", severity: "info" },
commonAnnotations: {},
externalURL: "http://eb024ed65dcf:9093",
version: "4",
groupKey: '{}:{alertname="demo2", severity="info"}',
truncatedAlerts: 0,
};
const email =
body?.groupLabels?.annotation_owner ||
body?.commonLabels?.annotation_owner ||
body?.groupLabels?.owner ||
body?.commonLabels?.owner ||
body?.groupLabels?.tag_owner ||
body?.commonLabels?.tag_owner ||
body?.alerts?.[0]?.labels?.annotation_owner ||
body?.alerts?.[0]?.labels?.owner ||
body?.alerts?.[0]?.labels?.tag_owner ||
"alexandrm@rabota.ua"; // ''
const payload = {
type: "message",
attachments: [
{
contentType: "application/vnd.microsoft.card.adaptive",
content: {
$schema: "http://adaptivecards.io/schemas/adaptive-card.json",
version: "1.0",
type: "AdaptiveCard",
body: [
{
type: "TextBlock",
weight: "default",
text: `<at>${email}</at>`,
},
],
msteams: {
entities: [
{
type: "mention",
text: `<at>${email}</at>`,
mentioned: {
id: email,
name: email,
},
},
],
},
},
},
],
};
for (const alert of body.alerts) {
const table = {
type: "Table",
columns: [{ width: 1 }, { width: 1 }],
rows: [],
};
for (const [key, val] of Object.entries(alert.labels)) {
table.rows.push({
type: "TableRow",
cells: [
{
type: "TableCell",
items: [
{
type: "TextBlock",
text: key,
wrap: true,
weight: "default",
},
],
},
{
type: "TableCell",
items: [
{
type: "TextBlock",
text: val,
wrap: true,
weight: key === "alertname" ? "bolder" : "default", // 'bolder'
color: "default", // 'attention', 'good', 'warning' depending on key and val, aka status=firing - attention, severity=warning - warning
},
],
},
],
});
}
payload.attachments[0].content.body.push(table);
const actions = {
type: "ActionSet",
actions: [],
};
if (alert.generatorURL) {
actions.actions.push({
type: "Action.OpenUrl",
title: "prometheus",
url: alert.generatorURL,
});
}
if (body.externalURL) {
actions.actions.push({
type: "Action.OpenUrl",
title: "alertmanager",
url: body.externalURL,
});
actions.actions.push({
type: "Action.OpenUrl",
title: "silence",
url: body.externalURL, // TODO: build silence link
});
}
actions.actions.push({
type: "Action.OpenUrl",
title: "readme",
url: `https://rabota.atlassian.net/wiki/search?spaces=OPS&text=${alert.labels.alertname}`,
});
payload.attachments[0].content.body.push(actions);
}
console.log(JSON.stringify(payload, null, 4));
const res = await fetch(
"https://ruaup.webhook.office.com/webhookb2/1893ca41-23b0-4307-b1e7-2f74c899e5fb@695e64b5-2d13-4ea8-bb11-a6fda2d60c41/IncomingWebhook/177657ef132b424cbb6bae18416f8361/57434352-42b0-4090-9d36-9561ae89c607",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
console.log(res.status); // 200
console.log(res.statusText); // 'OK'
console.log(await res.text()); // '1'
// {{ define "__alert_silence_link" -}}
// {{ .ExternalURL }}/#/silences/new?filter=%7B
// {{- range .CommonLabels.SortedPairs -}}
// {{- if ne .Name "alertname" -}}
// {{- .Name }}%3D"{{- .Value -}}"%2C%20
// {{- end -}}
// {{- end -}}
// alertname%3D"{{- .CommonLabels.alertname -}}"%7D
// {{- end }}
// {{/*
// https://hodovi.cc/blog/creating-awesome-alertmanager-templates-for-slack/
// */}}