← back to Ken
src/lib/slack.js
60 lines
const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN || '';
const STEVE_USER_ID = 'U03TV3UC2V7';
async function sendSlackAlert({ type, severity, message, details, channel }) {
const target = channel || STEVE_USER_ID;
const severityEmoji = {
info: ':information_source:',
warning: ':warning:',
critical: ':rotating_light:',
emergency: ':fire:'
};
const blocks = [
{
type: 'section',
text: {
type: 'mrkdwn',
text: `${severityEmoji[severity] || ':robot_face:'} *[Bertha] ${type}*\n${message}`
}
}
];
if (details) {
blocks.push({
type: 'context',
elements: [{
type: 'mrkdwn',
text: typeof details === 'string' ? details : Object.entries(details).map(([k, v]) => `*${k}:* ${v}`).join(' | ')
}]
});
}
if (!SLACK_BOT_TOKEN) {
console.log('[Slack] No token configured - would send:', JSON.stringify({ target, blocks }));
return { ok: false, error: 'no_token' };
}
try {
const res = await fetch('https://slack.com/api/chat.postMessage', {
method: 'POST',
headers: {
'Authorization': `Bearer ${SLACK_BOT_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
channel: target,
text: `[Bertha] ${type}: ${message}`,
blocks
})
});
return await res.json();
} catch (err) {
console.error('[Slack] Send error:', err.message);
return { ok: false, error: err.message };
}
}
module.exports = { sendSlackAlert, STEVE_USER_ID };