[GAS] はじめての Google Apps Script

Google Apps Script(以降GAS)は、多少語弊がありますが雑に言うとGoogleDrive上で動作させるプログラムの実行環境です。今回は初歩的な利用方法についてメモしておきます。

特徴

GASはEXCELやWORDなどMS Officeで言うところのVBAのGoogle版だと思えばイメージしやすいと思います。GoogleSpreadSheetやDocumentなどGoogleのOfficeSuiteはもちろん、その他のGoogleのサービスと連携することが簡単にできるのが強みですね。またGASの開発言語はJavaScriptとなっており、すでにJSが使える方にとっては新たに言語仕様を学習するコストがないのも魅力です。

  • Google SpreadSheets, Docs, Slides, Forms内に埋め込むことが可能
    • もちろん単独のスクリプトとして動作させることも可能
  • GMail, GoogleDrive, Calender, YouTubeなどGoogleの様々なサービスとの連携が可能
  • RESTfull APIの作成が可能
    • 何ならHTMLを出力してちょっとしたサイトの構築も可能
  • 指定時間に起動させることが可能(cron)
  • 外部のURLにリクエストを飛ばすことが可能
  • 専用の開発環境(エディタ)付き

制限はありますがこれらがすべて無料で利用できる点も大きいですね。

準備

Googleアカウントをご準備ください。これがないと話が始まりませんw 新規でのアカウント作成はこちらから。開発用に本番とは別のアカウントを作って置くと安心です。

GoogleDriveにGASを追加

GASはGoogleDrive上で動かしますのでDriveへログインしてください。 drive.google.com

左上にある「新規」ボタンをクリック

「その他」→「アプリを追加」を選択

「GoogleAppsScript」を選択。最初から表示されていますが、もし存在しなければ検索してください。

「接続」ボタンをクリック

以下のようなダイアログが表示されれば成功です。

プロジェクトを作成

最初にGASのプロジェクトを作成します。 GoogleDrive左上の「新規」ボタンをクリックし、「その他」→「GoogleAppsScript」を選択。

開発用のエディタが開きます。 今後はここでコードを書いていくことになります。

この状態だと保存されていませんので、上部にある「無題のプロジェクト」をクリックするとプロジェクト名の入力を求められますので適当な名前を入れます。日本語でもOK。

しばらくするとプロジェクト名が変化しますので、GoogleDriveのタブに戻るとGAS用のプロジェクトがファイルとして登場します。

このプロジェクトファイルは場所を移動したり名前を変更しても問題ありません。 これで準備は整いました。簡単ですよね?

HelloWorld

その場で実行

では早速HelloWorldしてみましょう。デフォルトで存在しているmyFunctionの中に1行追加してみました。必ずCtrl+Sか、「ファイル」メニューから「保存」を実行してください。挙動が変わらないと思ったら保存されてなかったパターンで割と痛い目に会いますw

Logger.log()はGASから提供されている機能で、Webブラウザで言うconsole.log()のような物です。デバッグ用に一時的になにか値を出力したい場合に利用します。

function myFunction() {
  Logger.log("HelloWorld");
}

メニューの「実行」→「関数を実行」から実行したい関数を選択します。今回はmyFunction()を選択。 GASでは原則として関数単位で実行することになります。

ログを出力するだけなので画面上に特に変化はないのですが、メニュー「表示」→「ログ」から先程出力した内容を確認できます。

ご覧の通りです。 日時は自動的に付加されます。また実行する度にログの内容はリセットされますのでご注意を。

現在時間がPSTと表示されていたら?

日本時間であるJSTにするには単純に17時間足します。

  • PST(太平洋標準時)はUTCから8時間遅らせた物 (UTC-0800)
  • JST(日本時間)はUTCから9時間進めた物 (UTC+0900)

エディターのメニュー「ファイル」→「プロジェクトのプロパティ」からタイムゾーンの設定ができるのですが、なぜか別の物になることがあるようです。

指定した時間に実行

冒頭でお話した通り、指定時間に、指定関数を実行できます。

