← back to Norma

agents/reddit-agent/server.js

92 lines

/**
 * Norma Reddit Agent — Port 9802
 *
 * Discovers, posts, replies, and monitors Reddit for advocacy topics.
 * Skills: discover, post, reply, monitor, report
 */

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

// 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 = 9802;
const AGENT_NAME = 'reddit-agent';

const { app, start, scheduler } = createAgentServer({
  name: AGENT_NAME,
  port: PORT,
  skills: {
    discover,
    post,
    reply,
    monitor,
    report,
  },
  cronJobs: [
    {
      name: 'monitor-subreddits',
      schedule: '0,30 * * * *', // every 30 minutes
      fn: async () => {
        console.log(`[${AGENT_NAME}] Cron: monitoring subreddits...`);
        try {
          const result = await monitor({ limit: 25, push_to_pulse: true });
          console.log(
            `[${AGENT_NAME}] Cron monitor complete: ${result.total_relevant} relevant posts across ${result.subreddits_monitored} subreddits`
          );
        } catch (err) {
          console.error(`[${AGENT_NAME}] Cron monitor error:`, err.message);
        }
      },
    },
    {
      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);
        }
      },
    },
    {
      name: 'discover-discussions',
      schedule: '20 */3 * * *', // every 3 hours at :20
      fn: async () => {
        console.log(`[${AGENT_NAME}] Cron: discovering new discussions...`);
        try {
          const queries = [
            'nonprofit advocacy',
            'civic engagement',
            'community organizing',
            'policy reform',
            'social impact',
            'grassroots activism',
          ];
          const randomQuery = queries[Math.floor(Math.random() * queries.length)];
          const result = await discover({
            query: randomQuery,
            max_results: 25,
            push_to_pulse: true,
          });
          console.log(
            `[${AGENT_NAME}] Cron discover complete: ${result.total_relevant} relevant posts for "${randomQuery}"`
          );
        } catch (err) {
          console.error(`[${AGENT_NAME}] Cron discover error:`, err.message);
        }
      },
    },
  ],
});

start();