🔍 Bing Ads Integration
🎯 Overview
Microsoft Advertising (formerly Bing Ads) integration providing programmatic access to search advertising campaigns through SOAP-based web services. Supports OAuth 2.0 authentication, campaign management, ad groups, ads, keywords, and comprehensive performance reporting with automatic token refresh.
Provider: Microsoft Advertising (https://ads.microsoft.com)
API Version: v13 (SOAP Web Services)
Integration Type: OAuth 2.0 + SOAP XML Protocol
📖 Documentation Structure
This integration is organized into the following sections:
- Authentication - OAuth 2.0 flow with automatic token refresh middleware
- Accounts - Manager accounts and accessible user accounts
- Campaigns - Campaign operations, metrics, and status management
- Ad Groups - Ad group management and targeting
- Ads - Ad operations by type (expanded text, responsive, etc.)
- Keywords - Keyword management and quality scores
- Reports - Async report generation and download
✨ Features
- ✅ SOAP Protocol: XML-based web services for Microsoft Advertising API
- ✅ OAuth 2.0 Authentication: Secure authorization with automatic token refresh
- ✅ Token Refresh Middleware: Automatic access token renewal using refresh tokens
- ✅ Manager Accounts (MCC): Support for Microsoft Advertising MCC hierarchy
- ✅ Campaign Management: Full CRUD operations on campaigns, ad groups, ads
- ✅ Keyword Management: Keyword bidding, quality scores, and performance
- ✅ Multiple Ad Types: Support for ExpandedText, Responsive, Dynamic Search, etc.
- ✅ Async Reporting: Generate and download performance reports
- ✅ Aggregation Timeframes: Daily, weekly, monthly, and custom date ranges
- ✅ Editorial Status: Filter by ad approval status
🏗️ Architecture
sequenceDiagram
participant Client as DashClicks App
participant Controller as Bing Controller
participant Middleware as Token Middleware
participant DB as MongoDB
participant SOAP as SOAP Client
participant Bing as Bing Ads API
Client->>Controller: API Request (JWT)
Controller->>Middleware: Check/refresh token
Middleware->>DB: Fetch token document
DB-->>Middleware: Return token + generated_at
alt Token Expired
Middleware->>Bing: POST /oauth2/v2.0/token
Note over Middleware,Bing: Refresh token grant
Bing-->>Middleware: New access token
Middleware->>DB: Update token document
end
Middleware-->>Controller: Valid access token
Controller->>SOAP: Build SOAP XML request
SOAP->>Bing: SOAP Web Service Call
Bing-->>SOAP: SOAP XML Response
SOAP->>SOAP: Parse XML to JSON
SOAP-->>Controller: JSON data
Controller-->>Client: Formatted response
🗄️ MongoDB Collections
📚 Detailed Schema: See Database Collections Documentation
bing.ads.tokens
Purpose: Store OAuth 2.0 tokens with automatic refresh capability
Model: shared/models/bing-ads-token.js
Key Fields:
account_id(ObjectId, required, indexed) - DashClicks account referenceuid(ObjectId, required, indexed) - DashClicks user referenceoauth(Object) - Full OAuth response from Microsoftaccess_token(String) - Bearer token for API requestsrefresh_token(String) - Token for automatic renewalexpires_in(Number) - Token lifetime in seconds (3600)token_type(String) - "Bearer"scope(String) - OAuth scopes grantedgenerated_at(Number) - Unix timestamp of token generation
createdAt(Date) - Document creation timestampupdatedAt(Date) - Last update timestamp
Indexes:
{ account_id: 1 }- Account-based queries{ uid: 1 }- User-based queries
Schema Type: strict: false - Allows flexible OAuth response storage
📁 Directory Structure
Source Code Location:
external/Integrations/BingAds/
├── Controllers/
│ ├── Auth/
│ │ └── AuthController.js # OAuth authentication
│ ├── Accounts/
│ │ └── AccountsController.js # Account operations
│ ├── Campaigns/
│ │ └── CampaignController.js # Campaign management
│ ├── Adgroups/
│ │ └── AdGroupController.js # Ad group operations
│ ├── Ads/
│ │ └── AdsController.js # Ad management
│ ├── Keywords/
│ │ └── KeyWordsController.js # Keyword operations
│ └── Reports/
│ └── ReportsController.js # Report generation
├── Models/
│ ├── token.js # Token CRUD operations
│ ├── Accounts/
│ │ └── AccountsModel.js # Account SOAP logic
│ ├── Campaigns/
│ │ └── CampaignsModel.js # Campaign SOAP logic
│ ├── AdGroups/
│ │ └── AdGroupsModel.js # AdGroup SOAP logic
│ ├── Ads/
│ │ └── AdsModel.js # Ads SOAP logic
│ ├── Keywords/
│ │ └── KeywordsModel.js # Keyword SOAP logic
│ └── Reports/
│ └── ReportsModel.js # Reports SOAP logic
├── Middleware/
│ └── getToken.js # Auto token refresh middleware
├── Routes/
│ └── index.js # Express route definitions
└── SoapClient.js # SOAP XML parser/client
Shared Models Used:
shared/models/bing-ads-token.js- OAuth token storage
🔐 Authentication & Configuration
Authentication Method: OAuth 2.0 Authorization Code Flow
Required Environment Variables:
| Variable | Description | Required |
|---|---|---|
BING_ADS_CLIENT_ID | Microsoft Azure app client ID | ✅ |
BING_CLIENT_SECRET | Microsoft Azure app secret | ✅ |
BING_ADS_REDIRECT_URL | OAuth callback URL | ✅ |
BING_ADS_CALLBACK_REDIRECT_URL | Frontend redirect after OAuth | ✅ |
BING_ADS_DEVELOPER_TOKEN | Microsoft Ads developer token | ✅ |
JWT_SECRET | JWT state token signing secret | ✅ |
OAuth Scopes: openid offline_access https://ads.microsoft.com/ads.manage
Developer Token:
- Sandbox:
BBD37VB98 - Production: Obtain from Microsoft Advertising Developer Portal
🚀 Quick Start
1. Configure Environment Variables
BING_ADS_CLIENT_ID=your_client_id
BING_CLIENT_SECRET=your_client_secret
BING_ADS_REDIRECT_URL=https://api.dashclicks.com/v1/integrations/bing/ads/auth/callback
BING_ADS_CALLBACK_REDIRECT_URL=https://app.dashclicks.com/integrations
BING_ADS_DEVELOPER_TOKEN=your_production_token
JWT_SECRET=your_jwt_secret
2. Initiate OAuth Flow
GET /v1/integrations/bing/ads/auth/login?forward_url=https://app.dashclicks.com/integrations
Authorization: Bearer {jwt_token}
3. List Manager Accounts
GET /v1/integrations/bing/ads/accounts/managers
Authorization: Bearer {jwt_token}
4. List User Accounts
GET /v1/integrations/bing/ads/accounts/users?customerID=12345678
Authorization: Bearer {jwt_token}
5. List Campaigns
GET /v1/integrations/bing/ads/campaigns?customerAccountID=98765432&customerID=12345678&campaignType=Search
Authorization: Bearer {jwt_token}
6. Get Campaign Metrics
GET /v1/integrations/bing/ads/campaigns/metrics?customerAccountID=98765432&aggregation=Monthly&predefinedTime=Last30Days
Authorization: Bearer {jwt_token}
📊 API Endpoints Summary
| Method | Endpoint | Description |
|---|---|---|
| GET | /auth/login | Initiate OAuth 2.0 flow |
| GET | /auth/callback | Handle OAuth callback |
| DELETE | /auth/:id | Delete OAuth token |
| GET | /accounts/managers | List manager accounts (MCC) |
| GET | /accounts/users | List accessible user accounts |
| GET | /campaigns | List campaigns |
| GET | /campaigns/show | Show single campaign |
| GET | /campaigns/metrics | Get campaign performance metrics |
| GET | /adgroups | List ad groups |
| GET | /adgroups/show | Show single ad group |
| GET | /adgroups/metrics | Get ad group metrics |
| GET | /ads | List ads |
| GET | /ads/show | Show single ad |
| GET | /ads/metrics | Get ad metrics |
| GET | /keywords | List keywords |
| GET | /keywords/show | Show single keyword |
| GET | /keywords/metrics | Get keyword metrics |
| GET | /reports/download | Download generated report |
🔄 Token Auto-Refresh Flow
Middleware: Middleware/getToken.js
Process:
- Every request passes through token middleware
- Middleware fetches token from MongoDB
- Checks if token expired (compares
generated_at+ 3600 seconds) - If expired:
- Calls Microsoft token endpoint with refresh token
- Updates MongoDB with new access token and
generated_at - Sets new token on
req.access_token
- If valid, passes token to controller
- If no token exists, returns error: "oauth token not found. Please redirect to login"
Token Lifetime: 3600 seconds (1 hour)
🎯 Campaign Types
Bing Ads supports multiple campaign types:
- Search - Text ads on Bing search results
- Shopping - Product listing ads
- DynamicSearchAds - Auto-generated search ads
Filter by Type: Use comma-separated values: campaignType=Search,Shopping
📈 Aggregation Timeframes
Supported Values:
Today,YesterdayLastSevenDays,Last14Days,Last30DaysThisWeek,LastWeek,LastFourWeeksThisMonth,LastMonthLastThreeMonths,LastSixMonthsThisYear,LastYearWeekly,Monthly,Summary
Default: Last30Days
🌍 Timezone Options
Default: EasternTimeUSCanada
Full List: See Microsoft Ads ReportTimeZone Reference
🎨 Ad Types
Supported Ad Types:
Text- Basic text ads (legacy)ExpandedText- Expanded text ads (default)ResponsiveSearch- Responsive search adsResponsiveAd- Display responsive adsImage- Image adsProduct- Shopping product adsAppInstall- Mobile app install adsDynamicSearch- Dynamic search ads
Reference: Microsoft Ads AdType Documentation
🚨 Error Handling
Common Error Scenarios:
| Error | Cause | Solution |
|---|---|---|
oauth token not found | No token in database | Redirect to OAuth login |
| Token expired | Access token > 1 hour old | Auto-refreshed by middleware |
customerAccountID is required | Missing required parameter | Provide account ID |
Please provide customerID | Missing customer ID | Provide customer ID |
| SOAP fault | Microsoft API error | Check SOAP response for details |
📊 Required Parameters
Account-Level Operations
customerAccountID (Required for most operations):
- The identifier of the account that owns the entities
- Must be provided as query parameter
- Example:
customerAccountID=98765432
customerID (Optional but recommended):
- The identifier of the customer that owns the account
- Used when managing accounts of other customers
- Example:
customerID=12345678
Reference: Microsoft Ads Request Headers
🔗 Related Documentation
- Microsoft Advertising API: https://docs.microsoft.com/en-us/advertising/
- OAuth 2.0 Setup: Azure Portal App Registration
- Developer Token: Get Developer Token
- SOAP Services: Campaign Management Service
- Reporting Service: Reporting Service Reference
⚠️ Important Notes
- 🔐 Production App Required: Sandbox accounts only work with desktop apps
- 🔄 Auto Token Refresh: Middleware automatically renews expired tokens
- 📦 SOAP Protocol: Uses XML-based SOAP web services (not REST)
- ⏱️ Token Lifetime: Access tokens expire after 1 hour (3600 seconds)
- 🔑 Developer Token: Required for all API requests
- 🎯 Customer Account ID: Required for most operations
- 📊 Multiple API Calls: Listing operations may make multiple SOAP calls
- 🌐 Timezone: All timestamps use account/report timezone setting
- 📈 Aggregation: Reports support flexible time aggregation
- 🔍 Editorial Status: Ads/keywords can be filtered by approval status
🎨 SOAP Client Architecture
Custom SOAP Client (SoapClient.js):
- Built with Axios for HTTP requests
- Uses
fast-xml-parserfor XML-to-JSON conversion - Handles SOAP envelope construction
- Parses SOAP fault responses
- Returns JSON for easy consumption
SOAP Request Format:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:AuthenticationToken>...</h:AuthenticationToken>
<h:DeveloperToken>...</h:DeveloperToken>
<h:CustomerAccountId>...</h:CustomerAccountId>
</s:Header>
<s:Body>
<!-- SOAP operation specific body -->
</s:Body>
</s:Envelope>
🏢 Manager Account Hierarchy
MCC (Microsoft Advertising Center) Support:
- List manager accounts with linked customer accounts
- Access campaigns across multiple managed accounts
- Filter operations by specific customer IDs
- Support for agency/reseller account structures