显示带有标签的帖子 报告. 显示所有帖子
显示带有标签的帖子 报告. 显示所有帖子

2014年7月27日星期日

异常无效的报告查询INVALID_PREDICATE_ENUM_VALUE有效

更新:这是一个 AdWords脚本小组关于该主题的说明.

几天前,我开始从脚本中收到很多错误,如下所示:
Exception: Invalid 报告 query: INVALID_PREDICATE_ENUM_VALUE: ACTIVE

如果其他人看到此问题,则与报告API的更新有关。以前,ACTIVE曾经是CampaignStatus的有效枚举值,由于其他所有东西都使用ENABLED,因此它总是有点异常。它已更新为与其他“状态”值匹配,但在此过程中,它破坏了所有使用“活动”状态的脚本。这是一个例子:
    ...
    var query = ['select',cols.join(','),'from',report,
                 'where CampaignStatus = ACTIVE',
                 'and AdGroupStatus = ENABLED',
                 'and Status = ACTIVE',
                 'during','TODAY'].join(' ');
    ...
这应该更改为:
    ...
    var query = ['select',cols.join(','),'from',report,
                 'where CampaignStatus = ENABLED',
                 'and AdGroupStatus = ENABLED',
                 'and Status = ENABLED',
                 'during','TODAY'].join(' ');
    ...

我正在尝试返回并更新以前的脚本,但是可能需要一些时间。
谢谢,
拉斯

2013年7月30日,星期二

确定何时创建广告,广告组,关键字或广告系列

知道何时创建广告(或实体) 不可能使用脚本。根本不会在AdWords中跟踪该信息。其次,最好的办法是找出您的广告何时首次开始获得展示,并假设它是在创建的时候(如果创建了广告,但没人看到它,那它确实存在吗?)。

因此,为了帮助我跟踪何时 广告 实体已创建,我将以下脚本放在一起以将标签应用于我 广告 具有第一印象日期的实体。这样我就能知道 广告 我创建的实体,并确保不要对太小的内容采取任何措施。我也可以对所有 广告 只需选择正确的标签,即可在AdWords用户界面中相对容易地在一天中建立实体。

谢谢,
拉斯



/**************************************
* Track Entity Creation Date
* Version 1.4
* Changelog v1.4
*  - Removed apiVersion from 报告 呼叫
* Changelog v1.3
*  - Updated script to handle all entities
* Changelog v1.2
*  - Fixed an issue with comparing 日期
* ChangeLog v1.1
*  - Updated logic to work with larger accounts
* Created By: 拉斯 Savage
* http://www.FreeAdWordsScripts.com
**************************************/
//All my 标签 will start with this. For example: Created:2013-05-01
var LABEL_PREFIX = 'Created:';
var DAYS_IN_REPORT = 30;
var ENTITY = 'ad'; //or 广告群组 or 关键词 or 运动
 
function main() {
  //First we get the impression history of our 实体
  var ret_map = getImpressionHistory();
  //Then we apply our 标签
  applyLabels(ret_map);
}
 
//Function to apply 标签 to the 广告 in an account
function applyLabels(ret_map) {
  var iter;
  if(ENTITY === 'campaign') { iter = AdWordsApp.campaigns().get(); }
  if(ENTITY === 'adgroup') { iter = AdWordsApp.adGroups().get(); }
  if(ENTITY === 'ad') { iter = AdWordsApp.ads().get(); }
  if(ENTITY === 'keyword') { iter = AdWordsApp.keywords().get(); }
  
  while(iter.hasNext()) {
    var 实体 = iter.next();
    var id = 实体.getId();
    if(ret_map[id]) {
      var 标签_name = LABEL_PREFIX+Utilities.formatDate(ret_map[id], AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
      createLabelIfNeeded(label_name);
      entity.applyLabel(label_name);
    }
  }
}
 
//This is a helper function to 创造 the 标签 if it does not already exist
function 创造LabelIfNeeded(name) {
  if(!AdWordsApp.labels().withCondition("Name = '"+name+"'").get().hasNext()) {
    AdWordsApp.createLabel(name);
  }
}
 
//A helper function to find the date days ago
function getDateDaysAgo(days) {
  var the_past = new Date();
  the_past.setDate(the_past.getDate() - days);
  return Utilities.formatDate(the_past,AdWordsApp.currentAccount().getTimeZone(),"yyyyMMdd");
}
 
//A helper function to compare 日期.
//Copied from: http://goo.gl/uW48a
function diffDays(firstDate,secondDate) {
  var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
  return Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay))); 
}
 
