| name | meta-ads-collector-adarsh |
| description | Meta Ads Collector Adarsh |
Meta Ads Collector Skill
Purpose
Scans the Meta Ad Library API to find active advertisements for a given brand. Extracts the number of active ads, ad formats used, ad types, and the longest-running ad duration. This collector feeds into the Marketing Audit Pipeline to populate the Paid Ads Strategy section of the final report.
Input Schema
collectMetaAds(brandName: string, domain?: string): Promise<MetaAdsData>
Output Schema
interface MetaAdsData {
activeAds: number;
formatsUsed: string[];
longestRunningAdDays: number;
adTypes: string[];
estimatedSpend?: string;
error?: string;
}
API Dependencies
- API Name: Meta Ad Library API
- Endpoint:
https://graph.facebook.com/v19.0/ads_archive
- Auth:
META_ACCESS_TOKEN environment variable (requires a Facebook App with Ad Library API access)
- Additional env vars:
META_APP_ID, META_APP_SECRET (used for token generation if needed)
- Cost estimate: Free (no per-request charge)
- Rate limits: Subject to Meta's standard Graph API rate limits (~200 calls/hour)
Implementation Pattern
Data Flow
- Receive
brandName and optional domain from the pipeline
- Call
metaAdsService.getMetaAds(brandName, domain) which queries the Ad Library API
- Process the returned ads array to extract metrics
- Map processed data to the
MetaAdsData interface
API Query Parameters
{
access_token: process.env.META_ACCESS_TOKEN,
search_terms: brandName,
ad_reached_countries: "['US']",
ad_active_status: "ACTIVE",
ad_type: "ALL",
fields: "id,ad_creation_time,ad_creative_bodies,ad_creative_link_captions,ad_creative_link_titles,ad_delivery_start_time,ad_snapshot_url,page_name",
limit: 100
}
Metrics Calculation
Active Ads Count:
- Count the total number of ads returned from the API response
Formats Detection:
- Analyze
ad_snapshot_url or creative fields to classify format
- Categories:
"image", "video", "carousel", "dynamic", "collection"
- Deduplicate into a unique list
Longest Running Ad:
const now = new Date();
const longestRunningAdDays = Math.max(
...ads.map(ad => {
const startDate = new Date(ad.ad_delivery_start_time);
return Math.floor((now.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
})
);
Ad Types:
- Extract unique
ad_type values from the response
- Common types:
"POLITICAL_AND_ISSUE_ADS", "HOUSING_ADS", "CREDIT_ADS", "EMPLOYMENT_ADS", general/uncategorized
Estimated Spend:
- Only available for political/issue ads (Meta requirement)
- For other ad types, this field will be
undefined
- If available, format as a range string:
"$10,000 - $50,000"
Domain Filtering
When domain is provided:
- Filter results to only include ads where the creative body, link caption, or link title references the domain
- This improves accuracy for brands with common names
Error Handling
- Entire function wrapped in
try/catch
- On failure, return
EMPTY_META_ADS_DATA with error field set:
return { ...EMPTY_META_ADS_DATA, error: 'Meta Ads data unavailable: <reason>' };
- Never throw -- always return a valid
MetaAdsData object
- Log errors with Winston logger including brandName and error details:
logger.error('Meta Ads collector failed', { brandName, domain, err });
- Common failure scenarios:
- Access token invalid, expired, or lacking Ad Library permissions
- Brand name returns zero results (not necessarily an error -- return zeroed data without error flag)
- Rate limit exceeded (Meta Graph API throttling)
- Network timeout
Example Usage
import { collectMetaAds } from '../collectors/metaAdsCollector';
const data = await collectMetaAds('Gymshark', 'gymshark.com');
const noAds = await collectMetaAds('TinyLocalShop');
const failedData = await collectMetaAds('Gymshark');
Notes
- The collector depends on
metaAdsService.ts for the actual API communication. The collector handles only data aggregation and metric calculation.
- Meta Ad Library API requires a Facebook App registered with Ad Library access. The app must be reviewed and approved by Meta for production use.
- The API only returns publicly available ad data. Spend data is only available for political/issue ads as mandated by Meta's transparency policies.
- Zero active ads is a valid result (small or new brands may not run Meta ads) and should be returned without an error flag.
- The
EMPTY_META_ADS_DATA constant is defined in src/types/audit.types.ts and should be imported for fallback returns.
- This collector must never block the pipeline. Even a complete failure returns valid typed data with an error flag.
- Pagination: the Meta API returns a maximum of 100 results per page. For brands with many ads, pagination via the
after cursor may be needed. For audit purposes, the first page (100 ads) is sufficient.