Posts tagged with google-ads-script

Really sorry if this is the basic question.

I have been searching for two days to find the documentation/sample function to use in apps script that fetches google ads accounts, reports, etc. what I have found all, is the documentation for languages like PHP, python, c, etc and they are giving me tough time understanding them. I know integrating google ads in google sheets is possible as google itself has published an add-on to fetch the reports but can't find any hint either in this platform or in the official documentation. any help will be highly appreciated.

Note: I am seeking help for integrating google ads in google sheets through apps script not ads script. I know there are functions available for ads script even in the documentation but none I found for apps script to the best of my research.

Thanks.

I've tried to write an ads-script that returns all the child accounts which had zero impression in the latest available hour (3 hours ago)

However the script returns false negative results. Meaning there was an account with zero impressions, but the script flagged it as non-zero.

What am I missing?

function main() {   Logger.log("now.getHours(); = "+new Date().getHours());   var past = new Date(new Date().getTime() - HOURS_BACK * 3600 * 1000);   var pastHour = past.getHours();   var pastDateStr = getDateStringInTimeZone(past, 'yyyy-MM-dd');   query = "SELECT customer.id, metrics.impressions, segments.hour FROM customer WHERE metrics.impressions = 0 AND segments.hour = " + pastHour + " AND segments.date = '" + pastDateStr + "'";   Logger.log("query " + query);   updateAccountsInParallel(); } function updateAccountsInParallel() {   // You can use this approach when you have a large amount of processing   // to do in each of your client accounts.   // Select the accounts to be processed. You can process up to 50 accounts.   var accountSelector = AdsManagerApp.accounts();   // Process the account in parallel. The callback method is optional.   accountSelector.executeInParallel('processAccount', 'allFinished', query); } /**  * Process one account at a time. This method is called by the executeInParallel  * method call in updateAccountsInParallel function for every account that  * it processes.  */ function processAccount(query) {   // executeInParallel will automatically switch context to the account being   // processed, so all calls to AdsApp will apply to the selected account.   var customerId = AdsApp.currentAccount();   if (excludedAccountIds.includes(customerId)) return null;   var currentZeroImpressionRows = AdsApp.report(query, { apiVersion: 'v10' });   var rows = currentZeroImpressionRows.rows();   var accounts = [];   while (rows.hasNext()) {     var row = rows.next();     Logger.log(JSON.stringify(row));     accounts = accounts.push(row["customer.id"] + " " + row["customer.descriptive_name"]);   }     // Optional: return a string value. If you have a more complex JavaScript   // object to return from this method, use JSON.stringify(value). This value   // will be passed on to the callback method, if specified, in the   // executeInParallel method call.   return accounts.length > 0 ? account.getCustomerId() + " " + account.getName() : null; } /**  * Post-process the results from processAccount. This method will be called  * once all the accounts have been processed by the executeInParallel method  * call.  *  * @param {Array.<ExecutionResult>} results An array of ExecutionResult objects,  * one for each account that was processed by the executeInParallel method.  */ function allFinished(results) {   var todayZeroCostAccounts = [];   for (var i = 0; i < results.length; i++) {     // Get the ExecutionResult for an account.     var result = results[i];     //Logger.log('Customer ID: %s; status = %s.', result.getCustomerId(),     //  result.getStatus());     // Check the execution status. This can be one of ERROR, OK, or TIMEOUT.     if (result.getStatus() == 'ERROR') {       Logger.log("-- Failed with error: '%s'.", result.getError());     } else if (result.getStatus() == 'OK') {       // This is the value you returned from processAccount method. If you       // used JSON.stringify(value) in processAccount, you can use       // JSON.parse(text) to reconstruct the JavaScript object.       var retval = result.getReturnValue();       if (retval != null) {         Logger.log('%s had 0 impressions in that hour.', result.getCustomerId());         todayZeroCostAccounts.push(retval);       }       else       {        Logger.log('%s had positive impressions in that hour.', result.getCustomerId());       }            } else {       // Handle timeouts here.     }   } } 

I've seen a slide which advises to cache with a dictionary. In which case we can even get the same budget twice? What does it save?

The API docs state that:

getBudget() Returns the budget of the campaign. In order to change the campaign's budget,  

I am using Google Ads to track purchase conversions on my Ecommerce website. When a user clicks on my Google Ad for a product and then makes the purchase and lands on the thank you page, the conversion event is triggered and sends google the data so that it knows that an order has been placed and it can track the conversion.

My problem is that EACH time that same thank-you page is loaded with that users order id token, it fires that script and Google tracks that as another conversion. This should only be happening once, this should only happen the first time the page is accessed with that order token.

Take this url below for example. A user saw my Google Ad and then clicked on it and purchased and then he landed on the thank you page. At this point it was tracked as a conversion. https ://mywebsite.com/purchase/thank-you/order/1001632bfd1c-2x5a-701t-1xs90a0a4444

Sometime later the same day or 20 days later, the user opens up the browser on his phone and that page reloads, or the user wants to check his browsing history and clicks on this url. As soon as he lands on it, the script will fire once again and count that as a conversion for the ad he originally clicked on.

Is there a way that I can make it so that the script only fires the first time a url loads? Merchants who are using Shopify simply wrap the conversion event script with {% If First_time_accessed %} in Liquid which is Shopify's language. This makes it so that even if the user reloads that same url, the script won't fire again to track that page visit as another conversion.

How do I do this type of logic if I am developing my site in ASP.net using C# MVC ? Is there some javascript I can wrap my event snippet with to make it work like Shopify does it? I have searched for this but keep only finding info on how to do it on Shopify. Note...I am not using Tag Manager, I want to just leave the event snippet on my page without having to set up anything in tag manager.

Here is my script currently:

<!-- Global site tag (gtag.js) - Google Analytics -->   <script async src="https://www.googletagmanager.com/gtag/js?id=G-M3WT222222"></script> <script>     window.dataLayer = window.dataLayer || [];     function gtag() { dataLayer.push(arguments); }     gtag('js', new Date());     //conversion tracking for Google Analytics     gtag('config', 'G-M3WT222222');     //conversion tracking from Google Ads     gtag('config', 'AW-12057888501'); </script> <!-- Event snippet for MYwebsite Purchase conversion page --> <script>         gtag('event', 'conversion', {             'send_to': 'AW-12057888501/x0QzZp_vliJUHNC-B08Zx',             'value': @ViewBag.Display_subtotal,             'currency': '@ViewBag.Display_currencyAbbreviation',             'transaction_id': '@ViewBag.Display_invoiceNumber'         }); </script> 

This is an example of how Shopify does this. Notice the code is wrapped in some liquid code shown here {% if first_time_accessed %}

{% if first_time_accessed %} <!-- Event snippet for Purchases Shopify conversion page --> <script>   gtag('event', 'conversion', {   'send_to': 'AW-2035565011/frthgrt455_151f5rfc',   'transaction_id': '{{ order_number  }}'   }); </script> {% endif %} 

8/3/2022 13:40:32   NotImplementedError: This is not implemented yet. For currently supported API, see: https://developers.google.com/google-ads/scripts-beta/docs/reference/adsapp/adsapp at Ha (adsapp_compiled:298:11) at new $y (adsapp_compiled:13027:5) at qC.newVideoAd (adsapp_compiled:15250:12) at Object.<anonymous> (adsapp_compiled:18396:54) 
     var youtubeVideoId = "youtubeVideoId";     var adGroupName = "adGroupName" // name of my target video ad group     var displayUrl = "display-url.com";     var finalUrl = "https://final-url.com";     var assetOperation = AdsApp.adAssets().newYouTubeVideoAssetBuilder()         .withName(adName)         .withYouTubeVideoId(youtubeVideoId)         .build();     var videoAsset = assetOperation.getResult();          var videoAdGroup = AdsApp.videoAdGroups()         .withCondition(`Name = '${adGroupName}'`)         .withLimit(1)         .get()         .next();          var videoAdOperation = videoAdGroup.newVideoAd().inStreamAdBuilder()         .withVideo(videoAsset)         .withAdName(adName)         .withDisplayUrl(displayUrl)         .withFinalUrl(finalUrl)         .build()         .getResult();          // Code crash before next statement     if(videoAdOperation.isSuccessful()) {         var videoAd = videoAdOperation.getResult();         Logger.log("VideoAd " + videoAd.getName() + " created.");     } else {         Logger.log(videoAdOperation.getErrors());     } 

Code breaks after videoAdGroup.newVideoAd().inStreamAdBuilder().

Following the google ads script docs everything should works nice.

But when I compile the script, I always get the next error:

I have just found in a Google ads scripts forum somebody who has the same problem here but no solution.