function getImpressionHistory() {
  var API_VERSION = { includeZeroImpressions : false };
  var first_date = new Date('10/23/2000');
  var max_days_ago = diffDays(first_date,new Date());
  var cols = ['Date','Id','Impressions'];
  var report = { 
    'campaign' : 'CAMPAIGN_PERFORMANCE_REPORT',
    'adgroup' : 'ADGROUP_PERFORMANCE_REPORT',
    'ad' : 'AD_PERFORMANCE_REPORT',
    'keyword' : 'KEYWORDS_PERFORMANCE_REPORT'}[ENTITY];
  var ret_map = {};
  var prev_days_ago = 0;
  for(var i = DAYS_IN_REPORT; i < max_days_ago; i+=DAYS_IN_REPORT) {
    var start_date = getDateDaysAgo(i);
    var end_date = getDateDaysAgo(prev_days_ago);
    var date_range = start_date+','+end_date;
    Logger.log('Getting data for ' + date_range);
    var query = ['select',cols.join(','),'from',report,'during',date_range].join(' ');
    var report_iter = AdWordsApp.report(query, API_VERSION).rows();
    if(!report_iter.hasNext()) { Logger.log('No more impressions found. Breaking.'); break; } // no more entries
    while(report_iter.hasNext()) { 
      var row = report_iter.next();
      if(ret_map[row['Id']]) {
        var [year,month,day] = (row['Date']).split('-');
        var from_row = new Date(year, parseFloat(month)-1, day);
        var from_map = ret_map[row['Id']];
         
        if(from_row < from_map) {
          ret_map[row['Id']] = from_row;
        }
      } else {
        var [year,month,day] = (row['Date']).split('-');
        ret_map[row['Id']] = new Date(year, parseFloat(month)-1, day);
      }
    }
    prev_days_ago = i;
  }
  return ret_map;
}

2013年6月2日,星期日

在Amazon S3中存储关键字效果报告

自从我上一篇文章发表以来已经过了几周 将数据放入Amazon S3,其中提到了您可以使用它在一个地方存储多个AdWords帐户的关键字效果报告。这是完全可以做到的更新版本。它结合了我以前关于存储的帖子 Google电子表格中的AdWords帐户效果报告 (当然会有一些变化)。

另外,在本文中,我将开始对所有脚本进行版本控制,以确保您始终拥有最新版本。

谢谢,
拉斯

//-----------------------------------
// Store Keyword Performance Report in 亚马逊S3
// Created By: 拉斯 Savage
// Version: 1.0
// FreeAdWordsScripts.com
//-----------------------------------
var ACCESS_KEY = 'YOUR_ACCESS_KEY_HERE';
var SECRET_KEY = 'YOUR_SECRET_KEY_HERE';
var S3_BUCKET = 'YOUR_S3_BUCKET_NAME_HERE';

function main() {
  var date_str = Utilities.formatDate(new Date(),AdWordsApp.currentAccount().getTimeZone(),'yyyy-MM-dd');
  var file_name = 'adwords_keyword_perf_'+AdWordsApp.currentAccount().getCustomerId() + '_' + date_str+'.csv';
  putDataToBucket(S3_BUCKET,'/'+file_name,getKeywordPerformanceReport());
}

function putDataToBucket(bucket,file_path,data) {
  var auth_options = {  
    method : 'PUT',
    base_url : "http://" + bucket + ".s3.amazonaws.com",
    s3_bucket : bucket,
    path : file_path,
    headers : { 
       "Date" : getDate(),
       "Content-Type" : "application/x-www-form-urlencoded"
    },
  };
  
  var auth_string = generateAuthString(auth_options);
  auth_options.headers["Authorization"] = auth_string;
  
  var options = {
    method : auth_options.method,
    headers : auth_options.headers,
    payload : data
  };
  
  return (UrlFetchApp.fetch(auth_options.base_url+auth_options.path, options).getResponseCode() == 200);
}

function generateAuthString(url) {
  var string_to_sign =  getStringToSign(url);
  Logger.log(string_to_sign);
  var signature = getSignature(SECRET_KEY,string_to_sign);
  return "AWS" + " " + ACCESS_KEY + ":" + signature;
}

