Question

Track Amplitude Conversions in Google Ads

  • 1 December 2023
  • 11 replies
  • 453 views

I’ve followed the instructions to use an event stream to push conversion events from Amplitude to Google Ads which can then be used to optimize my campaigns by following the instructions here: https://www.docs.developers.amplitude.com/data/destinations/google-ads-event-streaming/. However, I cannot get the settings to pass the validation when I test the connection.

I’m getting tripped up by the Google Cloud Service Account field and what to put in there. The instructions say “Enter your Base64 encoded Google Cloud Service Account.” and the link references the service account you need to create in Google Cloud Console. I’ve created this account and downloaded the appropriate json file, but it’s not clear what needs to be input into the Google Cloud Service Account field. I tried encoding the json file in Base64 and inputting that and I’ve tried the private key information (both encoded and not). None of which work. 

I get two kinds of errors...

When I input the entire base64 encoded json file:

`Cannot invoke "com.google.gson.JsonElement.getAsJsonObject()" because the return value of "com.google.gson.JsonObject.get(String)" is null`

When I input other versions of the json file or the private key

Exception on building a connector using: public static com.amplitude.integrations.connector.PartnerConnector com.amplitude.integrations.connector.partners.google.GoogleAdsConnector.createPartnerConnector(com.amplitude.integrations.connector.ConnectorInfo)

 



Does anyone know what needs to go in here and in what format? 

  • Should it be the whole json file? 
  • Just the private key? 
  • Some other piece of information from the json file? 

11 replies

Badge +1

I have the very same issue. Anyone got this connection working?

Badge +1

If it helps anyone, with the help of Support I found out that the testing call is failing because of the testing payload not being compatible with Google Ads API. If you switch it for an actual payload (or just enable the integration after skipping the test) it will work.

Badge

If it helps anyone, with the help of Support I found out that the testing call is failing because of the testing payload not being compatible with Google Ads API. If you switch it for an actual payload (or just enable the integration after skipping the test) it will work.

Thanks @Ondrej Peterka! What did you end up using for the `Google Cloud Service Account` field? The base64 encoding of the JSON file or what?

Badge

@Steve Lionais did you end up base64’ing the entire json file? just the private key? something else?

Badge

@Ondrej Peterka did you end up base64 encoding the entire json download from google, just the key, or something else?

Badge

I actually got this to work by base64-encoding the entire JSON file (on a Mac, you can just do `base64 -i <path_to_json_file>`). Running into auth issues though now with my service account that I'm trying to work through with Amplitude Support, but at least I see attempts going through now. If anyone knows how to get the service account added to the Google Ads account, that’d be helpful!

Badge +1

I run into auth issues as well, “authentication_error: NOT_ADS_USER”, which I have not been able to resolve. I have domain-wide delegation enabled in Google Cloud, but it seems that Ads expect the call to impersonate actual account with access permissions, and I have not figured out how to do that in Amplitude, nor in Google Cloud.

So I solved it with a workaround.

In Amplitude I create data table chart grouped by initial utm_gclid that I store as a user property, day, and with event count. 

Then I leverage https://www.docs.developers.amplitude.com/analytics/apis/dashboard-rest-api/#get-results-from-an-existing-chart and with a simple script I populate a google sheet daily, then set this sheet as upload source to adwords.
 

// In the url below insert the chart ID.
const url = 'https://amplitude.com/api/3/chart/[chart_id]/query';
const options = {
headers: {

// Base64 encoded string representing amplitude key and secret.
'Authorization': 'Basic [Base64 encoded auth key]'
}
};

// We get the data.
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());

const spreadsheet = SpreadsheetApp.getActive();

// Change the name of the sheet if needed.
const sheet = spreadsheet.getSheetByName('Import from Script');

// We clear the table.
sheet.clear;

// Now we parse the JSON.
// This works for any chart that is grouped by id and day and contains one column of values.
// Adapt this section as needed.

const rows = data.data.labels.map((label, i) => {
const value = data.data.values[i][0];
if (label.length > 0 && value > 0) {
const id = label[0];
const date = label[1];
return [id, date, value];
}
}).filter(row => row !== undefined);

// We write everything in the table.
const headers = ['ID', 'Date', 'Value'];
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
sheet.getRange(2, 1, rows.length, headers.length).setValues(rows);
}

 

Has anyone succeeded in setting up event streaming to google ads? Would love to see more details in the instructions on:

  • Which roles need to be enabled for the service account?
  • How exactly do I set up the permissions in my google ads / service account to enable streaming?

Any solutions on this? I am having the same issue when I enter in the Base64 version of the json file from the service account.

 

When I look at the debugger, the failed reason does have to do with the NOT_ADS_USER.

Hello everyone,

We're aware of issues with our Google Ads streaming integration and are currently working on improving the setup experience. We're currently scoping out the effort and hope to deliver an improved integration by early Q2. If you have any questions or are interested in being part of the Beta program for the new iteration, feel free to reach out at brandon.khoo@amplitude.com.

Thank you for your patience and feedback so far.

Badge

Any update here @Brandon Khoo ? Would love to test the beta, pretty blocked by this right now.

Reply