Skip to content

feat(meta-ads): add meta ads integration for campaign and ad performance queries#3563

Open
waleedlatif1 wants to merge 9 commits intostagingfrom
waleedlatif1/meta-ads-integration
Open

feat(meta-ads): add meta ads integration for campaign and ad performance queries#3563
waleedlatif1 wants to merge 9 commits intostagingfrom
waleedlatif1/meta-ads-integration

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add Meta Ads integration with 5 tools: get account info, list campaigns, list ad sets, list ads, and get performance insights
  • Add account and campaign selectors with cascading dropdown support (select account → campaigns auto-populate)
  • OAuth configured with minimal ads_read scope for read-only operations
  • Auto-generated docs

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 14, 2026 4:10pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Mar 13, 2026

PR Summary

Medium Risk
Adds a new OAuth provider and token-exchange logic plus new tool endpoints that call the Meta Graph API; failures or misconfiguration could impact credential handling and new API routes, but changes are largely additive.

Overview
Adds a new Meta Ads integration end-to-end: a meta_ads block with OAuth auth, cascading selectors (ad account → campaign), and five new tools to fetch account details, list campaigns/ad sets/ads, and query insights/metrics from the Meta Marketing API.

Introduces supporting infrastructure: new Next.js API routes for selector dropdown data (/api/tools/meta_ads/accounts and /api/tools/meta_ads/campaigns), registers the tools in the tool registry, and wires up a new OAuth provider (meta-ads) including env vars, ads_read scope metadata, and post-connect exchange of short-lived tokens to long-lived tokens.

Updates docs and UI assets by adding MetaAdsIcon, mapping meta_ads to the icon, and generating a new meta_ads docs page (plus a small Grain docs update).

Written by Cursor Bugbot for commit b2bd567. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR adds a complete Meta Ads integration with five read-only tools (get account info, list campaigns, list ad sets, list ads, get performance insights), a block UI with cascading account → campaign selectors, and the supporting OAuth provider registration and long-lived token exchange logic.

