rubyでgoogle_adwors_apiを使って広告のレポート取得及びステータスの変更を行う方法

# 概要
この記事は体系的にGoogle adwords apiの使い方をまとめているわけではありません。あしからず。

# 広告のレポート取得
Google Adwords APIドキュメントには以下のような記述がある。
>API からレポートを生成する手順は、大きく次の 2 つに分かれます。

>1.レポート定義(report_definition)を作成します。レポート定義とは、レポートのパラメータを定義する XML か AWQL のフラグメントです。ここでレポート名、レポートに含める情報の種類、ダウンロード形式などレポートのパラメータを指定します。
>2.レポート定義を HTTP POST リクエストに格納し、AdWords サーバーに送信します。
この 2 つの手順について、以降で詳しく説明します。

ruby上であればレポート定義(report_definition)はAWQLまたはrubyのハッシュによるslectorの定義で作ることができる。どちらでも良いが、rubyライクにかけるほうがいいとは思います。
ただ、AWQLはかなり簡素に書けるので、僕はお好みだと思っています。


まず、rubyでレポートを取得しているコードを紹介します。

```ruby
#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
#
# License:: 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.
#
# This example gets and downloads an Ad Hoc report from a XML report definition.

require 'adwords_api'


def download_criteria_report_with_selector
  # AdwordsApi::Api はコンストラクトの際、引数なしであれば ENV['HOME']/adwords_api.ymlを読みます
  adwords = AdwordsApi::Api.new

adwords.credential_handler.set_credential(:client_customer_id, "<レポートが欲しい広告主のclient_id>")

  # レポートUtilsを取得。
  # 今回はv201710を使いたい
  report_utils = adwords.report_utils(API_VERSION)

  # 1.レポート定義の作成 + POST用URLの作成に当たる部分
  #----------------------------------------------
  report_definition = {
    :selector => {
      :fields => ['CampaignId', 'AdGroupId', 'Id', 'Criteria', 'CriteriaType',
          'FinalUrls', 'Impressions', 'Clicks', 'Cost'],
      # Predicates are optional.
      :predicates => {
        :field => 'Status',
        :operator => 'IN',
        :values => ['ENABLED', 'PAUSED']
      },
    },
    :report_name => 'Last 7 days CRITERIA_PERFORMANCE_REPORT',
    :report_type => 'CRITERIA_PERFORMANCE_REPORT',
    :download_format => 'CSV',
    :date_range_type => 'LAST_7_DAYS',
    
  }
  
  # Optional: HTTPのヘッダーに当たる値を設定　
  # column name, or summary rows in the report output. You can also configure
  # this in your adwords_api.yml configuration file.
  adwords.skip_report_header = false
  adwords.skip_column_header = false
  adwords.skip_report_summary = false
  # Enable to allow rows with zero impressions to show.
  adwords.include_zero_impressions = false
  # 1end------------------------------------------------
  
  # 2-------------------------------------------------
  # レポートを取得する。この時"download_report_as_file" というのもあるが、
  # 今回は"download_report"を使ってファイルには保存しない
  p report_utils.download_report(report_definition)
  puts "Report was downloaded"
  # 2 end
end
```

レポート定義の指定の部分を抜き出す

```ruby
  # Define report definition. You can also pass your own XML text as a string.
  report_definition = {
    :selector => {
      :fields => ['CampaignId', 'AdGroupId', 'Id', 'Criteria', 'CriteriaType',
          'FinalUrls', 'Impressions', 'Clicks', 'Cost'],
    },
  # filter
      :predicates => {
        :field => 'Status',
        :operator => 'IN',
        :values => ['ENABLED', 'PAUSED']
      },
    },
    :report_name => 'Last 7 days CRITERIA_PERFORMANCE_REPORT',
    :report_type => 'CRITERIA_PERFORMANCE_REPORT',
    :download_format => 'CSV',
    :date_range_type => 'LAST_7_DAYS',
     
  }
```
以下、`:selector`の構成要素の詳細。