メニュー「編集」から「現在のプロジェクトのトリガー」を選択。

新しくウィンドウ(タブ)が開き、現在のプロジェクトに設定されている「トリガー」の一覧が表示されます。まだ何も設定していないので現在は空っぽです。画面右下にある「トリガーを追加」ボタンをクリック。

いつ実行するのか設定するダイアログが開きますので、入力します。 毎日、毎時間、毎分、特定の曜日など様々な設定が行なえますが、ここでは特定の時間に1回だけ実行するよう設定しました。画面に書いてありますが、ここは GMT+9とあるので日本時間で設定します。入力が終わったら「保存」ボタンをクリック。

トリガーが1つ追加された状態になりました。このウィンドウ(タブ)は閉じても大丈夫です。

指定した時間以降にメニュー「表示」→「ログ」を見ると、先程指定した時間に実行されているのがわかります。こちらはPST(太平洋標準時)で表示されたので、17時間追加して日本時間で考えます。

RESTfull APIとして実行

お次にRESTfull APIとして外部から自由自在に呼び出せるようにしてみます。 コードを以下のように書き換えました。myFunction()はそのままにして別の場所に書いても、削除してしまってもどちらでもOKです。

GASではGETメソッドでアクセスされたときにdoGet()関数を実行すると決め打ちされていますので、関数名は必ずdoGet()にしておく必要があります。POSTメソッドの挙動を定義したい場合はdoPost()です。

function doGet(e) {
  // 返却するJSON文字列を作成
  var payload = JSON.stringify([{message:"HelloWorld", time:new Date().getTime()}]);

  // レスポンス値を準備
  var output  = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);  //MIME Typeの設定
  output.setContent(payload);  // 内容をセット

  return(output);
}

まずはメニュー「公開」から「実行可能APIとして導入」をクリック。

バージョンの説明に適当な文字列を入力、アクセス可能なユーザーは「自分のみ」か「全員」の2種類から選べます。自分だけは開発用ですね。今回は「全員」を選択。

こんな感じのダイアログが表示されればAPIとしての登録が完了しています。「閉じる」ボタンで閉じます。

次にこのAPIを公開する作業を行います。 メニュー「公開」から「ウェブアプリケーションとして導入」をクリック。

「導入」ボタンをクリックします(2回目以降は「更新」にボタンの名称が変わります)。 ここでAPIのバージョンを指定できますので、なにかあった場合に特定のバージョンに切り戻すことが可能です。

以下のダイアログが表示されれば成功です。表示されたURLをメモしましょう。

先程のURLにブラウザからアクセスすると無事にJSONが返ってきました。リロードする度にUNIX時間が変化しますね。

この時のレスポンスヘッダは以下のようになっています。MIMEはapplication/json、CORS用のAccess-Control-Allow-Originがアスタリスク(*)になってますので、どこからでもリクエスト可能です。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Thu, 14 Feb 2019 07:42:18 GMT
Content-Encoding: gzip
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39"
Transfer-Encoding: chunked

要注意

なお、この時点ではログイン中のブラウザからしかリクエストを受け付けてくれません。試しに別のブラウザやCLIなどでリクエストを送るとログインが表示されます。

当初設定したように誰でもリクエストを受け付けてくれるようになるまで、かなりの時間がかかります。少なくと1時間〜数時間程度は見ておいた方が良いです。同様に「更新」をした場合も同じように長時間待たされますので、公開する際には十分に注意してください。巻き戻そうと思っても中々戻りません。

GASは手軽に使えて面白いのですが、この本番反映に時間がかかる点だけは非常にストレスフルです。 正直ちょっとしたAPIを作るなら素直にAWSならAPI Gateway+Lambdaあたりを使った方が作りやすいです。GASが向いているのは例えばSpreadsheetのデータをREST APIで取り出すといったGoogleのサービスと連携したい場合ですね。

「承認が必要です」と表示されたら?

GASのスクリプトを実行する際に以下のようなダイアログが登場することがあります。GASから何らかのGoogleのサービスを操作する際には最初の1回だけ許可を求められるためです。ここまではGAS単体で動作させているため発生しませんでしたが、これ以降の項目では都度登場しすることになります。