Key changes:

  • 5 new tools in tools/meta_ads/ — all follow existing patterns (OAuth header auth, transformResponse, typed outputs)
  • 2 internal API routes (/api/tools/meta_ads/accounts and /api/tools/meta_ads/campaigns) that power the cascading dropdown selectors in the block UI
  • OAuth registration in lib/oauth/oauth.ts with ads_read scope and supportsRefreshTokenRotation: false (correct for Meta's long-lived token model)
  • Long-lived token exchange added to the auth callback in lib/auth/auth.ts — after sign-in, short-lived tokens are immediately exchanged for 60-day tokens via the fb_exchange_token grant
  • accountId added to SelectorContext to enable the campaign selector to depend on the selected account
  • Minor: v24.0 is hardcoded independently in auth.ts and oauth.ts rather than reusing getMetaApiBaseUrl(), and one log label in the accounts route is inaccurate (active vs total count)

Confidence Score: 5/5

Safe to merge — only P2 style findings remain; no functional defects or security issues.

All remaining findings are P2 (minor log label inaccuracy and version-string duplication across lib files). The core integration logic — OAuth flow, long-lived token exchange, cascading selectors, tool dispatch, and error handling — is correct and follows established codebase patterns.

apps/sim/lib/auth/auth.ts and apps/sim/lib/oauth/oauth.ts contain independently-hardcoded v24.0 version strings; apps/sim/app/api/tools/meta_ads/accounts/route.ts has a misleading log label.

Important Files Changed

Filename Overview
apps/sim/tools/meta_ads/types.ts Defines shared param/response interfaces and the getMetaApiBaseUrl()/stripActPrefix() helpers; clean, well-typed, no issues.
apps/sim/tools/meta_ads/get_insights.ts Implements insights query with proper date-preset/custom-range precedence, conversion action aggregation, and error handling; looks correct.
apps/sim/tools/meta_ads/get_account.ts Fetches a single ad-account record with proper field list, auth header, and error fallback output; well-structured.
apps/sim/tools/meta_ads/list_campaigns.ts Lists campaigns with optional status and limit params; correct effective_status encoding and clean response mapping.
apps/sim/tools/meta_ads/list_ad_sets.ts Lists ad sets scoped to account or campaign; correct parent-ID resolution logic, no issues.
apps/sim/tools/meta_ads/list_ads.ts Lists ads with cascading parent-ID selection (ad-set → campaign → account); clean and consistent with other list tools.
apps/sim/app/api/tools/meta_ads/accounts/route.ts Fetches all ad accounts with credential authorisation and token refresh; minor misleading log label (active vs total).
apps/sim/app/api/tools/meta_ads/campaigns/route.ts Fetches campaigns for a given account with proper credential/account-ID validation and token refresh; well-structured.
apps/sim/blocks/blocks/meta_ads.ts Defines the Meta Ads block with cascading account → campaign selectors, date-range UI, and correct tool dispatch via params; canonical IDs wired correctly.
apps/sim/lib/auth/auth.ts Adds post-OAuth callback logic to exchange the Meta short-lived token for a long-lived one; API version v24.0 is duplicated here rather than referencing the shared helper.
apps/sim/lib/oauth/oauth.ts Registers the meta-ads OAuth provider with ads_read scope and correct token endpoint; v24.0 version is hardcoded independently from the types.ts constant.
apps/sim/hooks/selectors/registry.ts Adds meta-ads.accounts and meta-ads.campaigns selectors with correct stale-time, query-key structure, and cascading enabled guards.
apps/sim/hooks/selectors/types.ts Adds meta-ads.accounts and meta-ads.campaigns to SelectorKey union, and accountId to SelectorContext; no issues.

Sequence Diagram

sequenceDiagram
    participant U as User/UI
    participant B as Meta Ads Block
    participant SA as /api/tools/meta_ads/accounts
    participant SC as /api/tools/meta_ads/campaigns
    participant T as Meta Ads Tool
    participant M as graph.facebook.com

    U->>B: Connect OAuth (meta-ads)
    B-->>M: OAuth authorize (ads_read)
    M-->>B: Short-lived token
    B->>M: Exchange for long-lived token (fb_exchange_token)
    M-->>B: Long-lived token (~60 days)

    U->>SA: POST {credential, workflowId}
    SA->>M: GET /me/adaccounts
    M-->>SA: Account list
    SA-->>U: {accounts}

    U->>SC: POST {credential, workflowId, accountId}
    SC->>M: GET /act_{id}/campaigns
    M-->>SC: Campaign list
    SC-->>U: {campaigns}

    U->>T: Execute tool (get_account / list_* / get_insights)
    T->>M: GET /act_{id}/{endpoint}?fields=...
    M-->>T: API response
    T-->>U: Typed output
Loading

Reviews (7): Last reviewed commit: "fix(meta-ads): include onsite_conversion..." | Re-trigger Greptile

…nce queries

- Add 5 tools: get_account, list_campaigns, list_ad_sets, list_ads, get_insights
- Add account and campaign selectors with cascading dropdown support
- Add OAuth config with ads_read scope
- Generate docs
…um date preset to docs

- Pass access token via Authorization header instead of URL query param in getUserInfo, matching all other providers
- Add missing 'maximum' date preset to tool param description and docs
@waleedlatif1 waleedlatif1 force-pushed the waleedlatif1/meta-ads-integration branch from f11f141 to bb8b314 Compare March 14, 2026 13:28
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

Addressing Review Comments

1. crypto.randomUUID() in getUserInfoNot a bug

Every OAuth provider in the codebase uses this exact same ${profile.id}-${crypto.randomUUID()} pattern (Google, Google Ads, Slack, LinkedIn, Asana, etc.). This is an established convention in auth.ts, not a defect specific to Meta Ads.

2. Access token in URL query parameter — Fixed (893bc40)

Moved to Authorization: Bearer header in the getUserInfo fetch call, matching every other provider in the codebase.

3. maximum date preset undocumented — Fixed (893bc40)

Added maximum to the tool's param description in get_insights.ts and to the generated docs in meta_ads.mdx.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

- Use useId() for MetaAdsIcon SVG gradient IDs to prevent collisions when multiple instances render on the same page
- Filter conversions to only count actual conversion action types (offsite_conversion, onsite_conversion, app_custom_event) instead of summing all actions
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile review

…rity, account statuses, DELETED filter

- Add stripActPrefix() helper to prevent act_ double-prefix bug when users provide prefixed IDs
- Clarify totalCount descriptions to indicate response-level count (not total in account)
- Show all ad accounts in selector with status badges instead of silently filtering to active only
- Add DELETED to status filter dropdown options

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

All 4 issues from the Greptile review have been addressed in b339b48:

1. act_ prefix double-prepend bug — Fixed. Added stripActPrefix() helper in types.ts that strips act_ if present before re-prepending. Applied across all 5 tool files and the campaigns API route.

2. Misleading totalCount field — Fixed. Updated descriptions in all 4 list/insights tools to clarify it's the response-level count: "Number of X returned in this response (may be limited by pagination)".

3. Accounts selector silently excludes non-active accounts — Fixed. Now shows all accounts regardless of status. Non-active accounts get a status badge appended to their name (e.g., "My Account (Disabled)", "My Account (Pending Risk Review)").

4. DELETED missing from status dropdown — Fixed. Added DELETED option to the status filter dropdown in the block config.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile review

…th connect

Meta's auth code flow returns a short-lived token (~1-2h) with no refresh token.
Add fb_exchange_token call in account.create.after hook to exchange for a
long-lived token (~60 days), following the same pattern as Salesforce's
post-connect token handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s in conversions

The conversion filter was only matching offsite_conversion.* subtypes but
missing onsite_conversion.* and app_custom_event.* subtypes, which the Meta
API commonly returns at the subtype level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1 waleedlatif1 deleted the branch staging April 3, 2026 23:01
@waleedlatif1 waleedlatif1 reopened this Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant