← 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 };