では承認作業をしますか。まずは「許可を確認」をクリック

利用するアカウントを選択します。

「このアプリは確認されていません」というエラーっぽい画面になりますが大丈夫です。 「詳細」という小さい文字のリンクをクリック。

一番下にある「〜安全ではないページへ移動」をクリック

OAuthっぽい画面になりました。「許可」ボタンをクリック

外部と通信する

UrlFetchApp.fetch()を利用することで外部と通信が行えます。

GET

NICTが現在時間を返却してくれるAPIを公開しているので、これを利用してみます。 www.nict.go.jp

function myFunction(){
  var response = UrlFetchApp.fetch("https://ntp-a1.nict.go.jp/cgi-bin/json");
  var results  = JSON.parse(response.getContentText());

  Logger.log(results);
}

結果はご覧の通りです。無事に取れてますね。

クエリーを付けたい場合は、URLのお尻に付けてあげます。 URLエンコードをお忘れなく。

var url = "https://example.com/api?query=" + encodeURIComponent("ほげ");
UrlFetchApp.fetch(url);

POST

POSTメソッドの場合は以下のように第2引数にハッシュを渡して指定します。

function myFunction(){
  var url = 'https://example.com/foo';
  var options = {
    "method" : "POST",
    "headers": {"Content-type": "application/json"},
    "payload" : '{"text":"' + text + '"}'
  };

  UrlFetchApp.fetch(url, options);
}

Google SpreadSheet

GoogleのOffice Suite系はどれも2種類の操作方法があります。ここではSpreadSheetを例に実行してみます。

A) GASを内部に埋め込む

まずはGASをSpreadSheet内に埋め込むやり方です。 何らかの方法でGoogleDriveにSpreadsheetsを作成します。左上の「新規」ボタンや、右クリック(コンテキストメニュー)などから作成できます。

適当な名前をつけます。ここではSampleにしました。

メニュー「ツール」→「スクリプトエディタ」を選択。

このタイミングで新しくウィンドウ(タブ)が起動するのですが、GoogleChromeを利用している場合、ポップアップブロックが作動する場合があるので解除してもう一度スクリプトエディタを起動します。

以下のようなコードを書きました。セルA1に指定の文字列を記録するだけです。

function myFunction() {
  var sheet = SpreadsheetApp.getActive().getSheetByName("シート1");
  sheet.getRange("A1").setValue("HelloWorld");
}

実行はこれまで説明した方法と同じです。

実行結果はご覧の通り。

B) GASを独立したファイルで実行する

個人的にはこのパターンを利用することが多いのですが、指定したSpreadsheetsを外部のGASプロジェクトから操作します。

最初に操作したいSpreadsheetをブラウザで開き、URLの赤線の箇所をメモします。

適当なGASのプロジェクトに以下のようなコードを記述します。 SpreadsheetApp.openById()の引数として最初にメモしたURLの一部を渡します。

function myFunction() {
  var spreadsheet = SpreadsheetApp.openById("1giiHqICdZFE5FOlSuS6w5ZL7mLUSU8as_vMfrqA40Tg");
  var sheet = spreadsheet.getSheetByName("シート1");
  sheet.getRange("A2").setValue("HelloWorld");
}

これまでと同様にmyFunction()を実行すると、無事にセルA2へ文字列を書き込むことができました。

セルに値を書き込む

function sheet1() {
  var spreadsheet = SpreadsheetApp.openById("1giiHqICdZFE5FOlSuS6w5ZL7mLUSU8as_vMfrqA40Tg");
  var sheet = spreadsheet.getSheetByName("シート1");
  sheet.getRange("A2").setValue("YAEH!");
}

セルの値を参照する

function sheet2() {
  var spreadsheet = SpreadsheetApp.openById("1giiHqICdZFE5FOlSuS6w5ZL7mLUSU8as_vMfrqA40Tg");
  var sheet = spreadsheet.getSheetByName("シート1");

  Logger.log( sheet.getRange("A2").getValue() );
}