function getSignature(SECRET_KEY,string_to_sign) {
  return  Utilities.base64Encode(
    Utilities.computeHmacSignature(
      Utilities.MacAlgorithm.HMAC_SHA_1,
      string_to_sign,
      SECRET_KEY,
      Utilities.Charset.UTF_8
    )
  );
}

function getStringToSign(url,params) {
  var method = url.method;
  var date = url.headers.Date;
  
  return method + "\n" + "\n" + 
    url.headers['Content-Type'] + "\n" +
    date + "\n" + 
    getCanonicalizedAmzHeaders(url);
}

function getCanonicalizedAmzHeaders(url) {
  var ret_val = "/" + url.s3_bucket;
  ret_val += url.path;
  return ret_val;
}

function getDate() {
  return Utilities.formatDate(new Date(),"GMT", "EEE, dd MMM yyyy HH:mm:ss +0000");
}


function getKeywordPerformanceReport() {
  var date_range = 'LAST_7_DAYS';
   
  var columns = ['Date',
                 'CampaignName',
                 'CampaignStatus',
                 'AdGroupName',
                 'AdGroupStatus',
                 'IsNegative',
                 'Id',
                 'KeywordMatchType',
                 'KeywordText',
                 'DestinationUrl',
                 'FirstPageCpc',
                 'MaxCpc',
                 'MaxCpm',
                 'PercentCpa',
                 'ClickType',
                 'Device',
                 'Slot',
                 'CpcBidSource',
                 'AverageCpc',
                 'AverageCpm',
                 'AveragePosition',
                 'PreferredPosition',
                 'QualityScore',
                 'Clicks',
                 'ConversionRate',
                 'ConversionRateManyPerClick',
                 'Conversions',
                 'ConversionsManyPerClick',
                 'ConversionValue',
                 'Cost',
                 'CostPerConversion',
                 'CostPerConversionManyPerClick',
                 'Ctr',
                 'Impressions',
                 'Cost',
                 'ValuePerConversion',
                 'ValuePerConversionManyPerClick',
                 'ViewThroughConversions'];
  var columns_str = columns.join(',') + " ";
   
  var report_iter = AdWordsApp.report(
    'SELECT ' + columns_str +
    'FROM KEYWORDS_PERFORMANCE_REPORT ' +
    'DURING ' + date_range, {
      includeZeroImpressions: false,
      apiVersion: 'v201302'
    }).rows();
  
  var ret_data = '"' + columns.join('","') + '"\n';
  while(report_iter.hasNext()) {
    var row = report_iter.next();
    var row_array = [];
    for(var i in columns) {
       row_array.push(row[columns[i]]);
    }
    ret_data += '"' + row_array.join('","') + '"\n';
  }
  
  return ret_data;
}

2013年5月3日,星期五

使用脚本将AdWords数据放入Amazon S3

我不确定您的身份,但是编写所有这些脚本会使我陷入Google Spreadsheet重载的境地。随着访问任何AdWords报告功能的发布,数据很快开始变得难以处理。一旦事情超过了数千行,我就更喜欢使用Excel或在数据库中存储和处理数据。

因此,我在寻找其他方法来从脚本世界中的AdWords报告中获取数据,因此我想到了 亚马逊S3。亚马逊通过其亚马逊网络服务提供了RESTful API,使您可以从云中存储和检索大量数据。我认为我可以使用它们存储帐户/广告系列/关键字性能的一些CSV文件,以便以后通过其他脚本或软件进行下载或处理。

下面的脚本尝试封装构建和授权适当的S3放置请求所需的所有逻辑。我遵循找到的文档 这里.

要免费开始使用,请注册 亚马逊S3在这里 并在此处找到您的访问权限和密钥:


接下来,创建一个新的S3存储桶以通过AWS控制台保存所有数据。填写以下详细信息,然后尝试测试文件。理想情况下,您可以将其与其他AdWords之一结合使用 报告 剧本 在这里找到开始将您的数据存储在云中。

注意:这是一组非常特定的功能,代表将文件放入Amazon S3所需的最低限度信息。有关更多信息,请查看完整的 亚马逊S3文件.

Thanks,
拉斯

