DOŁĄCZ DO GRUPY
BEZPŁATNY AUDYT
SKRYPT PMAX
NEWSLETTER

Zaawansowane Google Ads

5,001 członków

Dołącz do naszej społeczności ekspertów Google Ads i zyskaj dostęp do zaawansowanych strategii, wsparcia specjalistów i inspirujących case studies.

Prywatna grupa - Tylko zatwierdzeni członkowie

Nie jesteś pewny, czy Twoje reklamy działają tak, jak powinny?

Umów się na bezpłatny audyt konta Google Ads

Profesjonalna analiza

Szybki kontakt i konkretne informacje zwrotne.

Analiza efektywności
Weryfikacja Strategii
Praktyczne rekomendacje
Propozycja współpracy

Chcesz lepiej zrozumieć działanie kampanii Performance Max?

PMax Channels Analyzer

Darmowy skrypt dla Google Ads

Analizuj wydatki i konwersje z poszczególnych kanałów w kampaniach Performance Max.

Podział na kanały
Szczegółowe statystyki
Łatwa instalacja
Automatyczne raporty

Zapisz się na newsletter i otrzymuj praktyczne porady oraz narzędzia, które usprawnią twoje konto reklamowe.

Skrypt Google Ads: Easy LinkChecker

Easy Link Checker to skrypt Google Ads, który weryfikuje, czy nasze strony zwracają błąd 404.

Reklamy Google mają wbudowany system wykrywania tego typu błędów. Niestety nie zawsze działa on dostatecznie szybko i czasami płacimy za kliknięcia, które prowadzą do niedziałającej strony.

Dodatkowe narzędzie tego rodzaju pomoże nam rozwiązać ten problem.

Koncepcja aplikacji jest podobna do tej w oficjalnym skrypcie przygotowanym przez Google.

Różnica jest taka, że konfiguracja została uproszczona do minimum – wystarczy tylko adres e-mail. Rozwiązanie nie wprowadza też żadnych modyfikacji w kampaniach. Oficjalna wersja dodaje etykiety do każdego sprawdzonego elementu, co utrudnia analizowanie historii zmian na koncie.

Poniższy skrypt wykonuje dwa zadania:

  1. Sprawdza wszystkie linki z kampanii tekstowych, które otrzymały wczoraj > 0 wyświetleń
  2. Sprawdza wszystkie linki z rozszerzeń do podstron, które otrzymały w ostatnich 30 dniach > 0 wyświetleń

Jeśli któryś z nich zwróci błąd 404, to otrzymamy e-mail z nazwą kampanii i grupy reklam.

Harmonogram: raz dziennie
Konfiguracja : wstaw swój e-mail do zmiennej EMAIL