シートの一覧を取得する

function sheet3() {
  var spreadsheet = SpreadsheetApp.openById("1giiHqICdZFE5FOlSuS6w5ZL7mLUSU8as_vMfrqA40Tg");
  var sheet = spreadsheet.getSheets();

  for(var i=0; i<sheet.length; i++){
    Logger.log( "ID:"+sheet[i].getSheetId() +", Name:"+sheet[i].getSheetName() );
  }
}

Google Drive

DriveAppクラスを利用しGoogleDriveにファイルの保存や読み込みが可能です。 developers.google.com

ファイルを作成する

以下のコードで、Driveの一番上の階層に新規にファイルが作成されます。

function drive1a(){
  var name = '吾輩は猫である.txt';
  var body = '吾輩は猫である。名前はまだ無い。';

  DriveApp.createFile(name, body);
}

特定のディレクトリに保存するには以下のようにFolderオブジェクトを取得した上でcreateFile()メソッドを実行します。

function drive1b(){
  var name = '吾輩は猫である.txt';
  var body = '吾輩は猫である。名前はまだ無い。';
  var dir  = 'foo';

  var folder = DriveApp.getFoldersByName(dir).next();
  folder.createFile(name, body);
}

ファイルの一覧を取得

DriveApp.getFiles()でファイルの一覧を取得することができます。

function drive2a(){
  var files = DriveApp.getFiles();
  while ( files.hasNext() ) {
    var file = files.next();
    Logger.log(file.getName());
  }
}

特定のフォルダのファイル一覧の取得は以下の通り。フォルダのオブジェクトを取得する必要がありまs。

function drive2b(){
  var dir  = 'foo';
  var folder = DriveApp.getFoldersByName(dir).next();

  var files = folder.getFiles();
  while ( files.hasNext() ) {
    var file = files.next();
    Logger.log(file.getName());
  }
}

ファイルを読み込む

FILEオブジェクトのgetBlob()メソッドで内容を取得することができます。テキストとして取得したい場合はgetDataAsString()を通します。

function drive3(){
  var file = DriveApp.getFilesByName('吾輩は猫である.txt').next();
  var buff;

  switch( file.getMimeType() ){
    case MimeType.PLAIN_TEXT:
      buff = file.getBlob().getDataAsString('utf8');
      break;
    default:
      buff = file.getBlob();
  }

  Logger.log(buff);  
}

developers.google.com

ファイルを削除する

厳密にはゴミ箱に送るのですが、FILEクラスのsetTrashed()trueを渡すことで実現できます。

function drive4a(){
  var name = '吾輩は猫である.txt';
  var file = DriveApp.getFilesByName(name).next();
  file.setTrashed(true);
}

フォルダの削除は以下の通りです。フォルダ内にファイル等が存在していても問答無用でゴミ箱に移りますのでご注意を。

function drive4b(){
  var name   = 'foo';
  var folder = DriveApp.getFoldersByName(name).next();
  folder.setTrashed(true);
}

ファイルをコピーする

FILEクラスのmakeCopy()メソッドを利用します。

function drive5(){
  var from = '吾輩は猫である.txt';
  var to   = '吾輩は猫である_2.txt';
  var file = DriveApp.getFilesByName(from).next();
  file.makeCopy(to);
}

ファイルを移動する

どうも移動用のメソッドが用意されていないようなので、ファイルをコピーした後にオリジナルを削除します。

function drive6(){
  var from = '吾輩は猫である.txt';
  var to   = '吾輩は猫である_move.txt';
  var file = DriveApp.getFilesByName(from).next();
  file.makeCopy(to);
  file.setTrashed(true);
}

GMail

GMailを操作するにはGmailAppクラスを利用します。 developers.google.com

メールを検索する

GMailをお使いであればイメージできると思うのですが、メールが1件ずつ独立して存在しているわけではなく、複数のメールが「スレッド」の中にグルーピングされています。これを念頭に置く必要があります。