//-----------------------------------
// Put Data To 亚马逊S3
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
var ACCESS_KEY = 'YOUR_ACCESS_KEY_HERE';
var SECRET_KEY = 'YOUR_SECRET_KEY_HERE';
var S3_BUCKET = 'YOUR_S3_BUCKET_NAME_HERE';
  

function main() {
  var date_str = Utilities.formatDate(new Date(),AdWordsApp.currentAccount().getTimeZone(),'yyyy-MM-dd');
  var file_name = 'adwords_keyword_perf_'+date_str+'.csv';
  putDataToBucket(S3_BUCKET,'/'+file_name,'this is where the data from an AdWords report would go.');
}


function putDataToBucket(bucket,file_path,data) {
  var auth_options = {  
    method : 'PUT',
    base_url : "http://" + bucket + ".s3.amazonaws.com",
    s3_bucket : bucket,
    path : file_path,
    headers : { 
       "Date" : getDate(),
       "Content-Type" : "application/x-www-form-urlencoded"
    },
  };
  
  var auth_string = generateAuthString(auth_options);
  auth_options.headers["Authorization"] = auth_string;
  
  var options = {
    method : auth_options.method,
    headers : auth_options.headers,
    payload : data
  };
  
  return (UrlFetchApp.fetch(auth_options.base_url+auth_options.path, options).getResponseCode() == 200);
}

//Generates an AWS Auth String
//For more info, see the AWS docs - http://goo.gl/m5nCe
function generateAuthString(url) {
  var string_to_sign =  getStringToSign(url);
  Logger.log(string_to_sign);
  var signature = getSignature(SECRET_KEY,string_to_sign);
  return "AWS" + " " + ACCESS_KEY + ":" + signature;
}

//Generates an AWS Signature
//For more info, see the AWS docs - http://goo.gl/m5nCe
function getSignature(SECRET_KEY,string_to_sign) {
  return  Utilities.base64Encode(
    Utilities.computeHmacSignature(
      Utilities.MacAlgorithm.HMAC_SHA_1,
      string_to_sign,
      SECRET_KEY,
      Utilities.Charset.UTF_8
    )
  );
}

//Generates an AWS string to sign
//For more info, see the AWS docs - http://goo.gl/m5nCe
function getStringToSign(url,params) {
  var method = url.method;
  var date = url.headers.Date;
  
  return method + "\n" + "\n" + 
    url.headers['Content-Type'] + "\n" +
    date + "\n" + 
    getCanonicalizedAmzHeaders(url);
}

//Generates the Canonicalized Amazon Headers (not really)
//For more info, see the AWS docs - http://goo.gl/m5nCe
function getCanonicalizedAmzHeaders(url) {
  var ret_val = "/" + url.s3_bucket;
  ret_val += url.path;
  return ret_val;
}

function getDate() {
  return Utilities.formatDate(new Date(),"GMT", "EEE, dd MMM yyyy HH:mm:ss +0000");
}

2013年3月20日,星期三

在Google文档中存储帐户效果报告

第2天,我仍在使用新的报告API。我想我会发布一些人们开始从我以前的帖子中询问的内容 存储帐户级别质量得分 它将所有帐户级别的效果存储在电子表格中。

您需要做的就是创建一个全新的Google文档来存储您的数据并将该URL粘贴到脚本中。脚本第一次运行时,将创建列标题。您可以根据需要通过移动列名来添加,删除或重新排列列。不过,您应该在执行此操作后重设电子表格。

谢谢,
拉斯

