← back to Norma

agents/facebook-agent/skills/discover.js

85 lines

/**
 * Facebook Discover Skill
 *
 * Fetches trending/recent posts from the Facebook Page.
 * Runs in simulation mode when FB_PAGE_ACCESS_TOKEN is not set.
 *
 * Real endpoint:
 *   GET https://graph.facebook.com/v19.0/{page_id}/feed
 *   Params: fields=id,message,created_time,shares,likes.summary(true),comments.summary(true)&limit=N&access_token=TOKEN
 */

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

function hasCredentials() {
  return !!(process.env.FB_PAGE_ID && process.env.FB_PAGE_ACCESS_TOKEN);
}

/**
 * @param {Object} params - Request body
 * @param {number} [params.limit=10] - Number of posts to fetch
 * @param {boolean} [params.push_to_pulse=true] - Push results to Pulse
 * @returns {Promise<Object>}
 */
module.exports = async function discover(params) {
  const limit = Math.min(params.limit || 10, 100);
  const simulated = !hasCredentials();

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

  if (simulated) {
    // --- Simulation mode: return realistic-looking data ---
    const posts = Array.from({ length: Math.min(limit, 5) }, (_, i) => ({
      id: `fb_post_${Date.now()}_${i}`,
      message: [
        'Every voice matters in the fight for civic change. Sign our latest petition today!',
        'Your community needs you. Take 2 minutes to make a real difference.',
        'Breaking: New advocacy campaign launched. Learn how you can help.',
        'Thank you to everyone who signed last week — over 5,000 signatures strong!',
        'Policy update: Here is what our collective action has achieved so far.',
      ][i],
      created_time: new Date(Date.now() - i * 3600000).toISOString(),
      shares: { count: Math.floor(Math.random() * 50) },
      likes: { summary: { total_count: Math.floor(Math.random() * 200) } },
      comments: { summary: { total_count: Math.floor(Math.random() * 30) } },
    }));

    console.log(`[${AGENT}] SIMULATED discover: ${posts.length} posts`);

    return {
      count: posts.length,
      posts,
      simulated: true,
      platform: PLATFORM,
      fetched_at: new Date().toISOString(),
    };
  }

  // --- Real API call (commented out until credentials are configured) ---
  //
  // const pageId = process.env.FB_PAGE_ID;
  // const accessToken = process.env.FB_PAGE_ACCESS_TOKEN;
  //
  // const fields = 'id,message,created_time,shares,likes.summary(true),comments.summary(true)';
  // const url = `https://graph.facebook.com/v19.0/${pageId}/feed?fields=${fields}&limit=${limit}&access_token=${accessToken}`;
  //
  // const response = await fetch(url);
  // const data = await response.json();
  //
  // if (data.error) {
  //   throw new Error(`Facebook API error: ${data.error.message}`);
  // }
  //
  // return {
  //   count: data.data.length,
  //   posts: data.data,
  //   paging: data.paging || null,
  //   simulated: false,
  //   platform: PLATFORM,
  //   fetched_at: new Date().toISOString(),
  // };

  return { error: 'Real API call not yet enabled. Uncomment the code above.' };
};