以下は受信箱にある未読のメールの件名と日付を取り出すサンプルです。 処理的にはGmailApp.search()でスレッドを検索し、結果を変数inboxに格納。inboxにあるスレッドをループで回し、その中にあるメッセージ(メール)を取り出してLoggerに出力しているだけです。

function gmail1(){
  var inbox = GmailApp.search("label:inbox is:unread", 0, 10); //0番目〜最大10スレッドまで
  var result = "";

  for (var i=0; inbox[i]; i++){
    var messages = inbox[i].getMessages();
    for (var j=0; j<messages.length; j++) {
      var subject = messages[j].getSubject();
      var date = messages[j].getDate();
      Logger.log( subject + ":" + date);
    }
  }  
}

各メッセージ(メール)に対して様々なメソッドが用意されており、以下のページから確認することができます。 developers.google.com

また同様にスレッド自体にまとめて処理をすることも可能です。 developers.google.com

メールを送信する

GmailApp.sendEmail()を利用します。

function gmail2(){
  var to      = 'katsubemakito@gmail.com';
  var subject = 'テストメール';
  var body    = 'ここに本文を記入';

  GmailApp.sendEmail(to, subject, body, {
    name: 'M.Katsube'
  });
}

Fromのメールアドレスは変更することができますが、予めGMailに登録しておく必要があります。オプションでfrom, cc指定や、添付ファイルをつけることもできます。

添付ファイル付き

GoogleDrive内のファイルを添付ファイルとしてつけることが可能です。

function gmail3(){
  var to      = 'katsubemakito@gmail.com';
  var subject = '添付ファイルのテストメール';
  var body    = 'ご査収ください';

  GmailApp.sendEmail(to, subject, body, {
    name: 'M.Katsube',
    attachments: [_getFile('吾輩は猫である.txt', MimeType.PLAIN_TEXT)]
  });
}

function _getFile(name, type){
  var file = DriveApp.getFilesByName(name).next();
  return( file.getAs(type) );
}

メールを削除する

厳密にはゴミ箱に移動させます。GmailMessageオブジェクトのmoveToTrash()メソッドを利用します。

