Google Apps Script と各種Googleサービスとの簡単な連携(Gmail、Spread Sheet、Drive、Analitycs)

今回はGoogle Apps Script(以下、GAS)と以下のGoogleサービスとの連携方法について書きます。
- Gmail
- Google Spread Sheet(以下、スプレッドシート)、
- Google Drive
- Google Analitycs

#前置き

Googleの便利なサービスは、仕事に欠かせない方が多いと思います。
私もスプレッドシートとGoogle Drive、Gmail無しではもはや仕事出来ません(*-_-*)

そんな各種サービスですが、普通にAPIを利用して自動化を図ろうとすると、OAuthとかOauthとかOAuthとかのめんどくさい処理を入れないといけなかったりして心折れます。
が、GASを活用するとそこらへんは全く意識しなくてもスイスイ〜と利用出来るのです。
Googleでログインしてる前提があるので、そこらへんは裏で良きに計らってくれてるんですかね、よく分かりませんが(爆


ちなみに、GASですが、スプレッドシートから起動するタイプ(スプレッドシートと紐づくタイプ)と、GAS単体で起動するタイプがあります。
詳しくは下記のページが分かりやすかったのでそちらを参考にしてください。

[Google Apps Scriptの開発手法まとめ](http://qiita.com/soundTricker/items/4d04c97c499b22886dfd)

今回はGAS単体パターンで話を進めていきます。
(とはいってもそんなに変わりませんが)

では早速！


#【Gmail】との連携
[[Google Apps Script REFERENCE] Class GmailApp](https://developers.google.com/apps-script/reference/gmail/gmail-app)

```Code.gs
function myFunction() {
  GmailApp.sendEmail(
	"to_address",
	"title",
	"body",
	);
}
```

これだけです！一瞬！
送信者はスクリプトの実行者になります。
(初めて実行する場合は、Gmailへアクセスしてよいか確認のダイアログが出ますので、承認してください)

CcとかBccとかの送りたい場合はこんな感じ。

```Code.gs
function myFunction() {
  GmailApp.sendEmail(
	"to_address", 
	"title",
	"body",
	{bcc:"bcc_address"}
	);
}
```

詳しくはリファレンスをご参照くださいm(_ _)m
送信者を実行者以外にしたい場合も、一応方法はあるようですが私はやった事ありません。

#【スプレッドシート】との連携
[[Google Apps Script REFERENCE] Class Spreadsheet](https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet)

さすがにGmailに比べるとやや手数がかかりますが、こちらも簡単です。
流れとしては
1.対象のスプレッドシートのオブジェクトを取得
2.対象のシートのオブジェクトを取得
3.対象のRangeを操作
となります。

VBAを触った事がある方なら感覚的に分かりやすいかと思います。
ちなみに『名前付き範囲』(Excelで言うところの『名前』)を設定している場合は、上記手順の2を飛ばす事も可能です。

```Code.gs
function myFunction() {

  // 1.対象のスプレッドシートのオブジェクトを取得
  var spreadSheet =   SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxxxxxx/edit");

  // 2.対象のシートのオブジェクトを取得
  var targetSheet = spreadSheet.getSheetByName("sheet1");
  
  // 3.対象のRangeを操作
  // 値の設定
  targetSheet.getRange(1,1).setValue("test");

  // 値の取得
  Logger.log(targetSheet.getRange(1,1).getValue());
}
```

こんな感じです！
(こちらも初めて実行する場合は、スプレッドシートへアクセスしてよいか確認のダイアログが出ますので、承認してください)

SpreadsheetApp.openByUrlに渡しているのは、対象のスプレッドシートのURLです。
スプレッドシートを開いたときにブラウザに表示されているURLをそのままでOKです。
URLのお尻の方に、「#gid=000000000」みたいなものがくっついているかと思いますが、それはシート固有の番号です。
あくまでもSpreadsheetApp.openByUrlはスプレッドシート自体を取得してくるだけでシートは関係ありません。
そのため別にくっついていてもくっついてなくても問題なく動作します。

その他の細かい操作に関してはここでは割愛します。
一点だけ注意で、targetSheet.getRangeは呼び出すたびにスプレッドシートとの通信を行います。
そのため複数セルに対してfor文で繰り返し処理を行う場合にはものすごく重たくなります…
必要な範囲をスプレッドシートから一発で取得し、一括で書き込むように記述する事が出来ますので、こちらの方法をオススメします。
詳しくは下記サイトをご参照くださいm(_ _)m

[Google Apps Scriptを高速化するテクニック](http://eye4brain.sakura.ne.jp/wp/blog/2016/02/11/google-apps-script%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%96%E3%81%99%E3%82%8B%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF/)

ちなみにご存知の方もいらっしゃるかとは思いますが念のため。
しれっと記述しているLogger.logはGAS開発の友です。
console.logみたいな感じで実行結果を表示してくれます。
GASエディタのメニューの「表示」 > 「ログ」で結果を見る事が出来ます。


#【Google Drive】との連携
[[Google Apps Script REFERENCE] Class DriveApp](https://developers.google.com/apps-script/reference/drive/drive-app)

ちょっと複雑そうに見えるかもしれませんが、やる事はシンプルです。
「対象フォルダのIDを取得し、操作する」
これだけです。
※マイドライブ配下のファイルを片っ端から取得する方法もあるのですが、大量にファイルのある人がこれを実行すると、おそらくGASの実行時間上限5分に引っかかって5分後に停止するオチが見えるのでやりません

まずは対象フォルダのIDですが、これはフォルダを開いたときのURLから分かります。

https://drive.google.com/drive/folders/xxxxxxxxxxxxxxxxxxxxx
こんな感じになっていると思いますが、この「xxxxxxxxxxxxxxxxxxxxx」の部分がIDになります。

```Code.gs
function myFunction() {
  var target_folder = DriveApp.getFolderById("xxxxxxxxxxxxxxxxxxxxx");
  
  // ファイルの取得
  var files = target_folder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    Logger.log(file.getName());
  }
  
  // フォルダの取得
  var folders = target_folder.getFolders();
  while (folders.hasNext()) {
    var folder = folders.next();
    Logger.log(folder.getName());
  }
}
```

こんな感じです。
初めて実行する場合は(ry

フォルダをどんどん辿っていきたい場合は、getIdメソッドでファイルのIDを取得し、DriveApp.getFolderByIdでオブジェクトを取得…の繰り返しです。

これを活用して私は、とある集計結果をフォルダ作ってそれ毎に振り分ける、という作業を、振り分け先のフォルダ作成から全て自動化しました。
他にもフォルダ配下のバックアップ作成など行えたりするので、有効活用出来ればかなり威力を発揮します。


#【Google Analytics】との連携
さて、いよいよラストになりました。
こちらは先ほどまでのようにREFERENCEが見つからず…
いろいろなサイトを参考にして、かなり我流色が強いかもしれませんがご紹介します。

ちなみに実行者のアカウントに紐付いているアナリティクスの管理情報を引っ張ってきて、そこから対象のサイトを選択する手法もあるのですが、ちょっとめんど(ry
ややこしいので、簡単のために対象のトラッキングIDが分かっている状態で話を進めます。

トラッキングIDは、Analyticsのメニューの「管理」を開き、対象のアカウントを選択、対象のプロパティ(これがサイトに紐付いているはず)を選択、その状態でプロパティエリアの「トラッキング情報」 > 「トラッキングコード」を選択すれば確認出来ます。

そして下準備が必要です。

GASエディタのメニューの「リソース」 > 「Googleの拡張サービス」を選択し、無効になっている「Google Analytics API」をONにします。
![スクリーンショット 2016-12-07 22.32.54.png](https://qiita-image-store.s3.amazonaws.com/0/106608/f33b9c71-03cb-3d48-6f9c-096c9b05cf34.png)

さらに「リソース」 > 「Developers Console プロジェクト」を選択し、プロジェクト名のリンクをクリックします。
![スクリーンショット 2016-12-07 22.39.49.png](https://qiita-image-store.s3.amazonaws.com/0/106608/ddd2cff2-40f7-36ef-0464-eeb7385d60c0.png)

ライブラリからAnalytics APIを選択。
![スクリーンショット 2016-12-07 22.36.34.png](https://qiita-image-store.s3.amazonaws.com/0/106608/4cc73a8c-21c1-12c8-33b1-a07bc3e54ae0.png)

きちんと対象のプロジェクトが選択されているのを確認したら「有効にする」をポチっとな。
![スクリーンショット 2016-12-07 22.39.32.png](https://qiita-image-store.s3.amazonaws.com/0/106608/0b4e95fa-c75d-b4d1-6f93-0459dd0a6894.png)

ここまで出来たらいよいよ実行です。



```Code.gs
function myFunction() {
  // 対象サイトの情報を設定
  var profile = Analytics.Management.Profiles.list("xxxxxxxx", "UA-xxxxxxxx-1");

  // 対象サイトの情報をAnalyticsから取得(期間指定)
  var ga_result = Analytics.Data.Ga.get(
	"ga:"+profile.getItems()[0].getId(),
	"2016-12-01",	// 開始日
	"2016-12-01",	// 終了日
	"ga:visits"	// メトリクス
	);
  
  for(var rows = 0; rows < ga_result.getRows().length; rows++) {
      resultRow = ga_result.getRows()[rows];
      Logger.log(resultRow[0]);
    }
}
```

Analytics.Management.Profiles.listの第一引数は、
トラッキングコードが(UA-xxxxxxxx-1)みたいな感じになっているはずですが
このハイフンに囲まれた「xxxxxxxx」の部分の数字です。

Analytics.Data.Ga.getの第二引数と第三引数は、取得の開始日と終了日です。
時間ではなく日単位でデータを取得してきますので、yyyy-mm-dd形式で設定します。

問題は第四引数です。
これはメトリクスというやつです。
Analyticsのレポートを触った事の無い方だと、ディメンションとメトリクスという言葉に馴染みが無いと思います。
が、これの説明を仕出すとなかなかぱない事になるので…
ざっくりSQL風に言うと、
ディメンションがgroup by句で、メトリクスがselect句です。
ディメンション　→　抽出したいデータの単位(県単位、時間単位、ページ単位、など)
メトリクス　→　抽出したいデータの項目(ページビュー、滞在時間、ユニークユーザ数、など)

上の例では、メトリクスでセッション数(ga:visits)しか指定しておらず、ディメンションの設定をしていません。
なので取れるデータは開始日から終了日までの全データのセッション数です。

ディメンションの設定をしたい場合は第五引数に
 {"dimensions":"ga:pageTitle"}
のような感じで設定します。


```Code.gs
function myFunction() {
  // 対象サイトの情報を設定
  var profile = Analytics.Management.Profiles.list("xxxxxxxx", "UA-xxxxxxxx-1");

  // 対象サイトの情報をAnalyticsから取得(期間指定)
  var ga_result = Analytics.Data.Ga.get(
	"ga:"+profile.getItems()[0].getId(),
	"2016-12-01",	// 開始日
	"2016-12-01",	// 終了日
	"ga:visits"	// メトリクス
	 {"dimensions":"ga:pageTitle"}	// ディメンション　
	);
  
  for(var rows = 0; rows < ga_result.getRows().length; rows++) {
      resultRow = ga_result.getRows()[rows];
      Logger.log(resultRow[0]);
    }
}
```

複数メトリクスを指定したい場合は、
"ga:visits,ga:pageViews”
みたいな感じで、stringの中でカンマ区切りで記述します。
ディメンションに関しても同じくです。

ディメンションとメトリクスの詳細は下記を参考にしてください。
私も全部を把握できていないので、取りたいディメンションはどれだ〜と都度探しています…笑

[Dimensions & Metrics Explorer](https://developers.google.com/analytics/devguides/reporting/core/dimsmets#cats=user)

[Google Analytics Data Export API リファレンス日本語訳](http://www.kagua.biz/api/gaapijp.html)

#まとめ

こんな感じで便利なGoogleの各種サービスをGASで実行する事が出来ます。
いやぁ、日々の作業を自動化していくとかすごく浪漫ですね(*´﹃｀*)
まだまだ連携した事の無いサービスがありますので、どんどん活用していきたいと思います！
皆様も良きGASライフを！