adAccounts.js•7.02 kB
/**
* Ad Accounts routes
* Handles operations related to Facebook ad accounts
*/
const express = require('express');
const router = express.Router();
const { protect, checkFacebookToken } = require('../middleware/auth');
const { validate, schemas } = require('../middleware/validator');
const { sendSuccess, sendError, sendPaginated } = require('../utils/responseFormatter');
const { NotFoundError } = require('../utils/errorTypes');
const AdAccount = require('../models/adAccount');
const facebookApiService = require('../services/facebookApiService');
const logger = require('../utils/logger');
/**
* @route GET /api/ad-accounts
* @desc Get all ad accounts for the current user
* @access Private
*/
router.get('/', protect, async (req, res, next) => {
try {
// Get pagination parameters
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const skip = (page - 1) * limit;
// Get ad accounts from database
const adAccounts = await AdAccount.find({ userId: req.user._id })
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit);
// Get total count
const total = await AdAccount.countDocuments({ userId: req.user._id });
return sendPaginated(res, adAccounts, page, limit, total, 'Ad accounts retrieved successfully');
} catch (error) {
logger.error(`Error retrieving ad accounts: ${error.message}`);
return next(error);
}
});
/**
* @route GET /api/ad-accounts/sync
* @desc Sync ad accounts from Facebook
* @access Private
*/
router.get('/sync', protect, checkFacebookToken, async (req, res, next) => {
try {
// Create Facebook API service
const fbApi = await facebookApiService.createForUser(req.user);
// Get ad accounts from Facebook
const fbAdAccounts = await fbApi.getAdAccounts();
// Process and save ad accounts
const savedAccounts = [];
for (const fbAccount of fbAdAccounts) {
// Find existing account or create new one
let adAccount = await AdAccount.findOne({
accountId: fbAccount.account_id,
userId: req.user._id
});
if (!adAccount) {
adAccount = new AdAccount({
accountId: fbAccount.account_id,
userId: req.user._id
});
}
// Update account details
adAccount.name = fbAccount.name;
adAccount.currency = fbAccount.currency;
adAccount.timezone = fbAccount.timezone_name;
adAccount.status = fbAccount.account_status === 1 ? 'ACTIVE' : 'DISABLED';
adAccount.spendCap = fbAccount.spend_cap;
adAccount.balance = fbAccount.balance;
adAccount.businessName = fbAccount.business_name;
adAccount.businessId = fbAccount.business_id;
adAccount.businessCity = fbAccount.business_city;
adAccount.businessCountryCode = fbAccount.business_country_code;
adAccount.capabilities = fbAccount.capabilities || [];
adAccount.lastSyncedAt = new Date();
// Save account
await adAccount.save();
savedAccounts.push(adAccount);
}
return sendSuccess(res, savedAccounts, 'Ad accounts synced successfully');
} catch (error) {
logger.error(`Error syncing ad accounts: ${error.message}`);
return next(error);
}
});
/**
* @route GET /api/ad-accounts/:id
* @desc Get ad account by ID
* @access Private
*/
router.get('/:id', protect, validate(schemas.idParam, 'params'), async (req, res, next) => {
try {
// Get ad account from database
const adAccount = await AdAccount.findOne({
accountId: req.params.id,
userId: req.user._id
});
if (!adAccount) {
return next(new NotFoundError('Ad account not found'));
}
return sendSuccess(res, adAccount, 'Ad account retrieved successfully');
} catch (error) {
logger.error(`Error retrieving ad account: ${error.message}`);
return next(error);
}
});
/**
* @route GET /api/ad-accounts/:id/insights
* @desc Get insights for an ad account
* @access Private
*/
router.get('/:id/insights', protect, checkFacebookToken, validate(schemas.idParam, 'params'), async (req, res, next) => {
try {
// Get ad account from database
const adAccount = await AdAccount.findOne({
accountId: req.params.id,
userId: req.user._id
});
if (!adAccount) {
return next(new NotFoundError('Ad account not found'));
}
// Create Facebook API service
const fbApi = await facebookApiService.createForUser(req.user);
// Get time range from query params
const timeRange = req.query.timeRange || 'last_30_days';
// Get insights from Facebook
const insights = await fbApi.getInsights(`act_${adAccount.accountId}`, timeRange, [], {
level: 'account'
});
return sendSuccess(res, insights, 'Ad account insights retrieved successfully');
} catch (error) {
logger.error(`Error retrieving ad account insights: ${error.message}`);
return next(error);
}
});
/**
* @route GET /api/ad-accounts/:id/campaigns
* @desc Get campaigns for an ad account
* @access Private
*/
router.get('/:id/campaigns', protect, checkFacebookToken, validate(schemas.idParam, 'params'), async (req, res, next) => {
try {
// Get ad account from database
const adAccount = await AdAccount.findOne({
accountId: req.params.id,
userId: req.user._id
});
if (!adAccount) {
return next(new NotFoundError('Ad account not found'));
}
// Create Facebook API service
const fbApi = await facebookApiService.createForUser(req.user);
// Get campaigns from Facebook
const campaigns = await fbApi.getCampaigns(adAccount.accountId);
return sendSuccess(res, campaigns, 'Ad account campaigns retrieved successfully');
} catch (error) {
logger.error(`Error retrieving ad account campaigns: ${error.message}`);
return next(error);
}
});
/**
* @route GET /api/ad-accounts/:id/status
* @desc Get ad account status
* @access Private
*/
router.get('/:id/status', protect, validate(schemas.idParam, 'params'), async (req, res, next) => {
try {
// Get ad account from database
const adAccount = await AdAccount.findOne({
accountId: req.params.id,
userId: req.user._id
});
if (!adAccount) {
return next(new NotFoundError('Ad account not found'));
}
// Get status information
const status = {
accountId: adAccount.accountId,
name: adAccount.name,
status: adAccount.status,
currency: adAccount.currency,
timezone: adAccount.timezone,
spendCap: adAccount.spendCap,
balance: adAccount.balance,
lastSyncedAt: adAccount.lastSyncedAt
};
return sendSuccess(res, status, 'Ad account status retrieved successfully');
} catch (error) {
logger.error(`Error retrieving ad account status: ${error.message}`);
return next(error);
}
});
module.exports = router;