npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@akson/cortex-google-ads

v2.1.0

Published

Google Ads API client and MCP server for Cortex ecosystem

Downloads

111

Readme

@akson/cortex-google-ads

TypeScript client for Google Ads API operations, enabling programmatic campaign management, conversion tracking, audience targeting, and performance optimization.

User Stories

Account & Customer Management Stories

As a PPC Account Manager, I want to retrieve customer account information, so that I can audit account settings and permissions programmatically.

As a Digital Marketing Director, I want to list all accessible customer accounts, so that I can manage multiple client accounts efficiently.

As a Marketing Operations Specialist, I want to validate account access permissions, so that I can ensure API integration has required access levels.

Campaign Management Stories

As a Performance Marketing Manager, I want to list all campaigns with their performance metrics, so that I can identify optimization opportunities at scale.

As a SEM Specialist, I want to create new campaigns programmatically, so that I can rapidly deploy campaign structures across multiple accounts.

As a Campaign Manager, I want to update campaign budgets and bidding strategies, so that I can respond to performance changes automatically.

As a Digital Marketing Analyst, I want to pause or activate campaigns based on performance thresholds, so that I can prevent budget waste on underperforming campaigns.

Conversion Tracking Stories

As a Growth Marketing Manager, I want to create conversion actions programmatically, so that I can scale attribution tracking across multiple touchpoints.

As a Marketing Attribution Specialist, I want to list all existing conversion actions, so that I can audit current tracking implementation.

As a Performance Marketing Director, I want to upload offline conversions, so that I can attribute phone calls and in-store purchases to digital campaigns.

As a Ecommerce Marketing Manager, I want to bulk upload conversion data with customer information, so that I can improve audience targeting with first-party data.

Audience & Targeting Stories

As a Customer Acquisition Manager, I want to create customer match audiences, so that I can target similar users for lookalike campaigns.

As a Retention Marketing Specialist, I want to create remarketing audiences based on website behavior, so that I can re-engage users who didn't convert.

As a Data-Driven Marketing Manager, I want to sync CRM data to Google Ads audiences, so that I can create highly targeted campaigns based on customer lifetime value.

Reporting & Analytics Stories

As a Marketing Analyst, I want to execute custom GAQL queries, so that I can extract specific performance data for analysis.

As a Performance Marketing Director, I want to generate automated reports on campaign performance, so that I can monitor ROI across all accounts.

As a Digital Marketing Manager, I want to track impression share and competitive metrics, so that I can adjust bidding strategies to maintain market position.

As a Marketing Data Analyst, I want to export detailed conversion path data, so that I can understand multi-touch attribution patterns.

Optimization & Automation Stories

As a SEM Manager, I want to automatically adjust bids based on performance metrics, so that I can maximize ROAS without manual intervention.

As a Performance Marketing Specialist, I want to create and manage responsive search ads at scale, so that I can test ad variations efficiently.

As a Growth Marketing Engineer, I want to integrate Google Ads with marketing automation platforms, so that I can trigger campaign optimizations based on external data.

Quality & Compliance Stories

As a Compliance Manager, I want to audit ad disapprovals and policy violations, so that I can maintain account health across all campaigns.

As a Marketing Operations Manager, I want to validate ad creative compliance before deployment, so that I can prevent policy violations.

As a Brand Marketing Manager, I want to monitor brand safety metrics and negative keywords, so that I can protect brand reputation in search campaigns.

Multi-Account Management Stories

As an Agency Account Director, I want to manage multiple client accounts through a single interface, so that I can scale operations efficiently.

As a Marketing Technology Manager, I want to synchronize campaigns across multiple Google Ads accounts, so that I can maintain consistency for multi-brand companies.

As a Digital Marketing Consultant, I want to benchmark performance across different client accounts, so that I can identify best practices and optimization opportunities.

Installation

npm install @akson/cortex-google-ads

Quick Start

import { GoogleAdsClient } from '@akson/cortex-google-ads';

const client = new GoogleAdsClient({
  config: {
    customerId: '123-456-7890',
    serviceAccount: {
      keyFile: 'path/to/service-account.json',
      email: '[email protected]'
    }
  }
});

// Authenticate and get customer info
await client.authenticate();
const customer = await client.getCustomer();

// List campaigns with performance metrics
const campaigns = await client.listCampaigns();

// Create conversion action
await client.createConversionAction({
  name: 'Website Purchase',
  type: 'WEBPAGE',
  category: 'PURCHASE',
  value: 100.0,
  currency: 'USD'
});