Po więcej na temat Skryptów zapraszam na grupę FB o automatyzacji:
https://www.facebook.com/groups/skrypty.google.ads


Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/*
Copyright 2019 Krzysztof Bycina, www.LiveAds.pl
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//Configuration:
var EMAIL = "ENTER YOUR EMAIL HERE";
//End of the configuration
var badLandingPages = [];
var badSiteLinks = [];
var iterator = -1;
//It is possible to add headers exceptions here
var options =
{
"muteHttpExceptions": true,
};
function main() {
checkTheAdsData();
checkTheSitelinksData();
if (badLandingPages.length || badSiteLinks.length) {
sendEmails();
} else {
Logger.log("All landing pages look ok!");
}
}
//Check links from the ads
function checkTheAdsData() {
var report = AdWordsApp.report("SELECT CampaignName, AdGroupName, EffectiveFinalUrl, Impressions " +
"FROM FINAL_URL_REPORT " +
"WHERE Impressions > 0 " +
"DURING YESTERDAY ");
var rows = report.rows();
while (rows.hasNext()) {
iterator++
var row = rows.next();
var response = UrlFetchApp.fetch(row['EffectiveFinalUrl'], options)
//Is the link broken?
if (response.getResponseCode() != 200) {
badLandingPages[iterator] = (response.getResponseCode() + " >> " + row['CampaignName'] + " >> " + row['AdGroupName'] + ">>" + row['EffectiveFinalUrl']);
Logger.log(badLandingPages[iterator]);
}
}
}
//Check links from Sitelinks
function checkTheSitelinksData() {
var sitelinkSelector = AdsApp.extensions()
.sitelinks()
.withCondition("Impressions > 0")
.forDateRange("LAST_30_DAYS");
var sitelinkIterator = sitelinkSelector.get();
while (sitelinkIterator.hasNext()) {
iterator++
var sitelink = sitelinkIterator.next();
var response = UrlFetchApp.fetch(sitelink.urls().getFinalUrl(), options)
//Is the link broken?
if (response.getResponseCode() != 200) {
badSiteLinks[iterator] = (response.getResponseCode() + " >> SiteLink >>" + sitelink.getLinkText() + ">>" + sitelink.urls().getFinalUrl());
}
}
}
function validateEmail(email) {
var key = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (key.test(email) === false) {
throw new Error('You must eneter a valid email address to run the script!')
}
}
function sendEmails() {
badLandingPages = badLandingPages.filter(Boolean);
MailApp.sendEmail(EMAIL, AdWordsApp.currentAccount().getName() + ' has Landing Pages with broken links',
'Hi, \n\nYou have broken links. Please, check these Campaigns and Ad groups:\n\n' + badLandingPages.join("\n") + '\n\n' + badSiteLinks.join("\n"));
}
/* Copyright 2019 Krzysztof Bycina, www.LiveAds.pl Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ //Configuration: var EMAIL = "ENTER YOUR EMAIL HERE"; //End of the configuration var badLandingPages = []; var badSiteLinks = []; var iterator = -1; //It is possible to add headers exceptions here var options = { "muteHttpExceptions": true, }; function main() { checkTheAdsData(); checkTheSitelinksData(); if (badLandingPages.length || badSiteLinks.length) { sendEmails(); } else { Logger.log("All landing pages look ok!"); } } //Check links from the ads function checkTheAdsData() { var report = AdWordsApp.report("SELECT CampaignName, AdGroupName, EffectiveFinalUrl, Impressions " + "FROM FINAL_URL_REPORT " + "WHERE Impressions > 0 " + "DURING YESTERDAY "); var rows = report.rows(); while (rows.hasNext()) { iterator++ var row = rows.next(); var response = UrlFetchApp.fetch(row['EffectiveFinalUrl'], options) //Is the link broken? if (response.getResponseCode() != 200) { badLandingPages[iterator] = (response.getResponseCode() + " >> " + row['CampaignName'] + " >> " + row['AdGroupName'] + ">>" + row['EffectiveFinalUrl']); Logger.log(badLandingPages[iterator]); } } } //Check links from Sitelinks function checkTheSitelinksData() { var sitelinkSelector = AdsApp.extensions() .sitelinks() .withCondition("Impressions > 0") .forDateRange("LAST_30_DAYS"); var sitelinkIterator = sitelinkSelector.get(); while (sitelinkIterator.hasNext()) { iterator++ var sitelink = sitelinkIterator.next(); var response = UrlFetchApp.fetch(sitelink.urls().getFinalUrl(), options) //Is the link broken? if (response.getResponseCode() != 200) { badSiteLinks[iterator] = (response.getResponseCode() + " >> SiteLink >>" + sitelink.getLinkText() + ">>" + sitelink.urls().getFinalUrl()); } } } function validateEmail(email) { var key = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (key.test(email) === false) { throw new Error('You must eneter a valid email address to run the script!') } } function sendEmails() { badLandingPages = badLandingPages.filter(Boolean); MailApp.sendEmail(EMAIL, AdWordsApp.currentAccount().getName() + ' has Landing Pages with broken links', 'Hi, \n\nYou have broken links. Please, check these Campaigns and Ad groups:\n\n' + badLandingPages.join("\n") + '\n\n' + badSiteLinks.join("\n")); }
/*
Copyright 2019 Krzysztof Bycina, www.LiveAds.pl

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//Configuration:
var EMAIL = "ENTER YOUR EMAIL HERE";
//End of the configuration

var badLandingPages = [];
var badSiteLinks = [];
var iterator = -1;

//It is possible to add headers exceptions here
var options =
      {
   "muteHttpExceptions": true,
      };



function main() {
    checkTheAdsData();
    checkTheSitelinksData();
    if (badLandingPages.length || badSiteLinks.length) {
        sendEmails();
    } else {
        Logger.log("All landing pages look ok!");
    }
}

//Check links from the ads
function checkTheAdsData() {
    var report = AdWordsApp.report("SELECT CampaignName, AdGroupName, EffectiveFinalUrl, Impressions " +
        "FROM FINAL_URL_REPORT " +
        "WHERE Impressions > 0 " +
        "DURING YESTERDAY ");

    var rows = report.rows();
    while (rows.hasNext()) {
        iterator++
        var row = rows.next();
        var response = UrlFetchApp.fetch(row['EffectiveFinalUrl'], options)

        //Is the link broken?
        if (response.getResponseCode() != 200) {
            badLandingPages[iterator] = (response.getResponseCode() + " >> " + row['CampaignName'] + " >> " + row['AdGroupName'] + ">>" + row['EffectiveFinalUrl']);
            Logger.log(badLandingPages[iterator]);
        }
    }
}

//Check links from Sitelinks
function checkTheSitelinksData() {
    var sitelinkSelector = AdsApp.extensions()
        .sitelinks()
        .withCondition("Impressions > 0")
        .forDateRange("LAST_30_DAYS");

    var sitelinkIterator = sitelinkSelector.get();
    while (sitelinkIterator.hasNext()) {
        iterator++
        var sitelink = sitelinkIterator.next();
        var response = UrlFetchApp.fetch(sitelink.urls().getFinalUrl(), options)

        //Is the link broken?
        if (response.getResponseCode() != 200) {
            badSiteLinks[iterator] = (response.getResponseCode() + " >> SiteLink >>" + sitelink.getLinkText() + ">>" + sitelink.urls().getFinalUrl());
        }
    }
}

function validateEmail(email) {
    var key = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

    if (key.test(email) === false) {
        throw new Error('You must eneter a valid email address to run the script!')
    }
}

function sendEmails() {
    badLandingPages = badLandingPages.filter(Boolean);
    MailApp.sendEmail(EMAIL, AdWordsApp.currentAccount().getName() + ' has Landing Pages with broken links',
        'Hi, \n\nYou have broken links. Please, check these Campaigns and Ad groups:\n\n' + badLandingPages.join("\n") + '\n\n' + badSiteLinks.join("\n"));
}

2 comments / Add your comment below

  1. Hej,

    do części sendEmails może warto dodać 2 warianty, obecny mail jeśli znajduje błędne url, drugi mail jeśli wszystkie url są ok ( na podstawie choćby Logger.log(„All landing pages look ok!) ) to wyślij mail z innym tematem i treścią: wszystko jest OK

    1. Cześć Maciej,

      dzięki za komentarz. Można by to dodać.
      Tutaj nie zrobiłem tego celowo, gdyż mam na kontach kilkadziesiąt aktywnych skryptów, które przysyłają maile tylko w niepokojących sytuacjach.

      Oszczędzam skrzynkę pocztową 🙂

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *