import type { EventSummary, EventTone } from "./summarize";
const SLACK_TEXT_LIMIT = 2900;
const GCHAT_TEXT_LIMIT = 3500;
const DIGEST_MAX_ITEMS = 50;
const SLACK_EMOJI: Record<EventTone, string> = {
good: ":large_green_circle:",
bad: ":red_circle:",
info: ":large_blue_circle:",
neutral: ":white_circle:",
};
const GCHAT_ICON: Record<EventTone, string> = {
good: "STAR",
bad: "BOOKMARK",
info: "DESCRIPTION",
neutral: "DESCRIPTION",
};
/** Slack mrkdwn treats `&`, `<` and `>` as control characters; everything user-authored is escaped. */
export function escapeSlack(text: string): string {
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
}
function slackLink(url: string, label: string): string {
return `<${url.replaceAll("|", "%7C").replaceAll(">", "%3E")}|${escapeSlack(label)}>`;
}
function limit(text: string, max: number): string {
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
}
type SlackBlock = Record<string, unknown>;
export type SlackMessage = { text: string; blocks: SlackBlock[]; unfurl_links: false; unfurl_media: false };
/** Block Kit message: linked title, optional excerpt and fields, repo/actor context, and a "View" button. */
export function slackMessage(summary: EventSummary): SlackMessage {
const heading = `${SLACK_EMOJI[summary.tone]} *${slackLink(summary.url, summary.title)}*`;