// Upload conversion
await client.uploadConversion({
  conversionActionResourceName: 'customers/123456/conversionActions/456789',
  gclid: 'gclid_value',
  conversionValue: 99.99,
  conversionDateTime: new Date().toISOString(),
  currencyCode: 'USD'
});

Configuration

Environment Variables

GOOGLE_ADS_CUSTOMER_ID=123-456-7890
GOOGLE_ADS_DEVELOPER_TOKEN=your-developer-token
GOOGLE_ADS_SERVICE_ACCOUNT_EMAIL=ads-service@project.iam.gserviceaccount.com
GOOGLE_ADS_SERVICE_ACCOUNT_KEY_FILE=path/to/key.json

Configuration File

Create google-ads-config.json:

{
  "customerId": "123-456-7890",
  "developerToken": "your-developer-token",
  "serviceAccount": {
    "email": "[email protected]",
    "keyFile": "path/to/service-account.json"
  }
}

API Reference

Authentication

// Authenticate with service account
const authResult = await client.authenticate();
if (!authResult.success) {
  throw new Error(authResult.error);
}

Customer Operations

// Get customer information
const customerResult = await client.getCustomer();
if (customerResult.success) {
  console.log('Customer:', customerResult.data);
}

// Get customer with specific ID
const specificCustomer = await client.getCustomer('987-654-3210');

Campaign Operations

// List all campaigns
const campaignsResult = await client.listCampaigns();
if (campaignsResult.success) {
  campaignsResult.data.forEach(campaign => {
    console.log(`Campaign: ${campaign.name}, Status: ${campaign.status}`);
  });
}

// Get campaign performance
const performance = await client.getCampaignPerformance('campaign-id', {
  startDate: '2025-01-01',
  endDate: '2025-01-31',
  metrics: ['clicks', 'impressions', 'conversions', 'cost']
});

Conversion Operations

// List conversion actions
const conversionsResult = await client.listConversionActions();

// Create conversion action
const conversionResult = await client.createConversionAction({
  name: 'Email Signup',
  type: 'WEBPAGE',
  category: 'SIGNUP',
  value: 10.0,
  currency: 'USD',
  countingType: 'ONE_PER_CLICK'
});

// Upload single conversion
await client.uploadConversion({
  conversionActionResourceName: 'customers/123/conversionActions/456',
  gclid: 'Cj0KCQjw...',
  conversionValue: 25.99,
  conversionDateTime: '2025-01-15T10:30:00+00:00',
  currencyCode: 'USD'
});

// Bulk upload conversions
await client.bulkUploadConversions([
  {
    conversionActionResourceName: 'customers/123/conversionActions/456',
    gclid: 'Cj0KCQjw1...',
    conversionValue: 99.99,
    conversionDateTime: '2025-01-15T14:20:00+00:00',
    currencyCode: 'USD'
  },
  {
    conversionActionResourceName: 'customers/123/conversionActions/456',
    gclid: 'Cj0KCQjw2...',
    conversionValue: 149.99,
    conversionDateTime: '2025-01-15T16:45:00+00:00',
    currencyCode: 'USD'
  }
]);

Query Operations

// Execute GAQL query
const queryResult = await client.executeQuery({
  query: `
    SELECT 
      campaign.name,
      campaign.status,
      metrics.clicks,
      metrics.impressions,
      metrics.cost_micros
    FROM campaign 
    WHERE campaign.status = 'ENABLED'
      AND segments.date DURING LAST_30_DAYS
    ORDER BY metrics.clicks DESC
    LIMIT 10
  `
});

// Query with date range
const dateRangeQuery = await client.executeQuery({
  query: 'SELECT campaign.name, metrics.clicks FROM campaign',
  customerId: '123-456-7890',
  dateRange: {
    startDate: '2025-01-01',
    endDate: '2025-01-31'
  }
});

Reporting

// Generate campaign performance report
const report = await client.generateReport({
  reportType: 'CAMPAIGN_PERFORMANCE',
  dateRange: {
    startDate: '2025-01-01',
    endDate: '2025-01-31'
  },
  metrics: ['clicks', 'impressions', 'conversions', 'cost'],
  dimensions: ['campaign_name', 'date'],
  filters: {
    campaignStatus: 'ENABLED'
  }
});

// Export report to CSV
await client.exportReportToCSV(report, 'campaign-report.csv');

Audience Operations

