← back to Norma

agents/discord-agent/server.js

73 lines

/**
 * Norma Discord Agent — Port 9803
 *
 * Discovers, posts, replies, and monitors Discord for advocacy topics.
 * Skills: discover, post, reply, monitor, report
 *
 * Note: Discord monitoring is event-driven via Discord.js, not cron-based.
 * The monitor skill manages configuration; the bot handles real-time events.
 */

require('dotenv').config();
const { createAgentServer } = require('../shared/agent-base');
const { initBot } = require('./lib/discord');

// Import skills
const discover = require('./skills/discover');
const post = require('./skills/post');
const reply = require('./skills/reply');
const monitor = require('./skills/monitor');
const report = require('./skills/report');

const PORT = 9803;
const AGENT_NAME = 'discord-agent';

const { app, start, scheduler } = createAgentServer({
  name: AGENT_NAME,
  port: PORT,
  skills: {
    discover,
    post,
    reply,
    monitor,
    report,
  },
  cronJobs: [
    {
      name: 'report-to-pulse',
      schedule: '0 */4 * * *', // every 4 hours
      fn: async () => {
        console.log(`[${AGENT_NAME}] Cron: reporting to Pulse...`);
        try {
          const result = await report({ hours_back: 4 });
          console.log(`[${AGENT_NAME}] Cron report complete`);
        } catch (err) {
          console.error(`[${AGENT_NAME}] Cron report error:`, err.message);
        }
      },
    },
  ],
});

// Initialize Discord bot in the background after server starts
const originalStart = start;
function startWithBot() {
  originalStart();

  // Attempt to connect the Discord bot
  initBot()
    .then((connected) => {
      if (connected) {
        console.log(`[${AGENT_NAME}] Discord bot connected successfully`);
      } else {
        console.log(`[${AGENT_NAME}] Running without Discord bot (no token configured)`);
      }
    })
    .catch((err) => {
      console.error(`[${AGENT_NAME}] Discord bot initialization failed:`, err.message);
      console.log(`[${AGENT_NAME}] Agent will continue running in simulation mode`);
    });
}

startWithBot();