← back to Norma

agents/instagram-agent/skills/report.js

101 lines

/**
 * Instagram Report Skill
 *
 * Generates a summary report of Instagram account activity.
 * Aggregates insights, recent media performance, and engagement metrics.
 * Runs in simulation mode when IG_ACCESS_TOKEN is not set.
 */

const AGENT = 'instagram-agent';
const PLATFORM = 'instagram';

function hasCredentials() {
  return !!(process.env.IG_USER_ID && process.env.IG_ACCESS_TOKEN);
}

/**
 * @param {Object} params - Request body
 * @param {number} [params.hours_back=24] - How many hours back to report
 * @returns {Promise<Object>}
 */
module.exports = async function report(params) {
  const hoursBack = params.hours_back || 24;
  const simulated = !hasCredentials();

  console.log(`[${AGENT}] Report skill invoked — simulation=${simulated}, hours_back=${hoursBack}`);

  if (simulated) {
    // --- Simulation mode: return realistic-looking report ---
    const reportData = {
      agent: AGENT,
      platform: PLATFORM,
      credentials_configured: false,
      period_hours: hoursBack,
      summary: {
        total_posts: Math.floor(Math.random() * 8) + 1,
        total_reels: Math.floor(Math.random() * 3),
        total_stories: Math.floor(Math.random() * 5),
        total_reach: Math.floor(Math.random() * 20000) + 3000,
        total_impressions: Math.floor(Math.random() * 40000) + 8000,
        total_likes: Math.floor(Math.random() * 2000) + 300,
        total_comments: Math.floor(Math.random() * 150) + 20,
        follower_change: Math.floor(Math.random() * 50) - 5,
        top_post: {
          id: `ig_top_${Date.now()}`,
          caption: 'Our petition for accessible education has crossed 50,000 signatures! #EducationForAll',
          media_type: 'IMAGE',
          likes: Math.floor(Math.random() * 300) + 100,
          comments: Math.floor(Math.random() * 50) + 10,
          reach: Math.floor(Math.random() * 5000) + 1000,
        },
      },
      uptime: process.uptime(),
      simulated: true,
      reported_at: new Date().toISOString(),
    };

    console.log(`[${AGENT}] SIMULATED report: posts=${reportData.summary.total_posts}, reach=${reportData.summary.total_reach}`);

    return reportData;
  }

  // --- Real mode: aggregate data from other skills / API ---
  //
  // In real mode, this would:
  // 1. Call the monitor skill to get current insights
  // 2. Call the discover skill to get recent media with engagement
  // 3. Query sdcc_agent_actions for recent actions by this agent
  // 4. Push aggregated report to Pulse via shared/pulse-reporter
  //
  const monitor = require('./monitor');
  const discover = require('./discover');
  const { reportAgentStatus } = require('../../shared/pulse-reporter');
  const { getActionSummary } = require('../../shared/audit-logger');

  const insights = await monitor({ period: 'day' });
  const recentMedia = await discover({ limit: 10 });
  const actionSummary = await getActionSummary(AGENT, hoursBack);

  const reportData = {
    agent: AGENT,
    platform: PLATFORM,
    credentials_configured: true,
    period_hours: hoursBack,
    insights: insights.insights,
    account: insights.account,
    recent_media: recentMedia.media,
    actions: actionSummary,
    uptime: process.uptime(),
    simulated: false,
    reported_at: new Date().toISOString(),
  };

  await reportAgentStatus(AGENT, {
    state: 'running',
    uptime: process.uptime(),
    stats: reportData.insights,
  });

  return reportData;
};