// Create customer match audience
const audienceResult = await client.createCustomerMatchAudience({
  name: 'VIP Customers',
  description: 'High-value repeat customers',
  membershipLifespan: 365,
  uploadKeyType: 'EMAIL_HASH'
});

// Upload audience members
await client.uploadAudienceMembers(audienceResult.data.resourceName, [
  { hashedEmail: 'hashed_email_1' },
  { hashedEmail: 'hashed_email_2' }
]);

Error Handling

All methods return GoogleAdsOperationResult<T>:

const result = await client.listCampaigns();

if (result.success) {
  console.log('Campaigns:', result.data);
  console.log('Total:', result.total);
} else {
  console.error('Error:', result.error);
  if (result.details) {
    console.error('Details:', result.details);
  }
}

Advanced Usage

Performance Monitoring

class GoogleAdsMonitor {
  constructor(private client: GoogleAdsClient) {}

  async checkCampaignHealth() {
    const campaigns = await this.client.listCampaigns();
    
    if (!campaigns.success) return;

    for (const campaign of campaigns.data) {
      const performance = await this.client.getCampaignPerformance(campaign.id, {
        startDate: '2025-01-01',
        endDate: new Date().toISOString().split('T')[0]
      });

      if (performance.success) {
        const ctr = performance.data.clicks / performance.data.impressions;
        if (ctr < 0.01) { // CTR below 1%
          console.warn(`Low CTR alert: ${campaign.name} - ${(ctr * 100).toFixed(2)}%`);
        }
      }
    }
  }
}

Automated Bid Management

async function optimizeBids() {
  const campaigns = await client.listCampaigns();
  
  if (!campaigns.success) return;

  for (const campaign of campaigns.data) {
    const performance = await client.getCampaignPerformance(campaign.id, {
      startDate: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
      endDate: new Date().toISOString().split('T')[0]
    });

    if (performance.success) {
      const roas = performance.data.conversionValue / (performance.data.cost / 1000000);
      
      if (roas > 4.0) {
        // Increase budget by 10%
        await client.updateCampaignBudget(campaign.id, campaign.budget * 1.1);
        console.log(`Increased budget for high-performing campaign: ${campaign.name}`);
      } else if (roas < 2.0) {
        // Decrease budget by 10%
        await client.updateCampaignBudget(campaign.id, campaign.budget * 0.9);
        console.log(`Decreased budget for low-performing campaign: ${campaign.name}`);
      }
    }
  }
}

Multi-Account Management

class MultiAccountManager {
  private clients: Map<string, GoogleAdsClient> = new Map();

  addClient(customerId: string, client: GoogleAdsClient) {
    this.clients.set(customerId, client);
  }

  async getCrossAccountPerformance() {
    const allPerformance = [];

    for (const [customerId, client] of this.clients) {
      const campaigns = await client.listCampaigns();
      if (campaigns.success) {
        allPerformance.push({
          customerId,
          campaigns: campaigns.data.length,
          totalCost: campaigns.data.reduce((sum, c) => sum + (c.cost || 0), 0)
        });
      }
    }

    return allPerformance;
  }
}

Integration Examples

Webhook-Triggered Optimizations

import express from 'express';

const app = express();

app.post('/optimize-campaigns', async (req, res) => {
  const { customerId, threshold } = req.body;
  
  const client = new GoogleAdsClient({
    config: { customerId }
  });

  await client.authenticate();
  
  // Get underperforming campaigns
  const campaigns = await client.executeQuery({
    query: `
      SELECT campaign.id, campaign.name, metrics.cost_per_conversion
      FROM campaign
      WHERE metrics.cost_per_conversion > ${threshold}
        AND segments.date DURING LAST_7_DAYS
    `
  });

  if (campaigns.success) {
    for (const campaign of campaigns.data) {
      await client.pauseCampaign(campaign.id);
      console.log(`Paused expensive campaign: ${campaign.name}`);
    }
  }

  res.json({ success: true, paused: campaigns.data?.length || 0 });
});

CRM Integration

async function syncCRMConversions() {
  // Fetch conversions from CRM
  const crmConversions = await fetchFromCRM();
  
  const conversions = crmConversions.map(crm => ({
    conversionActionResourceName: 'customers/123/conversionActions/456',
    gclid: crm.gclid,
    conversionValue: crm.orderValue,
    conversionDateTime: crm.purchaseDate,
    currencyCode: 'USD',
    orderId: crm.orderId
  }));

  await client.bulkUploadConversions(conversions);
  console.log(`Uploaded ${conversions.length} CRM conversions`);
}

Functions Reference