/**************************************
* 在Google文档中存储帐户效果报告
* Version 1.1
* Changelog v1.1 - Removed apiVersion, Removed get 电子表格
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
**************************************/
function main() {
  var 电子表格_url = "Your Spreadsheet Url Goes Here";
  var date_range = 'YESTERDAY';
  var columns = ['Date',
                 'AccountCurrencyCode',
                 'AccountDescriptiveName',
                 'AccountId',
                 'AccountTimeZoneId',
                 'CustomerDescriptiveName',
                 'ExternalCustomerId',
                 'PrimaryCompanyName',
                 'PrimaryUserLogin',
                 'Device',
                 'AverageCpc',
                 'AverageCpm',
                 'AveragePosition',
                 'Clicks',
                 'ConversionRate',
                 'ConversionRateManyPerClick',
                 'Conversions',
                 'ConversionsManyPerClick',
                 'ConversionValue',
                 'Cost',
                 'CostPerConversion',
                 'CostPerConversionManyPerClick',
                 'Ctr',
                 'Impressions',
                 'SearchBudgetLostImpressionShare',
                 'SearchExactMatchImpressionShare',
                 'SearchImpressionShare',
                 'SearchRankLostImpressionShare',
                 'ValuePerConversion',
                 'ValuePerConversionManyPerClick',
                 'ViewThroughConversions'];
  var columns_str = columns.join(',') + " ";
  
  var sheet = SpreadsheetApp.openByUrl(spreadsheet_url).getActiveSheet();
  if(sheet.getRange('A1:A1').getValues()[0][0] == "") {
    sheet.clear();
    sheet.appendRow(columns);
  }
  
  var report_iter = AdWordsApp.report(
    'SELECT ' + columns_str +
    'FROM ACCOUNT_PERFORMANCE_REPORT ' +
    'DURING ' +date_range).rows();
  
  while(report_iter.hasNext()) {
    var row = report_iter.next();
    var row_array = [];
    for(var i in columns) {
       row_array.push(row[columns[i]]);
    }
    sheet.appendRow(row_array); 
  }
}

2013年3月19日,星期二

在Google文档中存储搜索查询效果报告

好吧,我向您保证,一旦AdWords脚本小组解决了报告API的问题,我将开始添加一些示例。幸好他们今天修复了它,因为我想开始玩 搜索查询效果报告.

该报告将为您提供广泛匹配关键字的所有用户搜索查询。通常,您必须每天登录并手动生成报告。但是,借助AdWords脚本,您可以开始将所有数据存储到Google Spreadsheet中,以便于使用。

因此,今天我有一个简单的脚本,该脚本将存储搜索查询报告并向您发送一封电子邮件,提醒您它已准备就绪。您所需要做的就是用与您的AdWords帐户相同的登录名填写您有权访问的现有Google文档的网址,并设置您要发送通知的电子邮件地址,并且应该已经准备就绪。我还建议您使用一个标志来确定是否要从结果中忽略完全匹配(完全匹配)的关键字。

谢谢,
拉斯

/***************************************************
* Store 搜索 Query Perf Report in Google Doc
* Version 1.1
* CHangelog v1.1 - Removed apiVersion, Updated formatting
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
****************************************************/
var DATE_RANGE = 'LAST_7_DAYS';
var IGNORE_EXACT = true;
var TO = ["电子邮件[email protected]_company.com","电子邮件[email protected]_company.com"];
var SPREADSHEET_URL = "your 电子表格 url goes 这里";  

function main() {
  var columns = ['AccountDescriptiveName',
                 'CampaignName',
                 'AdGroupName',
                 'KeywordTextMatchingQuery',
                 'MatchType',
                 'Query',
                 'Device',
                 'Impressions',
                 'Clicks',
                 'Cost',
                 'Conversions',
                 'AverageCpc',
                 'CostPerConversion',
                 'ConversionRate',
                 'Ctr'];
  var columnsStr = columns.join(',') + " ";
   
  var sheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL).getActiveSheet();
  sheet.clear();
  sheet.appendRow(columns);
   
  var reportIter = AdWordsApp.report(
    'SELECT ' + columnsStr +
    'FROM SEARCH_QUERY_PERFORMANCE_REPORT ' +
    'DURING ' + DATE_RANGE, {
      includeZeroImpressions: false
    }).rows();
   
  while(reportIter.hasNext()) {
    var row = reportIter.next();
    if(IGNORE_EXACT && row['MatchType'].indexOf('exact') >= 0) { continue; }
    var rowArray = [];
    for(var i in columns) {
      rowArray.push(row[columns[i]]);
    }
    sheet.appendRow(rowArray); 
  }
   
  for(var i in TO) {
    MailApp.sendEmail(TO[i], "搜索 Query Report Ready", SPREADSHEET_URL);
  }
}

2013年3月17日,星期日

新Reporting API的问题

像你们中的许多人一样,我一直在努力尝试新报告 原来的功能 最近添加的 上周晚些时候使用AdWords脚本。 不幸的是,即使使用 示例代码 在API中给出。如果有人遇到过同样的问题, 论坛上的主题 您可以在这里等待AdWords脚本小组解决该问题。 解决后,我将开始发布一些示例代码。 我一直在研究自动贩卖用户查询脚本,这非常酷。

谢谢,
拉斯