- `:fields`はArray型で、レポートとして返して欲しいプロパティを定義します。fieldとして使用可能なものは[こちらのドキュメント](https://developers.google.com/adwords/api/docs/appendix/selectorfields?hl=ja#v201710-AdGroupAdService)を参照。

- `:predicates`はfilterの役目をする。SQLのWHERE句に対応すると考える。

- `:report_name`にはoutputされるレポートの名前を指定します(はず)。

- `:repot_type`には返すレポートの種別を指定する。今回の"CRITERIA_PERFORMANCE_REPORT"は全基準を一括りにしたもののようであり、Attributes項目にて様々な設定ができます。詳しくは[こちら]
(https://developers.google.com/adwords/api/docs/reference/v201710/ReportDefinitionService.ReportDefinition.ReportType)を参照。これによってfieldで使用可能な項目や意味合いが変わってきて、CRITERIA_PERFORMANCE_REPORTの場合は[こちら](https://developers.google.com/adwords/api/docs/appendix/reports/criteria-performance-report)を参照。
- `:download_format`は返すデータフォーマットの指定ができる。今回はCSVです。
- `:data_range_type`は返すレポートの期間を示す。"LAST_7_DAYS"以外にも、いろいろある。詳しくは[こちら](https://developers.google.com/adwords/api/docs/guides/reporting#date_ranges)。

## レポート取得のまとめ
1. report_utilsを取得
2. report_definitionを作成
3. report_definitionについては、欲しい値が返ってくるように指定
4. report_definitionをreport_utilsのdownload_reportメソッドに入力
5. 返ってきた値を弄ります。



# ステータスの変更
AdwordsではCampaign単位、AdGroup単位、Ad単位でステータスを変更することができます。
それぞれの単位に対して、CampaignService、AdGroupService、AdGroupAdServiceオブジェクトが対応しています。
それぞれのサービスはget系としてgetメソッド、post系メソッドとしてmutateを持っており、getの引数にはselectorが入り、mutateの引数にはOperationが入ります。
それぞれ単なるget, postパラメータとして考えてください。
今回はAd単位でのステータスの変更のサンプルを紹介します。
以下はmutateメソッドを用いてAdをstopさせるためのものです。

```ruby
#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
#
# License:: 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.
#
# This example illustrates how to update an ad, setting its status to 'PAUSED'.

require 'adwords_api'

def pause_ad(ad_group_id, ad_id)
  adwords = AdwordsApi::Api.new

  # AdGroupServiceを取得 Versionは最新のものを使っていきたい
  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)
  adwords.credential_handler.set_credential(:client_customer_id, "<広告をいじりたい広告主のID>")

  # Operationを作成
  operation = {
    :operator => 'SET',
    :operand => {
      :ad_group_id => ad_group_id,
      :status => 'PAUSED',
      :ad => {:id => ad_id}
    }
  }

  # 広告をmutateメソッドによりupdate
  response = ad_group_ad_srv.mutate([operation])
  if response and response[:value]
    ad = response[:value].first
    puts "Ad ID %d was successfully updated, status set to '%s'." %
        [ad[:ad][:id], ad[:status]]
  else
    puts 'No ads were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201710

  begin
    # IDs of ad to pause and its ad group.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    ad_id = 'INSERT_AD_ID_HERE'.to_i
    pause_ad(ad_group_id, ad_id)
  end
# ------------
# エラー処理
# ------------
end
```

Operationの部分について抜き出していく

```ruby
# Operationを作成
  operation = {
    :operator => 'SET',
    :operand => {
      :ad_group_id => ad_group_id,
      :status => 'PAUSED',
      :ad => {:id => ad_id}
    }
  }
```

`:operator`については、どのような操作をするかを指定する。SET, REMOVE, ADDの三種類があります。
`:operand`については、どの広告に対してなんの操作(operation)を行うかの指定ができます。

mutateの部分について抜き出していきます。

```ruby
# 広告をmutateメソッドによりupdate
  response = ad_group_ad_srv.mutate([operation])
  if response and response[:value]
    ad = response[:value].first
    puts "Ad ID %d was successfully updated, status set to '%s'." %
        [ad[:ad][:id], ad[:status]]
  else
    puts 'No ads were updated.'
  end
```

上記コードでは`response[:value]'にmutateで操作を行った広告のデータが入っているので、そこに値が入っていれば当該広告は値を更新されており、そうでなければ何も起きなかったという処理になっているます。

## 広告レポートの停止のまとめ
広告の停止をしたいとき
1. AdGroupAdServiceを取得し、operationを作成。
2. operationはoperatorを"SET"にし、operandではstatusをpauseにするようにする。
2. serviceのmutateメソッドにoperationを入力
3. mutateメソッドが正しく実行されたかの確認