sfdx-hardis
Version:
Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards
155 lines • 5.84 kB
JavaScript
import c from "chalk";
import { NotifProviderRoot } from "./notifProviderRoot.js";
import { getCurrentGitBranch, uxLog } from "../utils/index.js";
import { UtilsNotifs } from "./utils.js";
import { getEnvVar } from "../../config/index.js";
const ADAPTIVE_CARD_VERSION = "1.0";
const CONTENT_TYPE_ADAPTIVE_CARD = "application/vnd.microsoft.card.adaptive";
const DETAILS_CONTAINER_ID = "detailsContainer";
const ERROR_SEVERITIES = ["critical", "error", "warning"];
const MAIN_ENV_VAR = "MS_TEAMS_WEBHOOK_URL";
const ERRORS_WARNINGS_ENV_VAR = "MS_TEAMS_WEBHOOK_URL_ERRORS_WARNINGS";
export class TeamsProvider extends NotifProviderRoot {
getLabel() {
return "sfdx-hardis MsTeams connector";
}
async postNotification(notifMessage) {
const webhookUrls = await this.getWebhookUrls(notifMessage);
if (webhookUrls.length === 0) {
uxLog("error", this, c.red("[TeamsProvider] MS_TEAMS_WEBHOOK_URL is not defined"));
return;
}
const adaptiveCard = this.buildAdaptiveCard(notifMessage);
const payload = this.buildPayload(adaptiveCard);
await this.sendToWebhooks(webhookUrls, payload);
}
async getWebhookUrls(notifMessage) {
const mainWebhookUrl = getEnvVar(MAIN_ENV_VAR);
if (!mainWebhookUrl) {
return [];
}
const webhookUrls = mainWebhookUrl.split(",");
// Add branch-specific webhook if defined
const currentBranch = await getCurrentGitBranch();
if (currentBranch) {
const branchWebhookVar = `${MAIN_ENV_VAR}_${currentBranch.toUpperCase()}`;
const branchWebhook = getEnvVar(branchWebhookVar);
if (branchWebhook) {
webhookUrls.push(...branchWebhook.split(","));
}
}
// Add errors/warnings webhook if applicable
if (ERROR_SEVERITIES.indexOf(notifMessage.severity) > -1) {
const errorsWebhook = getEnvVar(ERRORS_WARNINGS_ENV_VAR);
if (errorsWebhook) {
webhookUrls.push(...errorsWebhook.split(","));
}
}
return webhookUrls;
}
buildPayload(adaptiveCard) {
return {
attachments: [
{
contentType: CONTENT_TYPE_ADAPTIVE_CARD,
content: adaptiveCard,
},
],
};
}
async sendToWebhooks(webhookUrls, payload) {
for (const webhookUrl of webhookUrls) {
try {
const response = await fetch(webhookUrl.trim(), {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (response.ok) {
uxLog("log", this, c.cyan("[TeamsProvider] Sent Teams notification to webhook"));
}
else {
const errorText = await response.text();
uxLog("error", this, c.grey("[TeamsProvider] Failed Teams message content:\n" + JSON.stringify(payload, null, 2)));
uxLog("error", this, c.red(`[TeamsProvider] Error while sending message to webhook\n${response.status} - ${errorText}`));
}
}
catch (error) {
uxLog("error", this, c.red(`[TeamsProvider] Error while sending message to webhook\n${error.message}`));
}
}
}
buildAdaptiveCard(notifMessage) {
const body = this.buildCardBody(notifMessage);
const actions = this.buildCardActions(notifMessage);
return {
type: "AdaptiveCard",
version: ADAPTIVE_CARD_VERSION,
body,
...(actions && { actions }),
};
}
buildCardBody(notifMessage) {
const messageText = UtilsNotifs.slackToTeamsMarkdown(UtilsNotifs.prefixWithSeverityEmoji(notifMessage.text, notifMessage.severity));
const body = [
{
type: "TextBlock",
text: messageText,
wrap: true,
},
];
// Add collapsible attachments section if present
const attachmentElements = this.buildAttachmentElements(notifMessage);
if (attachmentElements.length > 0) {
body.push(...attachmentElements);
}
return body;
}
buildAttachmentElements(notifMessage) {
if (!notifMessage.attachments?.length) {
return [];
}
const attachmentItems = notifMessage.attachments
.filter((attachment) => attachment.text)
.map((attachment) => ({
type: "TextBlock",
text: UtilsNotifs.slackToTeamsMarkdown(attachment.text),
wrap: true,
}));
if (attachmentItems.length === 0) {
return [];
}
return [
{
type: "Container",
id: DETAILS_CONTAINER_ID,
style: "emphasis",
isVisible: false,
items: attachmentItems,
},
{
type: "ActionSet",
actions: [
{
type: "Action.ToggleVisibility",
title: "Toggle details",
targetElements: [DETAILS_CONTAINER_ID],
},
],
},
];
}
buildCardActions(notifMessage) {
if (!notifMessage.buttons?.length) {
return undefined;
}
return notifMessage.buttons.map((button) => ({
type: "Action.OpenUrl",
title: button.text,
url: button.url,
}));
}
}
//# sourceMappingURL=teamsProvider.js.map