---
title: "Recipe: Ad Network Feedback, Finally Worth Serving"
description: Streamline ad network feedback with Google Ads and LinkedIn Ads integration for accurate conversion tracking and improved campaign performance.
image: https://tomdelaney.us/hubfs/Gemini_Generated_Image_eyl073eyl073eyl0.png
---

[![White Modern Minimalist Signature Brand Logo (Website) (4)](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/White%20Modern%20Minimalist%20Signature%20Brand%20Logo%20(Website)%20(4).png)](https://tomdelaney.us)

- [Resume](https://tomdelaney.us/resume)
- [Blog](https://tomdelaney.us/blog)
- [Portfolio](https://tomdelaney.us/portfolio)

[Contact Me](https://tomdelaney.us/contact-me)

Search **the website**

# Recipe: **Ad Network Feedback, Finally Worth Serving**

![](//24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/raw_assets/public/@marketplace/if_else_agency/Aesthetics/assets/images/icons/arrow-down.svg)

![Ads Connector](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_eyl073eyl073eyl0.png)

## Share this **post**

# Recipe: Ad Network Feedback, Finally Worth Serving

**Yield:** Google Ads and LinkedIn Ads that know what actually happened after the click

**Prep time:** Several days (Google developer token review adds real wait time)

**Active time:** Half a day to wire up

**Difficulty:** Intermediate — the tech is approachable, the process is not

[view the project brief](https://tomdelaney.us/ads-connector-portfolio)

---

## Ingredients

**Google Ads**

- Google Ads manager account with developer token (standard access requires Google review)
- OAuth 2.0 credentials (client ID, client secret, refresh token)
- Conversion actions created in Google Ads Manager (one per event type)
- GCP project with Secret Manager enabled
- Cloud Function deployment

**LinkedIn Ads**

- LinkedIn Campaign Manager account
- Conversion events created in Signals Manager (one per event type)
- Direct API access token from Signals Manager

**HubSpot**

- Operations Hub (required for custom coded workflow actions)
- Three workflows: Account Signup, Paid Upgrade, Enterprise Deal Closed

---

## Method

### 1. Set up Google Ads credentials

Apply for a Google Ads developer token in your manager account. Standard access — required to call the API in production — goes through a Google review of your use case. Budget time for this.

Once approved, create OAuth 2.0 credentials in Google Cloud Console and generate a refresh token. Store the full credential set in GCP Secret Manager:

```
google-ads-client-id google-ads-client-secret google-ads-refresh-token google-ads-developer-token google-ads-customer-id cloud-function-api-key   ← any secure random string, used to authenticate HubSpot 
```

### 2. Create conversion actions in Google Ads

In Google Ads Manager, create a conversion action for each event type (signup, upgrade, deal closed). Each gets a numeric conversion action ID — you'll pass these in the HubSpot workflow payload.

### 3. Deploy the Cloud Function

Deploy `index.js` as a Google Cloud Function. Set `GCP_PROJECT_ID` as an environment variable.

The function:

- Validates the `x-api-key` header against the secret
- Pulls credentials from Secret Manager on cold start, then caches them
- Refreshes an OAuth access token per invocation
- SHA-256 hashes email and phone before sending
- Posts to the Google Ads Conversions API

Payload shape HubSpot sends:

```
{   "email": "contact@example.com",   "phone": "+15555550100",   "gclid": "abc123",   "googleAdsConversionActionId": "123456789",   "conversionValue": 5000,   "conversionCurrency": "USD"} 
```

`conversionValue` accepts a deal amount for closed won events, or a static fallback for signups and upgrades.

### 4. Set up LinkedIn conversion events

In LinkedIn Campaign Manager: **Data → Signals Manager → Direct API**

Create a conversion event for each workflow. Each gets a numeric ID that forms part of the conversion URN:

```
urn:lla:llaPartnerConversion: 
```

Generate an access token from the same interface. Store it in HubSpot's secret store as `linkedin_access_token`.

### 5. Add the HubSpot custom coded action

For each workflow, add a custom coded action using `workflow-action.js`. Set the correct `` for that workflow. Configure input properties:

```
email       → Contact email firstName   → Contact first name lastName    → Contact last name 
```

The action returns `api_status` (success/error) and `api_response` as output fields — useful for workflow branching on failure.

### 6. Wire up the HubSpot workflows

Each workflow runs two actions in sequence:

1. **Webhook action** → Cloud Function URL, `x-api-key` header, conversion-specific payload
2. **Custom coded action** → LinkedIn, with the matching conversion ID

Build one workflow, confirm it fires correctly, then clone and adjust the conversion IDs for the other two.

---

## Plating Notes

**Expect 12–24 hours before conversions appear** in ad network dashboards after a successful API response. This is normal. A missing conversion after an hour does not mean something is broken — check Cloud Function logs and LinkedIn API responses first before assuming failure.

**Google Ads test conversions** show up in a separate test account view. LinkedIn has no equivalent — you're testing against production data from the start.

**The Google developer token review** is the longest single step. Apply early. The review evaluates your use case and app setup before granting standard API access.

**Conversion signal quality improves over time.** The real payoff isn't immediate — it accumulates as the ad platforms collect enough signals to meaningfully adjust targeting. Give campaigns several weeks before evaluating lift.

---

**[github.com/Suixcity/hubspot-ads-connector](https://github.com/Suixcity/hubspot-ads-connector)**

*Part of a professional portfolio — [view the project brief](https://tomdelaney.us/ads-connector-portfolio)*

![Thomas Delaney](https://app.hubspot.com/settings/avatar/6aa77e4b15fadd044100136646f8d3a4)

[**Thomas Delaney**](https://tomdelaney.us/blog/author/thomas-delaney)

People are talking about this blog post

### Related blog posts

[![Recipe: Channel Partners, Matched and Plated at the Table](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_vpvzanvpvzanvpvz.png) Recipe: Channel Partners, Matched and Plated at the Table on Mar 6, 2026 11:53:11 AM](https://tomdelaney.us/blog/recipe-channel-partners-matched)

[![Recipe: Contracts to CRM, Delivered While Still Hot](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_lhgafjlhgafjlhga.png) Recipe: Contracts to CRM, Delivered While Still Hot on Mar 5, 2026 11:29:31 AM](https://tomdelaney.us/blog/recipe-contracts-delivered-while-still-hot)

[![Recipe: Sanctions Screening, Baked into Every Workflow](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_r3fopir3fopir3fo.png) Recipe: Sanctions Screening, Baked into Every Workflow on Mar 5, 2026 9:41:54 AM](https://tomdelaney.us/blog/recipe-sanctions-screening)

## Related **blog posts**

<https://tomdelaney.us/blog/recipe-channel-partners-matched>

![](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_vpvzanvpvzanvpvz.png)

**Recipe: Channel Partners, Matched and Plated at the Table**

 Recipe: Channel Partners, Matched and Plated at the Table Yield: Partner assignments that live in HubSpot, not in...

 Read more

<https://tomdelaney.us/blog/recipe-contracts-delivered-while-still-hot>

![](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_lhgafjlhgafjlhga.png)

**Recipe: Contracts to CRM, Delivered While Still Hot**

 Read more

<https://tomdelaney.us/blog/recipe-sanctions-screening>

![](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/Gemini_Generated_Image_r3fopir3fopir3fo.png)

**Recipe: Sanctions Screening, Baked into Every Workflow**

 Read more

![White Modern Minimalist Signature Brand Logo (Website) (5)](https://24279033.fs1.hubspotusercontent-na1.net/hubfs/24279033/White%20Modern%20Minimalist%20Signature%20Brand%20Logo%20(Website)%20(5).png)

This website is the personal project of Thomas Delaney and the views and thoughts expressed are strictly his own and do not represent any other entity. 

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Thomas Delaney",
    "url" : "https://tomdelaney.us/blog/author/thomas-delaney"
  },
  "dateModified" : "2026-03-06T15:52:28.174Z",
  "datePublished" : "2026-03-06T15:49:30.000Z",
  "headline" : "Recipe: Ad Network Feedback, Finally Worth Serving",
  "image" : [ "https://tomdelaney.us/hubfs/Gemini_Generated_Image_eyl073eyl073eyl0.png" ],
  "mainEntityOfPage" : {
    "@id" : "https://tomdelaney.us/blog/recipe-ad-network-feedback-finally-worth-serving",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://tomdelaney.us/hubfs/White%20Modern%20Minimalist%20Signature%20Brand%20Logo.png"
    }
  }
}
```