In order to make informed decisions for your Google Ads accounts, we must track conversions within the account. Below are instructions for pulling conversions from Google Analytics and setting up Google Ads Website Call Tracking.
Last Updated on January 30, 2025
Importing Google Analytics Goals to Google Ads
Be careful when pulling goals over. Be sure that your goals are number double counting within the Ads account for whatever reason. Always make sure a value is associated with each goal – the best practice is to have the value recorded in Google Analytics and then have the Google Ads settings pull the value from Analytics.
Setting Up Conversions Using GTM
This video gives an example of setting up “direct” conversions in Google Ads using GTM. Google claims that these are “15% more accurate” than imported conversions. The downside is that these conversion actions are not recorded in Analytics and are only reported within Ads.
Google Ads Website Call Tracking (Google Ads DNI)
Also known as Google DNI (Dynamic Number Insertion). Google swaps out the number on the client’s website for a forwarding number whenever someone visits the client’s landing page from Google Ads. When a visitor calls that number, Google tracks that as a call conversion. We set this up using Google Ads and Google Tag Manager.
Send Google Ads Calls to Google Analytics
Create a script to run daily at 2am that sends call data from Google Ads to Google Analytics – https://www.adaptworldwide.com/insights/2017/adwords-call-tracking-in-google-analytics
In the event this article goes down you can find the script to here as well. Basically you add a script in Google Ads and paste this code in there and update the Google Analytics UA number.
You will then need to create an event goal in Google Analytics with the following settings:
[js]
/* Created by Analysts at SearchStar. Written by Sian Miller, @sianmiller141 *
* AdWords Call Tracking in Google Analytics – Runs campaign performance report for the previous day, and returns the number of "calls" tracked and which campaign they are attributed to. *
* This data is sent to GA via the Measurement Protocol in the form of an Event. Set up an event based Goal in GA using your parameters (conversion name). *
* Set this script to run daily at 2am. *
*/
function main(){
//variables for report
var dateRange = 'YESTERDAY';
var columns = ['CampaignName','ConversionTypeName','Conversions','ConversionValue'];
var columnsStr = columns.join(',') + " ";
//run report
var reportData = AdWordsApp.report(
'SELECT ' + columnsStr +
'FROM CAMPAIGN_PERFORMANCE_REPORT ' +
'WHERE ConversionTypeName CONTAINS_IGNORE_CASE "calls" ' + //filter to just conversions with "calls" in the name, adjust this to match your conversion names
'DURING ' + dateRange);
var rows = reportData.rows()
//function to create random UUID
function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
//variables for measurement protocol
var GAID = 'UA-XXXXXX-X'; //replace this with your GA Property ID
var campaignSource = 'google'; //ensures the GA goal is attributed to Google
var campaignMedium = 'cpc'; //ensures the GA goal is attributed to paid search
var eventCat = 'adwords%20conversion'; //change this to edit the Event Category, maintaining URL Encoding
var postURL = 'https://www.google-analytics.com/collect';
var queueTime = 12600000; //3.5 hours in milliseconds so we can send the data at 2am and it is assigned to the previous day
//loop to build measurement protocol from each row of report data
while (rows.hasNext()){
var row = rows.next();
var campaignName = encodeURI(row['CampaignName']); //encodes for use in URL
var conversionType = encodeURI(row['ConversionTypeName']).toLowerCase(); //encodes for use in URL and makes them lowercase to match existing GA event structure, change if necessary
var conversionCount = Math.round(row['Conversions']); //round the number of conversions to a whole number, remove rounding if you are using a fractional attribution model
var conversionValue = row['ConversionValue']/conversionCount; //the value of each individual conversion – *on the assumption that all conversions have the same value
//for each conversion, create & send measurement protocol
for (i=0; i<conversionCount; i++){
//generate random client id
var clientID = uuid();
//construct measurment protocol payload
var payload = 'v=1&t=event&ni=1' +
'&tid=' + GAID +
'&cid=' + clientID +
'&cs=' + campaignSource +
'&cm=' + campaignMedium +
'&cn=' + campaignName +
'&ec=' + eventCat +
'&ea=' + conversionType +
'&ev=' + conversionValue +
'&qt=' + queueTime;
//log URL for debugging
Logger.log(postURL+payload);
//send measurement protocol
var options = {
'method': 'POST',
'payload': payload
};
UrlFetchApp.fetch(postURL,options);
}
}
}
/* Be aware that this script causes “fake” traffic to be sent to your GA profile *
* This can inflate the number of users tracked, cause sessions per user to decrease and cause the percentgae of new sessions to rise. *
* Exclude this “fake” traffic using a user based segment when reporting on these metrics. *
*/
[/js]