const fs = require('fs'); const path = require('path'); // Auto-load .env file if present const envPath = path.resolve(__dirname, '../.env'); if (fs.existsSync(envPath)) { const envContent = fs.readFileSync(envPath, 'utf8'); envContent.split('\n').forEach(line => { const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)\s*$/); if (match) { const key = match[1]; let value = match[2].trim().replace(/^['"]|['"]$/g, ''); if (!process.env[key]) process.env[key] = value; } }); } const AD_ACCOUNT_ID = process.env.META_AD_ACCOUNT_ID; const ACCESS_TOKEN = process.env.META_ACCESS_TOKEN; const API_VERSION = 'v19.0'; const BASE_URL = `https://graph.facebook.com/${API_VERSION}`; async function apiCall(endpoint, method = 'GET', body = null) { const token = ACCESS_TOKEN; if (!token) { throw new Error('META_ACCESS_TOKEN environment variable is missing.'); } const url = new URL(`${BASE_URL}/${endpoint}`); url.searchParams.append('access_token', token); const options = { method, headers: { 'Content-Type': 'application/json' } }; if (body && method !== 'GET') { options.body = JSON.stringify(body); } const res = await fetch(url.toString(), options); const data = await res.json(); if (data.error) { throw new Error(`Meta API Error [${data.error.code}]: ${data.error.message}`); } return data; } async function getAccountStatus() { const actId = AD_ACCOUNT_ID.startsWith('act_') ? AD_ACCOUNT_ID : `act_${AD_ACCOUNT_ID}`; const data = await apiCall(`${actId}?fields=name,account_status,currency,balance,amount_spent`); return data; } async function getCampaigns() { const actId = AD_ACCOUNT_ID.startsWith('act_') ? AD_ACCOUNT_ID : `act_${AD_ACCOUNT_ID}`; const data = await apiCall(`${actId}/campaigns?fields=id,name,status,objective,daily_budget,lifetime_budget`); return data.data || []; } async function createCampaign({ name, objective = 'OUTCOME_LEADS', dailyBudgetUsd = 10 }) { const actId = AD_ACCOUNT_ID.startsWith('act_') ? AD_ACCOUNT_ID : `act_${AD_ACCOUNT_ID}`; const body = { name, objective, status: 'PAUSED', special_ad_categories: ['NONE'], daily_budget: dailyBudgetUsd * 100 // in cents }; return await apiCall(`${actId}/campaigns`, 'POST', body); } async function main() { const cmd = process.argv[2] || 'status'; try { if (cmd === 'status') { const status = await getAccountStatus(); console.log('Ad Account Status:', JSON.stringify(status, null, 2)); } else if (cmd === 'list-campaigns') { const campaigns = await getCampaigns(); console.log('Campaigns:', JSON.stringify(campaigns, null, 2)); } else { console.log(`Usage: node scripts/meta-ads-manager.js [status|list-campaigns]`); } } catch (err) { console.error('Error:', err.message); } } if (require.main === module) { main(); } module.exports = { apiCall, getAccountStatus, getCampaigns, createCampaign };