-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Add ad platforms integration example #87040
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: canary
Are you sure you want to change the base?
Add ad platforms integration example #87040
Conversation
This example demonstrates how to integrate multiple advertising and payment platforms into a Next.js application using a unified API client. Features: - AI content generation (Claude/OpenAI) - Google Ads campaign management - Meta Ads (Facebook/Instagram) integration - Stripe payment processing The API client provides a clean, consistent interface for all platforms with proper error handling and TypeScript support.
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a comprehensive example demonstrating integration of multiple advertising and payment platforms (AI content generation, Google Ads, Meta Ads, and Stripe) into a Next.js application. The example provides a unified API client architecture with proper TypeScript support and server-side security through the "server-only" package. The implementation showcases best practices for handling multiple third-party API integrations in a Next.js App Router context.
Key Changes:
- Unified API client architecture with individual service modules for AI content generation (Claude/OpenAI), Google Ads, Meta Ads, and Stripe
- TypeScript type definitions for all platform APIs with proper request/response interfaces
- Demo page showcasing all integrations with environment-based configuration
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
tsconfig.json |
Standard Next.js TypeScript configuration with ES2017 target and path aliases |
tailwind.config.ts |
Standard Tailwind CSS configuration for the example |
postcss.config.js |
PostCSS configuration for Tailwind CSS processing |
package.json |
Dependencies including Next.js, React, and server-only package |
next.config.js |
Next.js configuration with experimental server actions settings |
lib/types.ts |
TypeScript interfaces for all API request/response types |
lib/stripe-client.ts |
Stripe payment processing client with checkout, subscription, and customer management |
lib/meta-ads.ts |
Meta (Facebook/Instagram) Ads API client for campaign management |
lib/google-ads.ts |
Google Ads API client with OAuth token management and campaign operations |
lib/ai-content.ts |
AI content generation supporting both Claude and OpenAI APIs |
lib/api-client.ts |
Unified export module aggregating all service clients |
app/page.tsx |
Demo page showcasing AI content generation and API usage examples |
app/layout.tsx |
Root layout with metadata configuration |
app/globals.css |
Global styles with Tailwind directives |
README.md |
Comprehensive documentation with setup instructions and API examples |
.gitignore |
Standard Next.js gitignore with environment file exclusions |
.env.example |
Template for required environment variables |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async cancelSubscription(subscriptionId: string): Promise<any> { | ||
| return this.request(`/subscriptions/${subscriptionId}`, { | ||
| method: "DELETE", | ||
| }); | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is any, which loses type safety. Consider defining a proper interface for Stripe subscription objects in the types.ts file.
| async createPaymentIntent( | ||
| amount: number, | ||
| currency: string = "usd", | ||
| metadata: Record<string, string> = {} | ||
| ): Promise<any> { | ||
| return this.request("/payment_intents", { | ||
| method: "POST", | ||
| body: { | ||
| amount: Math.round(amount * 100), // Convert to cents | ||
| currency, | ||
| metadata, | ||
| }, | ||
| }); | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is any, which loses type safety. Consider defining a proper interface for Stripe payment intent objects in the types.ts file.
| metadata = {}, | ||
| } = request; | ||
|
|
||
| const session = await this.request<any>("/checkout/sessions", { |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable is named session but typed as any. Since this receives the full Stripe session response, consider typing it properly or using a more descriptive variable name that reflects it's the raw API response.
| const session = await this.request<any>("/checkout/sessions", { | |
| const session = await this.request<CheckoutSession>("/checkout/sessions", { |
| const systemPrompt = buildSystemPrompt(type, tone); | ||
|
|
||
| // Detect if using Claude or OpenAI based on key prefix | ||
| const isClaudeKey = API_KEY.startsWith("sk-ant-"); |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The detection logic for API key type using prefix "sk-ant-" is fragile and could break if Anthropic changes their key format. Consider using an explicit environment variable like AI_PROVIDER to specify which API to use, making the behavior more predictable and maintainable.
| async getPaymentIntent(paymentIntentId: string): Promise<any> { | ||
| return this.request(`/payment_intents/${paymentIntentId}`, { | ||
| method: "GET", | ||
| }); | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is any, which loses type safety. Consider defining a proper interface for Stripe payment intent objects in the types.ts file.
| ); | ||
| } | ||
|
|
||
| const { name, objective, dailyBudget, lifetimeBudget, targetingInterests } = request; |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The targetingInterests parameter is destructured but never used in the function. Either implement the targeting logic or remove this parameter from the interface to avoid confusion.
| const { name, objective, dailyBudget, lifetimeBudget, targetingInterests } = request; | |
| const { name, objective, dailyBudget, lifetimeBudget } = request; |
| const nextConfig = { | ||
| experimental: { | ||
| serverActions: { | ||
| allowedOrigins: ['localhost:3000'], |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The serverActions.allowedOrigins configuration includes 'localhost:3000' without a protocol. This could potentially allow requests from any protocol (http/https) and may not work as intended. Additionally, hardcoding origins in the config is not suitable for production. Consider using environment variables or removing this configuration if not necessary, as Next.js has built-in CSRF protection for server actions.
| allowedOrigins: ['localhost:3000'], |
| ): Promise<any> { | ||
| return this.request("/subscriptions", { | ||
| method: "POST", | ||
| body: { | ||
| customer: customerId, | ||
| items: [{ price: priceId }], | ||
| }, | ||
| }); |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is any, which loses type safety. Consider defining a proper interface for Stripe subscription objects in the types.ts file and using it here to provide better type checking and IDE support.
| async createCustomer(email: string, name?: string): Promise<any> { | ||
| return this.request("/customers", { | ||
| method: "POST", | ||
| body: { | ||
| email, | ||
| name, | ||
| }, | ||
| }); | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type is any, which loses type safety. Consider defining a proper interface for Stripe customer objects in the types.ts file.
Co-authored-by: Copilot <[email protected]>
This example demonstrates how to integrate multiple advertising and payment platforms into a Next.js application using a unified API client.
Features:
The API client provides a clean, consistent interface for all platforms with proper error handling and TypeScript support.