This section consolidates the function-level documentation that previously lived in FUNCTIONS.md.

Conversion Functions

getConversionMetrics

Get detailed conversion metrics with attribution analysis.

const metrics = await getConversionMetrics(client, {
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  conversionActionId: '123456' // optional
});

// Returns: ConversionMetrics[]
// - totalConversions, totalValue, averageValue
// - Device breakdown, top keywords/campaigns
// - Conversion paths and attribution data

getConversionActions

List conversion actions with configuration details.

const actions = await getConversionActions(client, {
  includeHidden: false
});

// Returns conversion action configurations including:
// - Value settings, counting type, attribution model
// - Lookback windows and tag snippets

getAttributionModels

Compare attribution models for conversions.

const models = await getAttributionModels(client, {
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  conversionActionId: '123456'
});

// Returns AttributionModel comparisons with:
// - Current model performance
// - Alternative simulations
// - Impact on conversion credit distribution

getConversionPaths

Analyze multi-touch conversion paths.

const paths = await getConversionPaths(client, {
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  minPathLength: 2
});

// Returns ConversionPathAnalysis including:
// - Average path length and time to conversion
// - Top conversion paths
// - Channel assists and interactions

Campaign Functions

getCampaignPerformance

Comprehensive campaign performance with trends.

const campaigns = await getCampaignPerformance(client, {
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  campaignIds: ['123', '456'], // optional
  includeRemoved: false
});

// Returns CampaignPerformance[] with:
// - Metrics: impressions, clicks, CTR, conversions, ROAS
// - Trends: period-over-period changes
// - Optimization score and recommendations
// - Impression share metrics

getAuctionInsights

Deep-dive competitor metrics for campaigns.

const insights = await getAuctionInsights(client, {
  customerId: '123-456-7890',
  campaignIds: ['123'],
  dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' }
});

// Returns competitor impression share, overlap rate, and outranking share.

getCampaignRecommendations

Retrieve Google Ads optimization recommendations.

const recommendations = await getCampaignRecommendations(client, {
  customerId: '123-456-7890',
  filters: ['KEYWORD'],
});

Keyword Functions

getKeywordPerformance

Detailed keyword metrics with quality scores.

const keywords = await getKeywordPerformance(client, {
  customerId: '123-456-7890',
  dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' },
  metrics: {
    includeQualityScore: true,
    includeSearchImpressionShare: true,
  },
});

getNegativeKeywords

Retrieve negative keyword lists per campaign.

const negatives = await getNegativeKeywords(client, {
  customerId: '123-456-7890',
  campaignId: '9876543210'
});

Audience Functions

getAudiencePerformance

Audience performance with segmentation.

const audiences = await getAudiencePerformance(client, {
  customerId: '123-456-7890',
  segments: ['DEVICE', 'LOCATION']
});

getCustomerMatchLists

Customer match audience metadata and size estimates.

const lists = await getCustomerMatchLists(client, {
  customerId: '123-456-7890'
});

Competitive Intelligence

getAuctionInsights

Retrieve auction insights for account- or campaign-level analysis (see example above).

getSearchImpressionShare

const impressionShare = await getSearchImpressionShare(client, {
  customerId: '123-456-7890',
  campaignId: '123',
  dateRange: { startDate: '2024-01-01', endDate: '2024-01-31' }
});

Advanced Analytics

getSegmentPerformance

const segments = await getSegmentPerformance(client, {
  customerId: '123-456-7890',
  dimensions: ['DEVICE', 'DAY_OF_WEEK'],
  metrics: ['impressions', 'clicks', 'conversions']
});

runAdvancedQuery

Execute custom GAQL queries with typed responses.

const report = await runAdvancedQuery(client, {
  customerId: '123-456-7890',
  query: `
    SELECT
      campaign.id,
      campaign.name,
      metrics.conversions,
      metrics.conversion_value
    FROM campaign
    WHERE segments.date DURING LAST_30_DAYS
  `,
});

TypeScript Support

Full TypeScript definitions included:

import type {
  GoogleAdsCustomer,
  GoogleAdsCampaign,
  GoogleAdsConversionAction,
  ConversionUpload,
  GoogleAdsQuery,
  GoogleAdsReport,
  ReportOptions,
  GoogleAdsOperationResult,
  GoogleAdsListResult
} from '@akson/cortex-google-ads';

Requirements

  • Node.js ≥18.0.0
  • Google Ads API access and developer token
  • Service account with Google Ads API permissions
  • Valid Google Ads customer account

License

MIT