こんにちは。android事業室エンジニアの@shinbashi です。
 
8月中旬にGoogle Tag Manager (以下GTM)がモバイル・アプリ向けに対応したことが正式に発表されてから久しいですが、きちんと見ていなかったのでせっかくなので調べて使ってみた時の事を書こうと思います。

さて、 GTMってなんだ?という方もいらっしゃるかもしれないので、簡単に紹介させていただきます。
こちらが正式発表がされた際のブログの日本語訳から、分かりやすそうな部分の抜粋になります

ボタンを押してイベントを追加するのを忘れた? それは、まいったな!

キャンペーン終了直前にコンバージョン追跡を追加しなくてはいけない? それはひどい!

大事な設定を変更しなくてはいけないことに気付いた? 残念だが、それは無理だ。

これは、今までの話! 今年初めにGoogle I/Oで予告したように、今日、当社はモバイルアプリ向けのGoogleタグマネージャをローンチします。

モバイルアプリ用Googleタグマネージャを一度導入してしまえば、設定変更は可能になり、分析、リマーケティング、コンバージョントラッキングを、対象のアプリをアップグレードせずに追加することが可能になります。
 

引用元:モバイルアプリ向けGoogleタグマネージャ登場! 

おお、なんだかすごく便利そうですね!予めSDKを仕込んでおけば、ある程度GTMからいろいろなところにフック出来そうな感じがします。
何はともあれ、とりあえずヘルプを見てみます。

モバイル アプリ向け Google タグマネージャ

Google タグマネージャを使用すると、変更予定のある設定値や、条件に応じて変える可能性のある設定値を簡単に管理できます。具体的には、アプリ内の値を定数ではなく変数として定義して、これらの値を指定するルールを Google タグマネージャで管理します。例として次のものが挙げられます。

  • アプリに掲載する広告のサイズや位置(画面サイズに応じて広告バナーの縦のサイズを変更する場合など)
  • ゲームの設定
  • ユーザー インターフェースの設定(プラットフォームに応じて変更する場合など)
  • デバイスの言語によってローカライズする文字列

引用元: Google タグマネージャについて - Tag Manager ヘルプ

・・・、なんだか入れ忘れたイベントを追加したり、コンバージョンを追加したりするのはどうやるのかイマイチわかりません。予め設定をGTM経由で取得するようにしておけば、設定変更を行えそうだということはわかりました。
  • イベント追加忘れ→そいつは参ったまま
  • 急なコンバージョンの追跡→それもひどいまま
  • 大事な設定の変更→残念じゃないかもしれない!予め仕込んで置けば無理じゃないかもしれない!
 といった具合のようです。
記事を書き始めた当初はイベント追加し忘れたよ!GTMで新しく追加したよ!みたいな記事を書こうと思ったんですが、完全な見切り発車でした。
 
なのでここで大きく方向転換をして、近々ABテストが実装できるとの事なので、おそらく現在の機能でも頑張ればABテストできるんじゃないかと思ってABテストのようなものを実装してみることにしてみました。 
前置きがかなり長くなりましたが、ABテストをしてみようと思います。

概要
  • インストールされたアプリ毎に、50%の確立でそれぞれボタンの文字が「a button」「b button」という文字が表示される
  • Analyticsには、「a button」が表示される場合には「ABActivity_AButton」、「b button」が表示される場合には「ABActivity_BButton」というスクリーンビューが発生。またどちらが表示されても「AB_Activity」というスクリーンビューが発生する。(Analyticsで正確にスクリーンビューを計測するにはフィルタの設定が必要になると思います)
  • Analyticsには「a button」がタップされた場合には、イベントとして「button,tap,a_button」、「b button」がタップされた場合には「button,tap,b_button」が発生する
 こんな感じにしておけば、アクション/スクリーンビューでそれぞれのCTRが出せそうですね。イベントをタップではなくコンバージョンとかにすればコンバージョン率も計測できそうです。

GTM側手順
  1. GTMコンソールで以下のマクロを作る
    GTM01

  2. 以下のルールを作る
    GTM02

  3. バージョンを作成して公開/プレビューする
 以上でGTM側の準備は完了です。上記のマクロとルールを使って何をするかを説明したいと思います。

マクロ
  • データレイヤー変数:ab_button_test_number
    データレイヤー変数は、アプリケーション側から値をセット出来る変数です。今回はabテストで何を表示するかを振り分ける為の乱数をセットします。乱数はアプリ側で初回起動時に生成して、SharedPreferenceなどに保存されている値が渡されるものとします。
  • 値のコレクション:ab_button_a_values, ab_button_b_value
    JSON形式で保存される値のコレクションです。このマクロにはルールを指定できるため、2で記述してある条件に合う方のコレクションが適用されることになります。
ルール
  •  ab_button_a_rule, ab_button_b_rule
    値のコレクションに適用するルールです。今回乱数は0~2147483647の間で発生するものとして、真ん中で分けます。(1ずれてるのはご愛嬌)
上記のように定義しておけば、以下の手順でABテストっぽいことが出来そうです。
  1. ab_button_test_numberにアプリ毎に生成されるランダムな数字が格納される
  2. ab_button_test_numberの値によって、ab_button_a_ruleかab_button_b_ruleが適用される
  3. button_stringやbutton_screen_nameに「button a」パターンか「button b」パターンの値が格納される
  4. 格納された値をビューの文字列やAnalyticsに送信する文字列として扱う
準備が整ったので、アプリ側のコードを書いていこう思います。

public class MainActivity extends Activity {

    private static final String CONTAINER_ID = "GTM-******";

    volatile private Container mContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TagManager mTagManager = TagManager.getInstance(this);
        ContainerOpener.openContainer(
                mTagManager,
                CONTAINER_ID,
                ContainerOpener.OpenType.PREFER_FRESH,
                null,
                new ContainerOpener.Notifier() {
                    @Override
                    public void containerAvailable(Container container) {
                        mContainer = container;
                        onLoadContainer();
                    }
                }
        );
        android.util.Log.d("DEBUG", "main");
        setContentView(R.layout.activity_main);
        // onLoadContainerメソッドの処理が終了するまでloading dialogを出すと良いかもしれない
    }

    private void onLoadContainer() {
        DataLayer dataLayer = TagManager.getInstance(MainActivity.this).getDataLayer();
        int random = (int)(Math.random() * 2147483647); // 実際は起動時に設定に保存して、そこから呼び出した方がよさそう
        dataLayer.push("ab_button_test_number", String.valueOf(random));
        Button button = (Button) findViewById(R.id.button);
        button.setText(mContainer.getString("button_string"));
        // UniversalAnalyticsタグを使用してボタン別のスクリーンを計測
        // buttonのonClickにイベントを計測する処理をセット
    }
}
こんな形で実装すれば、GTM上の設定を反映できそうです。
ネットワークに繋がっていない場合に備えて、デフォルト値を格納したjsonを入れておけばABテストができそう!

と思ったのですが、ここまで書いていたところで、後輩のプロデューサーが通って一言いいました。

「これってGTMでやる必要あるんですか?」

革新とは常に痛みを伴いますね。ありがとうございました。