LambdaとAPI GatewayとGoogle AnalyticsでGoogle広告のクリック計測

こちらの記事は[WEBやデータ分析に関する投稿をみんなでしてみよう Advent Calendar 2020](https://qiita.com/advent-calendar/2020/think-with-tomohiko)の21日目の記事になります。

※1年以上前に書いた記事なので今は仕様が違うと思う。本当はGA4に対応する形にしたかったけど時間が無かったので今回はそのまま掲載。

何となくLambdaとAPIGateway使って遊んでみた
#構成
Google広告→AWS APIGateway&Lambda→ランディングページ
#何が嬉しいの？
LPのドメインに関係なく広告のクリックデータをGoogle Analyticsに集約できる。
#手順
とりあえず必要最小限の設定でやってみる
##1.APIGatewayの作成
とかく色んな設定は出来るが、目的達成の為に簡単に

* APIの作成をクリック
![api1.png](https://qiita-image-store.s3.amazonaws.com/0/260443/bf05e793-da96-db56-3d2f-15d5b4741413.png)

* API名：適当（今回はGoogleAds）を入れて右下のAPIの作成
![api2.png](https://qiita-image-store.s3.amazonaws.com/0/260443/d06239f5-8365-86cd-65f3-7ef51baf32a5.png)

##2.Lambdaの設定
これもnodeとか色々あるが手に馴染みがあるのがpythonだったのでpython3.6を選択

* 関数の作成をクリック
![lambda1.png](https://qiita-image-store.s3.amazonaws.com/0/260443/78acfed5-8bb2-56d2-e1c6-161d447f4855.png)

* 以下のように作成
<dl>
<dt>名前</dt><dd>適当（今回はGoogleAds）</dd>
<dt>ランタイム</dt><dd>適当（今回はPython3.6）</dd>
<dt>ロール</dt><dd>既存のロールを選択（そのまま）</dd>
<dt>既存のロール</dt><dd>service-role/FullAccess</dd>
</dl>
![lambda2.png](https://qiita-image-store.s3.amazonaws.com/0/260443/12b78e12-6190-061d-2b79-4ce384898b08.png)

* lambda_functionとして以下を記述し、右上の保存をクリック

```
import http.client, urllib

def lambda_handler(event, context):
    params = urllib.parse.urlencode({
        'v':1,
        'tid':'UA-XXXXXXXX-Y', //計測するGoogle AnalyticsのトラッキングID
        'cid':event['gclid'],
        't':'pageview',
        'cd1':event['placement'],
        'cd2':event['targetid'],
        'cd3':event['campaignid'],
        'cd4':event['adgroupid'],
        'cd5':event['creative'],
        'cd6':event['user_agent'],
        'cd7':event['loc_physical_ms'],
        'cd8':event['source_ip'],
        'cd9':event['device']
    })

    conn = http.client.HTTPConnection("www.google-analytics.com")
    conn.request("POST", "/collect", params)
    response = conn.getresponse()
    data = response.read()
    conn.close()
    
    return {
        'location' : event['lpurl']
    }
```

計測はGoogle Analyticsで実施。Google AnalyticsのMeasurment Protocolを使う。計測パラメータは色々選択できるが、今回はとりあえずカスタムディメンションとして計測。

動作確認をしたい場合はテストの横のセレクトボックスをクリック「テストイベントの設定」を選んだらイベント名を入れて以下のように設定。

```
{
  "gclid": "EAIaIQobChMI66vvwqnz3AIVTWK9Ch2CnwIKEAEYASAAEgJA5_D_BwE",
  "lpurl": "http://www.google.com",
  "placement": "www.example.com",
  "targetid": "aud-484696578135",
  "campaignid": "1494334742",
  "adgroupid": "57748640396",
  "creative": "285605632536",
  "user_agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
  "loc_physical_ms": "1009507",
  "source_ip": "121.83.3.105",
  "device": "m"
}
```

テストイベント設定出来たら、テストボタンをクリックするとリクエスト結果が出てくる。200だったらGoogle Analytics側にもデータが来ているか（リアルタイムではないので、少し時間を置いて）確認する。
##3.API Gatewayの設定
* 作成したAPI（GoogleAds）をクリックしてアクション→メソッドの作成、下の選択肢で「GET」を選びチェックボタンをクリック
![api4.png](https://qiita-image-store.s3.amazonaws.com/0/260443/1c3c8c65-85fd-0a61-5a11-00508a6c4d46.png)

* Lambda関数の欄に先程作ったLambda関数名を入力する（途中まで入れると候補が出てくるので選択）保存
![api5.png](https://qiita-image-store.s3.amazonaws.com/0/260443/020bdd8e-ae84-a279-b75b-b7d5a55a806a.png)
警告が出るが「ＯＫ」で進める
![api6.png](https://qiita-image-store.s3.amazonaws.com/0/260443/b58799d1-5de5-95dd-6bad-b6e4c42b9d19.png)

###メソッドリクエストの設定
* メソッドリクエストをクリック、URLクエリ文字列パラメータを開き、クエリ文字列の追加をクリックしAPIとして受け付けるリクエストパラメータの設定をする
![api7.png](https://qiita-image-store.s3.amazonaws.com/0/260443/f3017375-248c-4cff-9e1a-5d94d169fd48.png)

###統合リエクストの設定
* 統合リクエストをクリックし、マッピングテンプレートを開き、マッピングテンプレートの追加をクリック、Content-Typeとしてapplication/jsonと入れてチェックボタンをクリックする
![api8.png](https://qiita-image-store.s3.amazonaws.com/0/260443/54932a66-1ebd-dfe0-59d5-539eb5cc0d01.png)

* 警告が出てくるので「いいえ、現在の設定を使用します」をクリックする
![api9.png](https://qiita-image-store.s3.amazonaws.com/0/260443/3eff89a8-49b9-f2f9-4953-581868d339c1.png)

* Content-Typeのapplication/jsonがクリッカブルになっているのでクリックし、下に出てくる入力欄に以下のように設定する（APIがリクエストで受け付けたデータをLambda側に引き渡す設定）
![api10.png](https://qiita-image-store.s3.amazonaws.com/0/260443/d6aec1a5-ade5-4969-8b8c-013ded89f581.png)

```
{
  "adgroupid": "$input.params('adgroupid')",
  "campaignid": "$input.params('campaignid')",
  "creative": "$input.params('creative')",
  "device": "$input.params('device')",
  "gclid": "$input.params('gclid')",
  "loc_physical_ms": "$input.params('loc_physical_ms')",
  "placement": "$input.params('placement')",
  "targetid": "$input.params('targetid')",
  "lpurl": "$input.params('lpurl')",
  "source_ip" : "$context.identity.sourceIp",
  "user_agent" : "$context.identity.userAgent"
}
```

\$input.paramsでリクエストパラメータとして受け取ったデータを引っ張ってきて$context.identityでリクエストヘッダーの内容を取ってきている。jsonの形にしてlambdaに送っている。
###メソッドレスポンスの設定
* メソッドレスポンスをクリックし、レスポンスの追加から302レスポンスを追加する
![api12.png](https://qiita-image-store.s3.amazonaws.com/0/260443/6c5cee9a-588f-e964-ea17-74e1d6c4b63f.png)

* 追加した302を開き、ヘッダーの追加で「Location」を追加しておく

###統合レスポンスの設定
* 統合レスポンスをクリックし、デフォルトのレスポンス（200）を削除する
![api11.png](https://qiita-image-store.s3.amazonaws.com/0/260443/68c7caca-5c65-c6ad-0214-c5127e681414.png)

* 統合レスポンスの追加をクリックし、以下のように設定する
<dl>
<dt>Lambdaエラーの正規表現</dt><dd>.*</dd>
<dt>メソッドレスポンスのステータス</dt><dd>302</dd>
<dt>コンテンツの処理</dt><dd>パススルー</dd>
<dt>ヘッダーのマッピング</dt><dd>レスポンスヘッダー「Location」、マッピングの値「integration.response.body.location」</dd>
</dl>
* 統合レスポンスのHTTPステータスパターンのセレクトボックスから先程「Lambdaエラーの正規表現」で設定した内容を選択

###テストおよびデプロイ
* テストをクリックし、クエリ文字列に以下を入れる（lambdaのテストと同じ内容をGETパラメータの形で渡している）

```　
gclid=EAIaIQobChMI66vvwqnz3AIVTWK9Ch2CnwIKEAEYASAAEgJA5_D_BwE&lpurl=http://www.google.com&placement=www.example.com&targetid=aud-484696578135&campaignid=1494334742&adgroupid=57748640396&creative=285605632536&loc_physical_ms=1009507&device=m
```

* アクションでAPIのデプロイを選択、デプロイステージを新しく作成、ステージ名は適当（今回はGoogleAds）

##4.Google広告の設定
今回のように広告クリック後、ランディングページに行く前にどっか経由させる場合、トラッキングテンプレートという欄にURLを設定するときちんと経由してくれる。

* 上記APIGatewayで発行されたURLをトラッキングテンプレートに設定。GETパラメータでValueTrackが計測出来るように設定。