Recipe: Ad Network Feedback, Finally Worth Serving
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
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-keyheader 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:
- Webhook action → Cloud Function URL,
x-api-keyheader, conversion-specific payload - 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
Part of a professional portfolio — view the project brief