### Install google-ads-api Source: https://github.com/opteo/google-ads-api/blob/master/README.md Install the library using npm. ```bash npm install google-ads-api ``` -------------------------------- ### OnQueryStart Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md An example implementation of the `onQueryStart` hook. This hook demonstrates checking a cache before execution and enabling `validate_only` mode in development environments. ```typescript const onQueryStart: OnQueryStart = async ({ query, cancel, editOptions }) => { console.log("Executing:", query); // Cancel with cached result const cached = await queryCache.get(query); if (cached) { cancel(cached); return; } // Enable validation in dev mode if (process.env.NODE_ENV === "development") { editOptions({ validate_only: true }); } }; const customer = client.Customer(customerOptions, { onQueryStart }); ``` -------------------------------- ### OnStreamStart Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md Intercepts the start of a stream to log the query and modify request options, such as setting a custom page size. ```typescript const onStreamStart: OnStreamStart = async ({ query, editOptions }) => { console.log("Starting stream:", query); editOptions({ page_size: 5000 }); }; const customer = client.Customer(customerOptions, { onStreamStart }); ``` -------------------------------- ### Complete GAQL Query Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/query-building.md A comprehensive example of a GAQL query demonstrating selection of fields and metrics, filtering by conditions and date ranges, and sorting results. ```typescript const results = await customer.query(` SELECT campaign.id, campaign.name, ad_group.id, ad_group.name, metrics.clicks, metrics.impressions, metrics.cost_micros, segments.date, segments.device FROM ad_group WHERE campaign.status = 'ENABLED' AND segments.date DURING 20240101 20240131 AND metrics.clicks > 100 ORDER BY segments.date DESC, metrics.clicks DESC LIMIT 1000 `); ``` -------------------------------- ### Constraint Examples Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/types-reference.md Illustrates how to use the different formats for specifying WHERE clause constraints. ```typescript // String format const constraints1 = ["campaign.status = 'ENABLED'"]; ``` ```typescript // Object format with operator const constraints2 = [ { key: "campaign.status", op: "=", val: "ENABLED" }, { key: "metrics.clicks", op: ">", val: 100 }, ]; ``` ```typescript // Object shorthand const constraints3 = { "campaign.status": "ENABLED", "campaign.id": 123, }; ``` -------------------------------- ### Minimal Import Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Demonstrates a minimal import of the GoogleAdsApi client and performing a report query. ```typescript import { GoogleAdsApi, enums } from "google-ads-api"; const client = new GoogleAdsApi(options); const customer = client.Customer(customerOptions); const campaigns = await customer.report({ entity: "campaign", constraints: { "campaign.status": enums.CampaignStatus.ENABLED }, }); ``` -------------------------------- ### Complete Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md This example demonstrates how to implement custom logic for query lifecycle events using the Hooks API. It includes caching, development-time validation, error logging, and response enhancement. ```typescript import { Hooks, OnQueryStart, OnQueryError, OnQueryEnd } from "google-ads-api"; const hooks: Hooks = { onQueryStart: async ({ query, cancel, editOptions, credentials }) => { console.log(`[${credentials.customer_id}] Starting query`); // Check cache const cached = await cache.get(query); if (cached) { console.log("Returning cached result"); cancel(cached); return; } // Add validation in dev if (process.env.NODE_ENV !== "production") { editOptions({ validate_only: true }); } }, onQueryError: async ({ error, query, credentials }) => { console.error(`[${credentials.customer_id}] Query error:`, error); await metrics.increment("query_error"); }, onQueryEnd: async ({ response, query, resolve, credentials }) => { console.log(`[${credentials.customer_id}] Query returned ${response.length} rows`); // Cache results for 1 hour await cache.set(query, response, { ttl: 3600 }); // Add metadata to each row const enhanced = response.map(row => ({ ...row, _fetched_at: new Date(), _customer_id: credentials.customer_id, })); resolve(enhanced); }, }; const customer = client.Customer(customerOptions, hooks); // Now all queries use the hooks const campaigns = await customer.query("SELECT campaign.id, campaign.name FROM campaign"); ``` -------------------------------- ### OnMutationStart Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md Intercepts mutations before they are sent to the API. This example enables dry-run validation in a staging environment. ```typescript const onMutationStart: OnMutationStart = async ({ mutations, editOptions }) => { console.log(`Applying ${mutations.length} mutations`); // Enable dry-run in staging if (process.env.ENVIRONMENT === "staging") { editOptions({ validate_only: true }); } }; ``` -------------------------------- ### OnQueryEnd Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md An example implementation of the `onQueryEnd` hook. This hook demonstrates caching query results and transforming the response data before it is returned. ```typescript const onQueryEnd: OnQueryEnd = async ({ query, response, resolve }) => { // Cache the results await queryCache.set(query, response, { ttl: 3600 }); // Transform response const transformed = response.map(row => ({ ...row, timestamp: new Date(), })); resolve(transformed); }; const customer = client.Customer(customerOptions, { onQueryEnd }); ``` -------------------------------- ### Complete Google Ads API Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/authentication-and-setup.md This snippet demonstrates initializing the Google Ads API client, creating a customer instance, and executing a query with error handling. Ensure all required environment variables are set. ```typescript import { GoogleAdsApi, errors } from "google-ads-api"; // Initialize client const client = new GoogleAdsApi({ client_id: process.env.GOOGLE_CLIENT_ID!, client_secret: process.env.GOOGLE_CLIENT_SECRET!, developer_token: process.env.GOOGLE_DEVELOPER_TOKEN!, }); // Create customer instance const customer = client.Customer({ customer_id: process.env.GOOGLE_CUSTOMER_ID!, refresh_token: process.env.GOOGLE_REFRESH_TOKEN!, login_customer_id: process.env.GOOGLE_LOGIN_CUSTOMER_ID, // Optional }); // Use with error handling try { const campaigns = await customer.query(` SELECT campaign.id, campaign.name FROM campaign `); console.log("Found", campaigns.length, "campaigns"); } catch (err) { if (err instanceof errors.GoogleAdsFailure) { console.error("API Error:", err.errors[0].message); } else { console.error("Connection Error:", err); } } ``` -------------------------------- ### Complete Import Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Shows a comprehensive import statement including all major types and utilities from the google-ads-api library. ```typescript import { GoogleAdsApi, enums, resources, services, errors, Hooks, toMicros, fromMicros, parse, ResourceNames, MutateOperation, ReportOptions, CustomerOptions, } from "google-ads-api"; ``` -------------------------------- ### Pre-request Hooks (onQueryStart Example) Source: https://github.com/opteo/google-ads-api/blob/master/README.md Demonstrates the usage of the onQueryStart pre-request hook to cancel a request or edit options before it's sent. This hook is executed before a query or stream. ```APIDOC ## Pre-request Hooks (onQueryStart) ### Description These hooks are executed **before** a query/stream/mutation/service. They have access to a `cancel` method to stop the action and an `editOptions` method to modify request options. ### Method `onQueryStart` ### Parameters - `cancel`: Function to cancel the action. Can accept an optional argument to be used as an alternative return value. - `editOptions`: Function to modify request options. Accepts an object with keys to be changed. ### Request Example ```ts import { OnQueryStart } from "google-ads-api"; const onQueryStart: OnQueryStart = async ({ cancel, editOptions }) => { if (env.mode === "test") { cancel([]); // Cancels the request. The supplied argument will become the alternative return value in query and mutation hooks } if (env.mode === "dev") { editOptions({ validate_only: true }); // Edits the request options } }; const customer = client.Customer( { clientOptions, customerOptions, }, { onQueryStart } ); ``` ``` -------------------------------- ### Post-request Hooks (onQueryEnd Example) Source: https://github.com/opteo/google-ads-api/blob/master/README.md Shows how to use the onQueryEnd hook, which runs after a query, mutation, or service completes. It provides access to the response and a resolve function. ```APIDOC ## Post-request Hooks (onQueryEnd) ### Description These hooks are executed **after** a query, mutation or service. This library does not contain an `onStreamEnd` hook to avoid accumulating stream results and blocking the thread. ### Method `onQueryEnd` ### Parameters - `response`: The results of the query/mutation. - `resolve`: Function to provide an alternative return value for the operation. ### Request Example ```ts import { OnQueryEnd } from "google-ads-api"; const onQueryEnd: OnQueryEnd = async ({ response, resolve }) => { const [first] = response; // The results of the query/mutation resolve([first]); // The supplied argument will become the alternative return value }; const customer = client.Customer( { clientOptions, customerOptions, }, { onQueryEnd } ); ``` ``` -------------------------------- ### Selective Imports Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Illustrates importing specific components like GoogleAdsApi, enums, resources, and utility functions individually. ```typescript import { GoogleAdsApi } from "google-ads-api"; import { enums, resources } from "google-ads-api"; import { toMicros, fromMicros } from "google-ads-api"; import type { ReportOptions, CustomerOptions } from "google-ads-api"; ``` -------------------------------- ### OnQueryStart Hook Type Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Callback type for hooks executed before a query starts. ```APIDOC ### Type: OnQueryStart ```typescript export { OnQueryStart } from "./hooks" ``` Hook before query execution. ``` -------------------------------- ### Create Customer Instance Source: https://github.com/opteo/google-ads-api/blob/master/README.md Create a customer instance using the client. Supports basic customer ID and refresh token, as well as optional login and linked customer IDs for more complex setups. ```typescript const customer = client.Customer({ customer_id: "1234567890", refresh_token: "", }); // Also supports login & linked customer ids const customer = client.Customer({ customer_id: "1234567890", login_customer_id: "", linked_customer_id: "", refresh_token: "", }); ``` -------------------------------- ### OnStreamStart Hook Type Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Callback type for hooks executed before a stream starts. ```APIDOC ### Type: OnStreamStart ```typescript export { OnStreamStart } from "./hooks" ``` Hook before stream execution. ``` -------------------------------- ### Google Ads API Client Setup with Environment Variables Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/authentication-and-setup.md Configure the Google Ads API client using environment variables for enhanced security. The .env file should contain your GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_DEVELOPER_TOKEN. ```typescript const client = new GoogleAdsApi({ client_id: process.env.GOOGLE_CLIENT_ID!, client_secret: process.env.GOOGLE_CLIENT_SECRET!, developer_token: process.env.GOOGLE_DEVELOPER_TOKEN!, }); ``` ```dotenv GOOGLE_CLIENT_ID=YOUR_CLIENT_ID.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=YOUR_CLIENT_SECRET GOOGLE_DEVELOPER_TOKEN=YOUR_DEVELOPER_TOKEN ``` -------------------------------- ### MutateOperation Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/types-reference.md Demonstrates the structure of a single mutation operation for creating a campaign resource. ```typescript const operations: MutateOperation[] = [ { entity: "campaign", operation: "create", resource: { name: "New Campaign", status: enums.CampaignStatus.PAUSED, campaign_budget: budgetResourceName, advertising_channel_type: enums.AdvertisingChannelType.SEARCH, }, }, ]; ``` -------------------------------- ### OnMutationStart Hook Type Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Callback type for hooks executed before a mutation starts. ```APIDOC ### Type: OnMutationStart ```typescript export { OnMutationStart } from "./hooks" ``` Hook before mutation execution. ``` -------------------------------- ### Build Complex Queries with Constraints and Ordering Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/INDEX.md Construct detailed reports by specifying attributes, metrics, constraints, and sorting order. This example retrieves enabled ad groups with more than 100 clicks, ordered by clicks in descending order. ```typescript const results = await customer.report({ entity: "ad_group", attributes: ["ad_group.id", "ad_group.name"], metrics: ["metrics.clicks"], constraints: [ { key: "campaign.status", op: "=", val: "ENABLED" }, { key: "metrics.clicks", op: ">", val: 100 }, ], order: [ { field: "metrics.clicks", sort_order: "DESC" }, ], }); ``` -------------------------------- ### OnQueryError Hook Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md An example implementation of the `onQueryError` hook. This hook logs specific Google Ads API errors to the console and a monitoring service. ```typescript const onQueryError: OnQueryError = async ({ error, query }) => { if (error instanceof errors.GoogleAdsFailure) { const [firstErr] = error.errors; console.error(`Query failed: ${firstErr.message}`); await logToMonitoring({ errorCode: firstErr.error_code, query, }); } }; const customer = client.Customer(customerOptions, { onQueryError }); ``` -------------------------------- ### TypeScript Query Normalization Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/query-building.md Demonstrates how the Google Ads API library automatically normalizes whitespace in GAQL queries before sending them. This ensures consistent query formatting. ```typescript const query = ` SELECT campaign.id, campaign.name FROM campaign `; // Library automatically normalizes before sending: // "SELECT campaign.id, campaign.name FROM campaign" ``` -------------------------------- ### Handle Partial Failures in Mutate Operations Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/error-handling.md This example shows how to process a list of operations and handle potential partial failures. It checks the response for a partial_failure_error, logs individual operation failures, and processes successful creations. ```typescript const operations = [ { entity: "campaign", operation: "create", resource: campaign1 }, { entity: "campaign", operation: "create", resource: campaign2 }, { entity: "campaign", operation: "create", resource: campaign3 }, ]; const response = await customer.mutateResources(operations); // Check for partial failures if (response.partial_failure_error) { const failure = response.partial_failure_error as errors.GoogleAdsFailure; failure.errors.forEach((error, index) => { if (error.message) { console.error(`Operation ${index} failed: ${error.message}`); } }); } // Process successful operations response.mutate_operation_responses?.forEach((operationResponse, index) => { if (operationResponse.create_result) { console.log(`Operation ${index} succeeded:`, operationResponse.create_result.resource_name); } }); ``` -------------------------------- ### Common Service Method Operations Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/mutations-and-service-methods.md Provides concise examples for creating, updating, and removing common Google Ads entities using their respective service methods. ```typescript // Create const { results } = await customer.campaigns.create([campaign]); ``` ```typescript // Update const { results } = await customer.campaigns.update([campaign]); ``` ```typescript // Remove const { results } = await customer.campaigns.remove([resourceName]); ``` ```typescript // Create const { results } = await customer.ad_groups.create([adGroup]); ``` ```typescript // Update const { results } = await customer.ad_groups.update([adGroup]); ``` ```typescript // Remove const { results } = await customer.ad_groups.remove([resourceName]); ``` ```typescript // Create const { results } = await customer.ad_group_ads.create([adGroupAd]); ``` ```typescript // Update const { results } = await customer.ad_group_ads.update([adGroupAd]); ``` ```typescript // Remove const { results } = await customer.ad_group_ads.remove([resourceName]); ``` ```typescript // Create keyword const { results } = await customer.ad_group_criteria.create([criterion]); ``` ```typescript // Update const { results } = await customer.ad_group_criteria.update([criterion]); ``` ```typescript // Remove const { results } = await customer.ad_group_criteria.remove([resourceName]); ``` -------------------------------- ### Query Validation Error Example Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/query-building.md Demonstrates how to catch and handle query validation errors, such as missing required fields, by using a try-catch block. ```typescript try { // Missing metrics, attributes, and segments await customer.report({ entity: "campaign", }); } catch (err) { console.error(err.message); // "Must specify at least one field..." } ``` -------------------------------- ### Obtain OAuth 2.0 Refresh Token using google-auth-library Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/authentication-and-setup.md This Node.js example demonstrates how to use the `google-auth-library` to exchange an authorization code for a refresh token. This is part of the OAuth 2.0 flow for authenticating with Google APIs. ```typescript import { OAuth2Client } from "google-auth-library"; async function getRefreshToken(authCode: string): Promise { const oauth2Client = new OAuth2Client( CLIENT_ID, CLIENT_SECRET, "http://localhost:3000/oauth2callback" // Redirect URI ); const { tokens } = await oauth2Client.getToken(authCode); const refreshToken = tokens.refresh_token; console.log("Refresh token:", refreshToken); return refreshToken; } ``` -------------------------------- ### Create Customer Instance for a Manager Account Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/authentication-and-setup.md Set up a customer instance when accessing a client account through a manager account. Include your manager account ID in the `login_customer_id` field. ```typescript const customer = client.Customer({ customer_id: "1234567890", // Client account ID refresh_token: "1//REFRESH_TOKEN", login_customer_id: "9876543210", // Your manager account ID }); ``` -------------------------------- ### Create Campaign via Service Method Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/mutations-and-service-methods.md Demonstrates how to create a new campaign using the `customer.campaigns.create` service method. ```APIDOC ## Create Campaign via Service Method ### Description Creates a new campaign using the `create` method on the `campaigns` service. ### Method `customer.campaigns.create(campaigns: Campaign[])` ### Parameters * `campaigns` (Campaign[]) - An array of Campaign objects to create. ### Request Example ```typescript import { resources, enums } from "google-ads-api"; const campaign = new resources.Campaign({ name: "Service Method Campaign", advertising_channel_type: enums.AdvertisingChannelType.SEARCH, status: enums.CampaignStatus.ENABLED, campaign_budget: budgetResourceName, }); const { results } = await customer.campaigns.create([campaign]); console.log("Created campaign:", results[0].resource_name); ``` ### Response * `results` (Array) - An array of results for each created campaign. ``` -------------------------------- ### Get Report Row Count Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/customer-api.md Use reportCount to get the total number of rows for a report query without fetching the data. This is useful for estimating report size. ```typescript async reportCount( options: Readonly ): Promise ``` ```typescript const totalRows = await customer.reportCount({ entity: "search_term_view", attributes: ["search_term_view.resource_name"], }); console.log(`Total rows in report: ${totalRows}`); ``` -------------------------------- ### Initialize GoogleAdsApi Client and Query Campaigns Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/INDEX.md Initialize the GoogleAdsApi client with credentials and query enabled campaigns. Ensure you replace placeholder values with your actual credentials and customer ID. ```typescript import { GoogleAdsApi, enums } from "google-ads-api"; // Initialize client const client = new GoogleAdsApi({ client_id: "YOUR_CLIENT_ID", client_secret: "YOUR_CLIENT_SECRET", developer_token: "YOUR_DEVELOPER_TOKEN", }); // Create customer instance const customer = client.Customer({ customer_id: "1234567890", refresh_token: "YOUR_REFRESH_TOKEN", }); // Query campaigns const campaigns = await customer.report({ entity: "campaign", attributes: ["campaign.id", "campaign.name"], metrics: ["metrics.clicks"], constraints: { "campaign.status": enums.CampaignStatus.ENABLED, }, }); ``` -------------------------------- ### Report with DateConstant Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/types-reference.md Example of building a report using a predefined date constant for the query. ```typescript const report = await customer.report({ entity: "campaign", metrics: ["metrics.clicks"], date_constant: "LAST_30_DAYS", }); ``` -------------------------------- ### OnServiceStart Hook Type Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Callback type for hooks executed before a service call starts. ```APIDOC ### Type: OnServiceStart ```typescript export { OnServiceStart } from "./hooks" ``` Hook before service execution. ``` -------------------------------- ### Using Pre-request Hooks (onQueryStart) Source: https://github.com/opteo/google-ads-api/blob/master/README.md Demonstrates how to use the onQueryStart hook to cancel a request or edit request options before it is sent. Use cancel() to stop the request and editOptions() to modify parameters like validateOnly. ```typescript import { OnQueryStart } from "google-ads-api"; const onQueryStart: OnQueryStart = async ({ cancel, editOptions }) => { if (env.mode === "test") { cancel([]); // Cancels the request. The supplied argument will become the alternative return value in query and mutation hooks } if (env.mode === "dev") { editOptions({ validate_only: true }); // Edits the request options } }; const customer = client.Customer( { clientOptions, customerOptions, }, { onQueryStart } ); ``` -------------------------------- ### Basic Google Ads API Client Initialization and Campaign Query Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/README.md Initializes the GoogleAdsApi client with credentials and retrieves enabled campaigns, including their ID, name, and clicks. Requires client ID, secret, developer token, customer ID, and refresh token. ```typescript import { GoogleAdsApi, enums } from "google-ads-api"; const client = new GoogleAdsApi({ client_id: "YOUR_CLIENT_ID", client_secret: "YOUR_CLIENT_SECRET", developer_token: "YOUR_DEVELOPER_TOKEN", }); const customer = client.Customer({ customer_id: "1234567890", refresh_token: "YOUR_REFRESH_TOKEN", }); // Query campaigns const campaigns = await customer.report({ entity: "campaign", attributes: ["campaign.id", "campaign.name"], metrics: ["metrics.clicks"], constraints: { "campaign.status": enums.CampaignStatus.ENABLED, }, }); ``` -------------------------------- ### Create Google Ads API Client Source: https://github.com/opteo/google-ads-api/blob/master/README.md Initialize the GoogleAdsApi client with your credentials. Ensure you replace placeholders with your actual client ID, client secret, and developer token. ```typescript import { GoogleAdsApi } from "google-ads-api"; const client = new GoogleAdsApi({ client_id: "", client_secret: "", developer_token: "", }); ``` -------------------------------- ### On Error Hooks (onQueryError Example) Source: https://github.com/opteo/google-ads-api/blob/master/README.md Illustrates the onQueryError hook, which is triggered when a query or stream encounters an error. It provides access to the error object. ```APIDOC ## On Error Hooks (onQueryError) ### Description These hooks are executed when a query/stream/mutation/service throws an error. Errors are converted to `GoogleAdsFailure` if applicable. The `error` argument provides access to the error details. ### Method `onQueryError` ### Parameters - `error`: The error object, which can be a standard Error or a `GoogleAdsFailure`. ### Request Example ```ts import { OnQueryError } from "google-ads-api"; const onQueryError: OnQueryError = async ({ error }) => { console.log(error.message); // An Error or a GoogleAdsFailure }; const customer = client.Customer( { clientOptions, customerOptions, }, { onQueryError } ); ``` ``` -------------------------------- ### CustomerOptions Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/types-reference.md Configuration object passed to `client.Customer()` to create a customer instance. It includes essential identifiers and optional manager/linked customer IDs. ```APIDOC ## Type: CustomerOptions Configuration object passed to `client.Customer()` to create a customer instance. | Field | Type | Required | Description | |---|---|---|---| | customer_id | string | Yes | 10-digit Google Ads customer ID without dashes | | refresh_token | string | Yes | OAuth 2.0 refresh token for this customer | | login_customer_id | string | No | Manager account ID when accessing customer as a manager | | linked_customer_id | string | No | Linked customer ID for cross-account operations | **Example:** ```typescript const customerOptions: CustomerOptions = { customer_id: "1234567890", refresh_token: "1//YOUR_REFRESH_TOKEN", login_customer_id: "9876543210", }; ``` ``` -------------------------------- ### Basic GAQL Query Structure Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/query-building.md Illustrates the fundamental structure of a Google Ads Query Language (GAQL) query, including SELECT, FROM, WHERE, ORDER BY, and LIMIT clauses. ```sql SELECT field1, field2, metric1, metric2 FROM entity WHERE condition1 AND condition2 ORDER BY field1 DESC, metric1 ASC LIMIT 100 ``` -------------------------------- ### Handle API Errors Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/INDEX.md Implement robust error handling for API requests. This example specifically catches `GoogleAdsFailure` errors and logs the API error message. ```typescript import { errors } from "google-ads-api"; try { const results = await customer.query(query); } catch (err) { if (err instanceof errors.GoogleAdsFailure) { const [error] = err.errors; console.error("API Error:", error.message); } } ``` -------------------------------- ### Manage Multiple Client Accounts Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/authentication-and-setup.md Demonstrates how to initialize the Google Ads API client and create instances for multiple customer accounts using their respective IDs and refresh tokens. This allows for querying data across all managed accounts. ```typescript const client = new GoogleAdsApi({ client_id: "...", client_secret: "...", developer_token: "...", }); // Access multiple customer accounts const customers = [ { id: "1111111111", refreshToken: "TOKEN_1", }, { id: "2222222222", refreshToken: "TOKEN_2", }, { id: "3333333333", refreshToken: "TOKEN_3", }, ]; // Create instances for each const customerInstances = customers.map(c => client.Customer({ customer_id: c.id, refresh_token: c.refreshToken, }) ); // Query all accounts const allCampaigns = await Promise.all( customerInstances.map(cus => cus.query("SELECT campaign.id, campaign.name FROM campaign") ) ); ``` -------------------------------- ### Stream Raw Report Data Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/customer-api.md Use reportStreamRaw to get the raw streaming response from the API without parsing. This is useful for custom parsing or event handling. ```typescript async reportStreamRaw( reportOptions: Readonly ): Promise ``` ```typescript import { parse } from "google-ads-api"; const stream = await customer.reportStreamRaw({ entity: "ad_group_criterion", attributes: [ "ad_group_criterion.keyword.text", "ad_group_criterion.status", ], constraints: { "ad_group_criterion.type": enums.CriterionType.KEYWORD, }, }); stream.on("data", (chunk) => { const parsedRows = parse({ results: chunk.results, reportOptions: { entity: "ad_group_criterion", attributes: ["ad_group_criterion.keyword.text", "ad_group_criterion.status"], }, }); console.log("Received chunk with", parsedRows.length, "rows"); }); stream.on("error", (error) => { console.error("Stream error:", error); }); stream.on("end", () => { console.log("Stream completed"); }); ``` -------------------------------- ### Create Campaign via Service Method Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/mutations-and-service-methods.md Use the `campaigns.create` method to create a new campaign. Ensure the `resources.Campaign` object is properly configured with required fields and a valid `campaign_budget` resource name. ```typescript import { resources, enums } from "google-ads-api"; const campaign = new resources.Campaign({ name: "Service Method Campaign", advertising_channel_type: enums.AdvertisingChannelType.SEARCH, status: enums.CampaignStatus.ENABLED, campaign_budget: budgetResourceName, }); const { results } = await customer.campaigns.create([campaign]); console.log("Created campaign:", results[0].resource_name); ``` -------------------------------- ### CustomerOptions Type Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Configuration object for creating a customer instance. ```APIDOC ### Type: CustomerOptions ```typescript export { CustomerOptions } from "./types" ``` Configuration for creating a customer instance. ``` -------------------------------- ### Handle QueryError: UNRECOGNIZED_FIELD Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/error-handling.md Example of handling a `UNRECOGNIZED_FIELD` error, which occurs when a field name in a GAQL query is not found. It logs the invalid field and suggests mapping to a valid one. ```typescript if (error.error_code.query_error === errors.QueryErrorEnum.QueryError.UNRECOGNIZED_FIELD) { console.log(`Field "${error.trigger}" does not exist`); // Map to valid field and retry } ``` -------------------------------- ### Get Total Results Count for a Report Source: https://github.com/opteo/google-ads-api/blob/master/README.md Retrieves the total number of rows a query would return, ignoring any limits. This is an alternative to the `return_total_results_count` report option and does not trigger hooks. ```typescript const totalRows = await customer.reportCount({ entity: "search_term_view", attributes: ["search_term_view.resource_name"], }); ``` -------------------------------- ### GoogleAdsApi Constructor Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/client-api.md Creates a new Google Ads API client with authentication credentials. Requires client ID, client secret, and developer token. ```APIDOC ## Class: GoogleAdsApi / Client Primary client for interacting with the Google Ads API. ### Constructor ```typescript new GoogleAdsApi(options: ClientOptions) ``` Creates a new Google Ads API client with authentication credentials. | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | options | ClientOptions | Yes | — | Configuration object with authentication credentials | | options.client_id | string | Yes | — | OAuth 2.0 client ID from Google Cloud | | options.client_secret | string | Yes | — | OAuth 2.0 client secret from Google Cloud | | options.developer_token | string | Yes | — | Google Ads API developer token | | options.disable_parsing | boolean | No | undefined | When true, disables automatic parsing of API responses to snake_case | | options.max_reporting_rows | number | No | undefined | Maximum number of rows to fetch in report queries; exceeding this limit throws an error | **Return:** GoogleAdsApi instance **Example:** ```typescript import { GoogleAdsApi } from "google-ads-api"; const client = new GoogleAdsApi({ client_id: "YOUR_CLIENT_ID.apps.googleusercontent.com", client_secret: "YOUR_CLIENT_SECRET", developer_token: "YOUR_DEVELOPER_TOKEN", }); ``` ``` -------------------------------- ### Use Streaming for Large Datasets Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/streaming-and-pagination.md Stream reports when expecting more than 10,000 rows to avoid memory issues and timeouts. This example shows a conditional check based on estimated row count. ```typescript // Rule of thumb: stream if expecting > 10,000 rows const estimatedRows = await customer.reportCount({ entity: "search_term_view", attributes: ["search_term_view.search_term"], }); if (estimatedRows > 10000) { // Use stream for await (const row of customer.reportStream(...)) { // ... } } else { // Use regular report const results = await customer.report(...); } ``` -------------------------------- ### OnQueryStart Hook Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md Hook executed before a query or report is sent to the API. It allows for actions like cache checking, parameter validation, logging, and modifying request options. ```APIDOC ## OnQueryStart Hook ### Description Hook executed before a query or report is sent to the API. Allows for cache checking, validation, logging, and modifying request options. ### Signature ```typescript type OnQueryStart = (args: { credentials: CustomerCredentials query: string reportOptions?: ReportOptions cancel: (result?: any) => void editOptions: (options: Partial) => void }) => void | Promise ``` ### Parameters - `credentials` (CustomerCredentials) - Object containing customer_id, login_customer_id, linked_customer_id. - `query` (string) - The GAQL query string being executed. - `reportOptions` (ReportOptions) - Report options if using the report() method; undefined for query(). - `cancel` (function) - Function to cancel the query; optionally return a value to use instead of API result. - `editOptions` (function) - Function to modify request options before sending. ### Use Cases - Cache checking before executing expensive queries - Validation of query parameters - Logging and monitoring - Setting validate_only mode in development ### Example ```typescript const onQueryStart: OnQueryStart = async ({ query, cancel, editOptions }) => { console.log("Executing:", query); // Cancel with cached result const cached = await queryCache.get(query); if (cached) { cancel(cached); return; } // Enable validation in dev mode if (process.env.NODE_ENV === "development") { editOptions({ validate_only: true }); } }; const customer = client.Customer(customerOptions, { onQueryStart }); ``` ``` -------------------------------- ### CustomerOptions Configuration Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/types-reference.md Configuration object for creating a customer instance. Requires customer ID and refresh token. Optionally includes manager or linked customer IDs. ```typescript const customerOptions: CustomerOptions = { customer_id: "1234567890", refresh_token: "1//YOUR_REFRESH_TOKEN", login_customer_id: "9876543210", }; ``` -------------------------------- ### Create a Campaign & Budget atomically Source: https://github.com/opteo/google-ads-api/blob/master/README.md Atomically creates a new campaign and its associated budget. ```APIDOC ## Create a Campaign & Budget atomically ```ts import { resources, enums, toMicros, ResourceNames, MutateOperation, } from "google-ads-api"; // Create a resource name with a temporary resource id (-1) const budgetResourceName = ResourceNames.campaignBudget( customer.credentials.customer_id, "-1" ); const operations: MutateOperation< resources.ICampaignBudget | resources.ICampaign >[] = [ { entity: "campaign_budget", operation: "create", resource: { // Create a budget with the temporary resource id resource_name: budgetResourceName, name: "Planet Express Budget", delivery_method: enums.BudgetDeliveryMethod.STANDARD, amount_micros: toMicros(500), }, }, { entity: "campaign", operation: "create", resource: { name: "Planet Express", advertising_channel_type: enums.AdvertisingChannelType.SEARCH, status: enums.CampaignStatus.PAUSED, manual_cpc: { enhanced_cpc_enabled: false, }, // Use the temporary resource id which will be created in the previous operation campaign_budget: budgetResourceName, network_settings: { target_google_search: true, target_search_network: true, }, }, }, ]; const result = await customer.mutateResources(operations); ``` ``` -------------------------------- ### Mock API Responses with onQueryStart Hook Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/best-practices.md Allows mocking of API query responses during testing by implementing the `onQueryStart` hook. This enables predictable test outcomes without making actual API calls. ```typescript const mockData = { "SELECT campaign.id FROM campaign": [ { campaign: { id: 123 } }, { campaign: { id: 456 } }, ], }; const customer = client.Customer( { customer_id: "...", refresh_token: "..." }, { onQueryStart: async ({ query, cancel }) => { if (process.env.NODE_ENV === "test") { const mockResponse = mockData[query]; if (mockResponse) { cancel(mockResponse); } } }, } ); ``` -------------------------------- ### OnStreamStart Hook Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md Hook executed before a stream is opened. Allows modification of request options and cancellation of the stream. ```APIDOC ## OnStreamStart Hook ### Description Hook executed before a stream is opened. Allows modification of request options and cancellation of the stream. ### Signature ```typescript type OnStreamStart = (args: { credentials: CustomerCredentials query: string reportOptions?: ReportOptions cancel: () => void editOptions: (options: Partial) => void }) => void | Promise ``` ### Parameters - **credentials** (CustomerCredentials) - Customer credentials - **query** (string) - The GAQL query string - **reportOptions** (ReportOptions) - Report options if using reportStream() - **cancel** (function) - Function to cancel stream without argument - **editOptions** (function) - Function to modify request options ### Example ```typescript const onStreamStart: OnStreamStart = async ({ query, editOptions }) => { console.log("Starting stream:", query); editOptions({ page_size: 5000 }); }; const customer = client.Customer(customerOptions, { onStreamStart }); ``` ``` -------------------------------- ### Implement Structured Logging for API Operations Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/best-practices.md Integrates structured logging using Winston to record details about API query lifecycle events like start, error, and completion. This aids in debugging and monitoring API interactions. ```typescript import winston from "winston"; const logger = winston.createLogger({ format: winston.format.json(), transports: [new winston.transports.Console()], }); const customer = client.Customer( { customer_id: "...", refresh_token: "..." }, { onQueryStart: async ({ query, credentials }) => { logger.info("Query started", { customerId: credentials.customer_id, query: query.substring(0, 200), }); }, onQueryError: async ({ error, credentials }) => { logger.error("Query error", { customerId: credentials.customer_id, error: error.message, timestamp: new Date().toISOString(), }); }, onQueryEnd: async ({ response, credentials }) => { logger.info("Query completed", { customerId: credentials.customer_id, rowCount: response.length, }); }, } ); ``` -------------------------------- ### Customer Method Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/client-api.md Creates a new Customer instance for a specific Google Ads account. Used for queries, reports, mutations, and service calls. ```APIDOC ### Method: Customer ```typescript Customer(customerOptions: CustomerOptions, hooks?: Hooks): Customer ``` Creates a new Customer instance for a specific Google Ads account. The Customer instance is used to perform queries, reports, mutations, and service calls. | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | customerOptions | CustomerOptions | Yes | — | Configuration for the specific customer account | | customerOptions.customer_id | string | Yes | — | 10-digit Google Ads customer ID (without dashes) | | customerOptions.refresh_token | string | Yes | — | OAuth 2.0 refresh token for this customer | | customerOptions.login_customer_id | string | No | undefined | For manager accounts, the login customer ID | | customerOptions.linked_customer_id | string | No | undefined | For accessing linked customer accounts | | hooks | Hooks | No | undefined | Optional lifecycle hooks for queries, streams, and mutations | **Return:** Customer instance **Example:** ```typescript const customer = client.Customer({ customer_id: "1234567890", refresh_token: "REFRESH_TOKEN", }); // With manager account const customerViaManager = client.Customer({ customer_id: "1234567890", refresh_token: "REFRESH_TOKEN", login_customer_id: "9876543210", }); // With hooks const customerWithHooks = client.Customer( { customer_id: "1234567890", refresh_token: "REFRESH_TOKEN", }, { onQueryStart: async ({ query, cancel }) => { console.log("Executing query:", query); }, } ); ``` ``` -------------------------------- ### Reuse Customer Instances for Efficiency Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/best-practices.md Demonstrates the recommended practice of reusing customer instances for multiple API operations to leverage internal caching of services and tokens. Avoid creating new customer instances for each operation. ```typescript // ✅ Good: Reuse customer instances const customer = client.Customer({ customer_id: "1234567890", refresh_token: "TOKEN", }); // Use customer for multiple operations const campaigns = await customer.report({ /* ... */ }); const adGroups = await customer.report({ /* ... */ }); const keywords = await customer.report({ /* ... */ }); // Services and tokens are cached automatically // ❌ Bad: Creating new customers for each operation for (const customerId of customerIds) { const customer = client.Customer({ customer_id: customerId, refresh_token: getToken(customerId), }); const result = await customer.report({ /* ... */ }); } ``` -------------------------------- ### GoogleAdsApi Class Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md The main client class for initializing the library. It allows for creating customer instances and listing accessible customers. ```APIDOC ## Class: GoogleAdsApi ### Description The main client class for initializing the library. **Methods:** - `Customer(customerOptions, hooks?)`: Create customer instance - `listAccessibleCustomers(refreshToken)`: List accessible customers ``` -------------------------------- ### resources Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Proto message classes for all resource types, including Campaign, AdGroup, Ad, AdGroupCriterion, CampaignBudget, and Keyword. ```APIDOC ### resources ```typescript export { resources } from "./protos/index" ``` Proto message classes for all resource types. ```typescript resources.Campaign resources.AdGroup resources.Ad resources.AdGroupCriterion resources.CampaignBudget resources.Keyword ``` **Usage:** ```typescript const campaign = new resources.Campaign({ name: "My Campaign", status: enums.CampaignStatus.ENABLED, }); ``` ``` -------------------------------- ### Client Options Interface Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/INDEX.md Defines the configuration options for initializing the Google Ads API client. Required fields include `client_id`, `client_secret`, and `developer_token`. ```typescript interface ClientOptions { client_id: string // OAuth client ID client_secret: string // OAuth client secret developer_token: string // API developer token disable_parsing?: boolean // Skip response parsing max_reporting_rows?: number // Max rows limit } ``` -------------------------------- ### Export GoogleAdsApi Client and Options Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/module-exports.md Exports the main client class and its options for initializing the library. ```typescript export { Client as GoogleAdsApi, ClientOptions } ``` -------------------------------- ### Uploading Click Conversions Source: https://github.com/opteo/google-ads-api/blob/master/README.md Shows how to upload click conversions using the `uploadClickConversions` method, providing details about the conversion event. ```APIDOC ## Uploading Click Conversions This section details how to upload click conversions to Google Ads. This is essential for tracking the effectiveness of your ad campaigns. ### Method `customer.conversionUploads.uploadClickConversions` ### Request Body Example ```json { "gclid": "", "conversion_action": "customers/1234567890/conversionActions/111222333", "conversion_date_time": "2022-01-11 00:00:00", "conversion_value": 123, "currency_code": "GBP" } ``` ### Example Usage ```ts const clickConversion = { gclid: "", conversion_action: "customers/1234567890/conversionActions/111222333", conversion_date_time: "2022-01-11 00:00:00", conversion_value: 123, currency_code: "GBP", }; const request = new services.UploadClickConversionsRequest({ customer_id: customerId, conversions: [clickConversion], }); await customer.conversionUploads.uploadClickConversions(request); ``` ``` -------------------------------- ### OnMutationStart Hook Source: https://github.com/opteo/google-ads-api/blob/master/_autodocs/hooks-api.md Hook executed before mutations are sent to the API. Allows modification of mutation options and cancellation of the mutation. ```APIDOC ## OnMutationStart Hook ### Description Hook executed before mutations are sent to the API. Allows modification of mutation options and cancellation of the mutation. ### Signature ```typescript type OnMutationStart = (args: { credentials: CustomerCredentials method: `${keyof typeof services}.${string}` mutations: MutateOperation[] isServiceCall: false cancel: (result?: any) => void editOptions: (options: Partial) => void }) | (args: { credentials: CustomerCredentials method: `${keyof typeof services}.${string}` mutation: any isServiceCall: true cancel: (result?: any) => void editOptions: (options: Partial) => void }) ``` ### Parameters - **credentials** (CustomerCredentials) - Customer credentials - **method** (string) - Service method being called (e.g., "CampaignsServiceClient.mutateCampaigns") - **mutations** or **mutation** (MutateOperation[] | any) - The operations being performed - **isServiceCall** (boolean) - true if called via service method, false for mutateResources() - **cancel** (function) - Function to cancel with optional override value - **editOptions** (function) - Function to modify mutation options ### Example ```typescript const onMutationStart: OnMutationStart = async ({ mutations, editOptions }) => { console.log(`Applying ${mutations.length} mutations`); // Enable dry-run in staging if (process.env.ENVIRONMENT === "staging") { editOptions({ validate_only: true }); } }; ``` ```