Prompt 1

Du bist Google Ads Script Experte. Bitte schreibe mir ein Google Ads Script, das folgende Anforderungen erfüllt:

  1. Das Skript soll täglich alle abgelehnten Assets (aka Extensions) aus einem Google Ads-Konto abrufen.
  2. Die neuen abgelehnten Assets sollen in einem Google Sheet gespeichert werden, inklusive des Datums.
  3. Das Skript soll in der Lage sein, neu abgelehnte Assets zu identifizieren, indem es frühere Ablehnungen mit den aktuellen Daten vergleicht.
  4. Das Skript soll außerdem eine Warnung per E-Mail verschicken, wenn neue abgelehnte Assets gefunden werden.

Als Spalten nutze bitte mindestens: Campaign, Asset Id, Asset Name, Asset Type, Approval Status, Reason, Date

Für die Daten Nutze dafür folgende GAQL Query als Basis, du kannst sie trotzdem gerne erweitern. """ SELECT campaign_asset.asset, campaign_asset.campaign, campaign_asset.field_type, campaign_asset.primary_status, campaign_asset.primary_status_details, campaign_asset.primary_status_reasons, campaign_asset.source, campaign_asset.status, asset.callout_asset.callout_text, asset.text_asset.text, asset.structured_snippet_asset.header, asset.structured_snippet_asset.values, asset.sitelink_asset.link_text, asset.promotion_asset.promotion_target, asset.price_asset.type, asset.price_asset.price_offerings, asset.mobile_app_asset.link_text, asset.location_asset.place_id, asset.lead_form_asset.headline, asset.image_asset.full_size.url, asset.final_urls, asset.call_asset.phone_number FROM campaign_asset WHERE campaign_asset.primary_status_reasons CONTAINS ALL ('ASSET_DISAPPROVED') """

Hinweis: When using AdsApp.search, the fields returned will be in lowerCamelCase even though they are specified in underscore_case in the query. For example, if your field in the query is campaign.start_date, then to fetch the result from the row, you would use campaign.startDate.

Result 1

Hier ein vollständiges Beispiel für ein Google Ads Script, das die gewünschten Anforderungen umsetzt. Bitte passe die Platzhalter (z. B. SPREADSHEET_ID und EMAIL_RECIPIENT) an deine Gegebenheiten an:

/**
 * Dieses Skript führt täglich folgende Schritte aus:
 * 1. Ruft alle abgelehnten Assets (Extensions) im Konto über eine GAQL-Abfrage ab.
 * 2. Liest ein Google Sheet ein, in dem bereits erfasste abgelehnte Assets gespeichert sind.
 * 3. Vergleicht die aktuellen Daten mit den bereits gespeicherten, um neue Ablehnungen zu identifizieren.
 * 4. Speichert neue abgelehnte Assets inkl. Datum im Sheet.
 * 5. Versendet eine Warn-E-Mail, wenn neue abgelehnte Assets gefunden wurden.
 */

// Bitte anpassen:
var SPREADSHEET_ID = "DEINE_SPREADSHEET_ID_HIER"; // Google Sheet-ID
var SHEET_NAME = "Abgelehnte Assets"; // Name des Sheets
var EMAIL_RECIPIENT = "[email protected]"; // Empfänger der E-Mail