function gmail4(){
  var inbox = GmailApp.search("label:inbox", 0, 10); //0番目〜最大10スレッドまで

  for (var i=0; inbox[i]; i++){
    var messages = inbox[i].getMessages();
    for (var j=0; j<messages.length; j++) {
      // 差出人(From)が特定のメールアドレスなら
      if( messages[j].getFrom().match(/foo@example\.com/ ){
        //ゴミ箱へ移動
        messages[j].moveToTrash();
      }
    }
  }  
}

メールを既読/未読にする

GmailMessageオブジェクトのmarkRead()メソッドで既読に、markUnread()メソッドで未読に変更できます。

function gmail5(){
  var inbox = GmailApp.search("label:inbox", 0, 10);  //0番目〜最大10スレッドまで

  for (var i=0; inbox[i]; i++){
    var messages = inbox[i].getMessages();
    for (var j=0; j<messages.length; j++) {
      var sendtime = messages[j].getDate().getTime();  //メールの送信時間
      var nowtime  = new Date().getTime();             //現在時間

      // 送信日から3日以上経過していれば
      if( (nowtime - sendtime) >= ( 1000 * 60 * 60 * 24 * 3) ){
        // 既読にする
        messages[j].markRead();
      }
      // 件名に "緊急" と入っていれば
      if( messages[j].getSubject().match(/緊急/) ){
        // 未読にする
        messages[j].markUnread();
      }
    }
  }  
}

ここでは個別のメッセージに対して行いましたが、GmailThreadクラスにも同様のメソッドが用意されていますので、スレッドに対してまるごと未読・既読の設定を行うことも可能です。

ラベルを操作する

ラベルはメッセージではなく、スレッドに紐付いているためGmailThreadオブジェクトを操作します。

スレッドのラベルを取得

スレッドに対してgetLabels()メソッドを実行すると、GmailLabelオブジェクトの配列が返ってきますので、forなどで回しながらgetname()すればラベル名を取り出すことができます。

function gmail6(){
  var inbox = GmailApp.search("label:inbox", 0, 10);  //0番目〜最大10スレッドまで

  for (var i=0; inbox[i]; i++){
    var labels = inbox[i].getLabels();
    var names  = [];
    for( var j=0; j<labels.length; j++ ){
      names.push( labels[j].getName() );
    }
    Logger.log(names.join(','));
  }
}

スレッドにラベルを追加

GmailThreadオブジェクトのaddLabel()メソッドでラベルを追加できますが、注意点としてはこのメソッドには文字列ではなくGmailLabelオブジェクトを引数として渡す必要があります。

以下のサンプルは実行前に"Amazon"という名前のラベルを事前に新規作成しておく必要があります。

function gmail7(){
  var inbox = GmailApp.search("label:inbox", 0, 10);  //0番目〜最大10スレッドまで
  var label = GmailApp.getUserLabelByName("Amazon");  //"Amazon"という名前のラベルを取得(事前に作成しておく必要あり)

  for (var i=0; inbox[i]; i++){
    // スレッドの最初のメールの件名に "Amazon" が含まれていれば
    if( inbox[i].getFirstMessageSubject().match(/Amazon/) ){
      // ラベルを追加
      inbox[i].addLabel(label);
    }
  }
}

スレッドのラベルを削除

ラベルの追加とやり方はほぼ同じです。GmailThreadオブジェクトのremoveLabel()メソッドでラベルを削除できます。引数にはGmailLabelオブジェクトを渡す必要があります。

function gmail8(){
  var inbox = GmailApp.search("label:inbox", 0, 10);  //0番目〜最大10スレッドまで
  var label = GmailApp.getUserLabelByName("Amazon");  //"Amazon"という名前のラベルを取得(事前に作成しておく必要あり)

  for (var i=0; inbox[i]; i++){
    // ラベルを削除
    inbox[i].removeLabel(label);
  }
}

指定のラベルが存在しないスレッドに対して実行してもエラーで停止するなどにはならないようです。

Google Calender

予定を追加する

デフォルトのカレンダーにイベント(予定)を追加します。時間はGMTではなくプロジェクトのローカルタイムが採用されるようです。第4引数のオプション群は必要なければ指定する必要はありません。

function cal1(){
  var event = CalendarApp.getDefaultCalendar().createEvent(
                  'チャーハンを作る',               // タイトル
                  new Date('2019-02-18T12:00:00'),  // 開始時間
                  new Date('2019-02-18T13:00:00'),  // 終了時間
                  {
                    description: "こぼさずに作るよ!",
                    location: "東京都",
                    guests: "katsubemakito@gmail.com,katsube@winning-section.net",
                    sendInvites: false
                  }
              );

  Logger.log('Event ID: ' + event.getId()); 
}

以下のように追加されます。

予定の一覧を取得する

特定の日付

function cal2(){
  var today = new Date('2019-02-18');
  var events = CalendarApp.getDefaultCalendar().getEventsForDay(today);

  for(var i=0; i<events.length; i++){
    var title = events[i].getTitle();       //タイトル
    var from  = events[i].getStartTime();   //開始時間(Dateオブジェクト)
    var to    = events[i].getEndTime();     //終了時間(Dateオブジェクト)
    var desc  = events[i].getDescription(); //説明
    var loc   = events[i].getLocation();    //場所

    Logger.log([title, from.toString(), to.toString(), desc, loc].join(":"));
  }
}

その他

短所

手軽に利用できて非常に便利なGASですが、もちろん惜しい点も色々あります。

  • 言語仕様が古い。ES2015以降のナウい書き方をするには工夫が必要。
  • 外部に公開する際の反映時間が非常に長い
  • 外部に公開する前にテストをする際にはGoogleアカウントでのログインが必須
  • 長大なコードを書くのは可能だが管理が大変
  • 完全なローカルでの開発は難しい

まぁ万能な物などこの世にありませんので、使い所がマッチすれば非常に強力な武器として機能してくれます。

制限

GASはGoogleアカウントの契約状態によって、どの程度のリソースを利用できるか上限が定められています。

Consumer
一般的なGoogleアカウント利用者。
G Suite
GSuiteの利用者。無料、ベーシック、ビジネス、エンタープライズ、エデュケーションでそれぞれ上限が設定されています。
Early Access
GSuiteBusinessユーザーで、GASの新機能をいち早く利用したいと自ら申請したユーザーです(詳細)

具体的には以下の表のように定義されています。 例えばConsumerであればスクリプトの実行時間は1回につき6分以内、外部のURLにリクエストを飛ばすのは1日20,000回までといった具合です。

Feature Consumer
(e.g., gmail.com)
G Suite free edition (legacy) G Suite
Basic / Gov
G Suite Business / Enterprise / Education Early Access
Script runtime 6 min / execution 6 min / execution 6 min / execution 30 min / execution 30 min / execution
Custom function runtime 30 sec / execution 30 sec / execution 30 sec / execution 30 sec / execution 30 sec / execution
Simultaneous executions 30 30 30 30 60
Email attachments 250 / msg 250 / msg 250 / msg 250 / msg 250 / msg
Email body size 200kB / msg 200kB / msg 400kB / msg 400kB / msg 400kB / msg
Email recipients per message 50 / msg 50 / msg 50 / msg 50 / msg 50 / msg
Email total attachments size 25MB / msg 25MB / msg 25MB / msg 25MB / msg 25MB / msg
Properties value size 9kB / val 9kB / val 9kB / val 9kB / val 9kB / val
Properties total storage 500kB / property store 500kB / property store 500kB / property store 500kB / property store 500kB / property store
Triggers 20 / user / script 20 / user / script 20 / user / script 20 / user / script 20 / user / script
URL Fetch response size 50MB / call 50MB / call 50MB / call 50MB / call 50MB / call
URL Fetch headers 100 / call 100 / call 100 / call 100 / call 100 / call
URL Fetch header size 8kB / call 8kB / call 8kB / call 8kB / call 8kB / call
URL Fetch POST size 50MB / call 50MB / call 50MB / call 50MB / call 50MB / call
URL Fetch URL length 2kB / call 2kB / call 2kB / call 2kB / call 2kB / call
Feature Consumer
(e.g., gmail.com)
G Suite free edition (legacy) G Suite
Basic / Gov
G Suite Business / Enterprise / Education Early Access
Calendar events created 5,000 / day 10,000 / day 10,000 / day 10,000 / day Flexible
Contacts created 1,000 / day 2,000 / day 2,000 / day 2,000 / day Flexible
Documents created 250 / day 500 / day 1,500 / day 1,500 / day Flexible
Email recipients per day 100* / day 100* / day 1,500* / day 1,500* / day 1,500* / day
Email read/write (excluding send) 20,000 / day 40,000 / day 50,000 / day 50,000 / day Flexible
Groups read 2,000 / day 5,000 / day 10,000 / day 10,000 / day Flexible
JDBC connection 10,000 / day 10,000 / day 50,000 / day 50,000 / day Flexible
JDBC failed connection 100 / day 100 / day 500 / day 500 / day 500 / day
Presentations created 250 / day 500 / day 1,500 / day 1,500 / day Flexible
Properties read/write 50,000 / day 100,000 / day 500,000 / day 500,000 / day Flexible
Spreadsheets created 250 / day 500 / day 3,200 / day 3,200 / day Flexible
Triggers total runtime 90 min / day 3 hr / day 6 hr / day 6 hr / day 6 hr / day
URL Fetch calls 20,000 / day 50,000 / day 100,000 / day 100,000 / day Flexible

上記は2018年8月時点の物になります。 予告なく変更されますので、気になったら最新のドキュメントを参照してみてください。 developers.google.com

参考ページ

developers.google.com

書籍

詳解! GoogleAppsScript完全入門 ~GoogleApps & G Suiteの最新プログラミングガイド~
高橋宣成
秀和システム
売り上げランキング: 7,983