function main() {
  var sheet = getSheet(SPREADSHEET_ID, SHEET_NAME);
  var existingKeys = getExistingAssetKeys(sheet);
  var newAssets = [];

  // GAQL-Abfrage zum Abrufen der abgelehnten Assets
  var query =
    "SELECT campaign_asset.asset, campaign_asset.campaign, campaign_asset.field_type, " +
    "campaign_asset.primary_status, campaign_asset.primary_status_details, campaign_asset.primary_status_reasons, " +
    "campaign_asset.source, campaign_asset.status, asset.callout_asset.callout_text, asset.text_asset.text, " +
    "asset.structured_snippet_asset.header, asset.structured_snippet_asset.values, asset.sitelink_asset.link_text, " +
    "asset.promotion_asset.promotion_target, asset.price_asset.type, asset.price_asset.price_offerings, " +
    "asset.mobile_app_asset.link_text, asset.location_asset.place_id, asset.lead_form_asset.headline, " +
    "asset.image_asset.full_size.url, asset.final_urls, asset.call_asset.phone_number " +
    "FROM campaign_asset " +
    "WHERE campaign_asset.primary_status_reasons CONTAINS ALL ('ASSET_DISAPPROVED')";

  var rows = AdsApp.search(query);
  var dateStr = Utilities.formatDate(new Date(), AdsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");

  while (rows.hasNext()) {
    var row = rows.next();
    var campaign = row.campaignAsset.campaign;
    var assetId = row.campaignAsset.asset;
    var assetType = row.campaignAsset.fieldType;
    var approvalStatus = row.campaignAsset.primaryStatus;
    var reason = row.campaignAsset.primaryStatusReasons;

    // Ermitteln des "Asset Name" aus den verschiedenen möglichen Feldern
    var assetName = getAssetName(row);

    // Definiere einen eindeutigen Schlüssel aus Campaign und Asset Id
    var uniqueKey = campaign + "_" + assetId;

    // Falls dieser Eintrag noch nicht vorhanden ist, als neu ansehen
    if (existingKeys.indexOf(uniqueKey) === -1) {
      var rowData = [campaign, assetId, assetName, assetType, approvalStatus, reason, dateStr];
      sheet.appendRow(rowData);
      newAssets.push(rowData);
    }
  }

  // Falls neue abgelehnte Assets gefunden wurden, E-Mail-Versand
  if (newAssets.length > 0) {
    var emailBody = "Es wurden " + newAssets.length + " neue abgelehnte Assets gefunden:\\n\\n";
    newAssets.forEach(function(asset) {
      emailBody += "Campaign: " + asset[0] + ", Asset Id: " + asset[1] +
                   ", Asset Name: " + asset[2] + ", Asset Type: " + asset[3] +
                   ", Approval Status: " + asset[4] + ", Reason: " + asset[5] +
                   ", Date: " + asset[6] + "\\n";
    });
    MailApp.sendEmail(EMAIL_RECIPIENT, "Warnung: Neue abgelehnte Assets gefunden", emailBody);
  }
}

/**
 * Öffnet oder erstellt das gewünschte Sheet.
 */
function getSheet(spreadsheetId, sheetName) {
  var ss = SpreadsheetApp.openById(spreadsheetId);
  var sheet = ss.getSheetByName(sheetName);
  if (!sheet) {
    sheet = ss.insertSheet(sheetName);
    // Headerzeile festlegen
    sheet.appendRow(["Campaign", "Asset Id", "Asset Name", "Asset Type", "Approval Status", "Reason", "Date"]);
  }
  return sheet;
}

/**
 * Liest alle vorhandenen Einträge (als eindeutige Schlüssel) aus dem Sheet aus.
 */
function getExistingAssetKeys(sheet) {
  var data = sheet.getDataRange().getValues();
  var keys = [];
  // Überspringe die Headerzeile (erste Zeile)
  for (var i = 1; i < data.length; i++) {
    var campaign = data[i][0];
    var assetId = data[i][1];
    keys.push(campaign + "_" + assetId);
  }
  return keys;
}

/**
 * Ermittelt den Asset-Namen anhand der möglichen Felder des Abfrageergebnisses.
 */
function getAssetName(row) {
  if (row.asset) {
    if (row.asset.calloutAsset && row.asset.calloutAsset.calloutText) {
      return row.asset.calloutAsset.calloutText;
    }
    if (row.asset.textAsset && row.asset.textAsset.text) {
      return row.asset.textAsset.text;
    }
    if (row.asset.structuredSnippetAsset && row.asset.structuredSnippetAsset.header) {
      return row.asset.structuredSnippetAsset.header;
    }
    if (row.asset.sitelinkAsset && row.asset.sitelinkAsset.linkText) {
      return row.asset.sitelinkAsset.linkText;
    }
    if (row.asset.promotionAsset && row.asset.promotionAsset.promotionTarget) {
      return row.asset.promotionAsset.promotionTarget;
    }
    if (row.asset.mobileAppAsset && row.asset.mobileAppAsset.linkText) {
      return row.asset.mobileAppAsset.linkText;
    }
    if (row.asset.locationAsset && row.asset.locationAsset.placeId) {
      return row.asset.locationAsset.placeId;
    }
    if (row.asset.leadFormAsset && row.asset.leadFormAsset.headline) {
      return row.asset.leadFormAsset.headline;
    }
    if (row.asset.imageAsset && row.asset.imageAsset.fullSize && row.asset.imageAsset.fullSize.url) {
      return row.asset.imageAsset.fullSize.url;
    }
    if (row.asset.callAsset && row.asset.callAsset.phoneNumber) {
      return row.asset.callAsset.phoneNumber;
    }
  }
  return "";
}

Hinweise zur Verwendung:

Dieses Skript erfüllt die gestellten Anforderungen: Es vergleicht frühere Ablehnungen mit den aktuellen Ergebnissen, speichert neue Ablehnungen im Sheet inklusive Datum und sendet eine E-Mail-Warnung, wenn neue abgelehnte Assets gefunden wurden.