インストール可能なトリガー

シンプルなトリガーと同様に、インストール可能なトリガーを使用すると、ドキュメントの開くなど、特定のイベントが発生したときに、Apps Script が関数を自動的に実行できます。ただし、インストール可能なトリガーは、単純なトリガーよりも柔軟性があります。認可が必要なサービスを呼び出すことができ、時間駆動(時計)トリガーなど、複数の追加タイプのイベントを提供します。また、プログラムで制御できます。シンプルなトリガーとインストール可能なトリガーの両方で、Apps Script は、イベントが発生したコンテキストに関する情報が含まれるイベント オブジェクトをトリガーされた関数に渡します。

制限事項

インストール可能なトリガーはシンプルなトリガーよりも柔軟性がありますが、いくつかの制限があります。

  • ファイルが読み取り専用モード(表示またはコメント)で開かれている場合は実行されません。スタンドアロン スクリプトの場合、トリガーを適切に実行するには、ユーザーにスクリプト ファイルに対する少なくとも閲覧権限が必要です。
  • スクリプトの実行や API リクエストによってトリガーが実行されることはありません。たとえば、FormResponse.submit() を呼び出して新しいフォーム レスポンスを送信しても、フォームの送信トリガーは実行されません。

  • インストール可能なトリガーは、常に作成したユーザーのアカウントで実行されます。たとえば、インストール可能な開くトリガーを作成すると、同僚がドキュメントを開いたときにトリガーが実行されます(同僚に編集権限がある場合)。ただし、実行されるのはあなたのアカウントです。つまり、ドキュメントが開かれたときにメールを送信するトリガーを作成した場合、メールは常に自分のアカウントから送信されます。ドキュメントを開いたアカウントから送信されるとは限りません。ただし、アカウントごとにインストール可能なトリガーを作成すると、アカウントごとに 1 通のメールが発送されます。

  • 1 つのアカウントでは、2 つ目のアカウントからインストールされたトリガーを表示できませんが、1 つ目のアカウントでそのトリガーを有効にすることはできます。

  • インストール可能なトリガーには、Apps Script トリガーの割り当て上限が適用されます。

時間ドリブンのトリガー

時間駆動型トリガー(クロック トリガー)は、Unix の cron ジョブに似ています。時間ベースのトリガーを使用すると、特定の時間または一定の間隔でスクリプトを実行できます。実行頻度は 1 分ごとから 1 か月ごとまで設定できます。(アドオンで時間ベースのトリガーを使用できるのは 1 時間に 1 回までです)。時間は若干ランダムに設定される場合があります。たとえば、午前 9 時のトリガーを作成した場合、Apps Script は午前 9 時から午前 10 時の間の時刻を選択し、そのタイミングを毎日一定に保ちます。これにより、トリガーが再び実行されるまでに 24 時間が経過します。

次の例は、アプリが存在するすべてのスペースに 1 分ごとにメッセージを投稿する Google Chat アプリの例です。

// Example app for Google Chat that demonstrates app-initiated messages
// by spamming the user every minute.
//
// This app makes use of the Apps Script OAuth2 library at:
//     https://github.com/googlesamples/apps-script-oauth2
//
// Follow the instructions there to add the library to your script.

// When added to a space, we store the space's ID in ScriptProperties.
function onAddToSpace(e) {
  PropertiesService.getScriptProperties()
      .setProperty(e.space.name, '');
  return {
    'text': 'Hi! I\'ll post a message here every minute. ' +
            'Please remove me after testing or I\'ll keep spamming you!'
  };
}

// When removed from a space, we remove the space's ID from ScriptProperties.
function onRemoveFromSpace(e) {
  PropertiesService.getScriptProperties()
      .deleteProperty(e.space.name);
}

// Add a trigger that invokes this function every minute in the
// "Edit > Current Project's Triggers" menu. When it runs, it
// posts in each space the app was added to.
function onTrigger() {
  var spaceIds = PropertiesService.getScriptProperties()
      .getKeys();
  var message = { 'text': 'Hi! It\'s now ' + (new Date()) };
  for (var i = 0; i < spaceIds.length; ++i) {
    postMessage(spaceIds[i], message);
  }
}
var SCOPE = 'https://www.googleapis.com/auth/chat.bot';
// The values below are copied from the JSON file downloaded upon
// service account creation.
// For SERVICE_ACCOUNT_PRIVATE_KEY, remember to include the BEGIN and END lines
// of the private key
var SERVICE_ACCOUNT_PRIVATE_KEY = '...';
var SERVICE_ACCOUNT_EMAIL = 'service-account@project-id.iam.gserviceaccount.com';

// Posts a message into the given space ID via the API, using
// service account authentication.
function postMessage(spaceId, message) {
  var service = OAuth2.createService('chat')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')
      .setPrivateKey(SERVICE_ACCOUNT_PRIVATE_KEY)
      .setClientId(SERVICE_ACCOUNT_EMAIL)
      .setPropertyStore(PropertiesService.getUserProperties())
      .setScope(SCOPE);
  if (!service.hasAccess()) {
    Logger.log('Authentication error: %s', service.getLastError());
    return;
  }
  var url = 'https://chat.googleapis.com/v1/' + spaceId + '/messages';
  UrlFetchApp.fetch(url, {
    method: 'post',
    headers: { 'Authorization': 'Bearer ' + service.getAccessToken() },
    contentType: 'application/json',
    payload: JSON.stringify(message),
  });
}

イベント ドリブン トリガー

インストール可能なイベントドリブン トリガーは、onOpen() などの単純なトリガーと概念的には似ていますが、追加のイベントに応答でき、動作が異なります。

たとえば、Google スプレッドシート用にインストール可能なオープン トリガーは、単純な onOpen() トリガーと同様に、編集権限を持つユーザーがスプレッドシートを開くたびにアクティブになります。ただし、インストール可能なバージョンでは、認可が必要なサービスを呼び出すことができます。インストール可能なバージョンは、編集権限を持つ別のユーザーがスプレッドシートを開いた場合でも、トリガーを作成したユーザーの承認で実行されます。

Google Workspace アプリケーションには、インストール可能なトリガーがいくつかあります。

  • インストール可能なopen トリガーは、ユーザーが編集権限を持つスプレッドシート、ドキュメント、フォームを開いたときに実行されます。
  • インストール可能な編集トリガーは、ユーザーがスプレッドシート内の値を変更したときに実行されます。
  • インストール可能な変更トリガーは、ユーザーがスプレッドシート自体の構造を変更したときに実行されます(新しいシートの追加や列の削除など)。
  • インストール可能なフォーム送信トリガーは、ユーザーがフォームに回答したときに実行されます。フォーム送信トリガーには、Google フォーム自体用と、フォームがスプレッドシートに送信される場合のスプレッドシート用の 2 つのバージョンがあります。
  • インストール可能なカレンダーの予定トリガーは、ユーザーのカレンダーの予定が更新されたとき(作成、編集、削除)に実行されます。

インストール可能なトリガーは、スタンドアロン スクリプトとバインド スクリプトで使用できます。たとえば、スタンドアロン スクリプトでは、TriggerBuilder.forSpreadsheet(key) を呼び出してスプレッドシートの ID を渡すことで、任意の Google スプレッドシート ファイルのインストール可能なトリガーをプログラムで作成できます。

トリガーを手動で管理する

スクリプト エディタでインストール可能なトリガーを手動で作成する手順は次のとおりです。

  1. Apps Script プロジェクトを開きます。
  2. 左側の [トリガー] をクリックします。
  3. 右下の [トリガーを追加] をクリックします。
  4. 作成するトリガーのタイプを選択して構成します。
  5. [保存] をクリックします。

トリガーをプログラムで管理する

スクリプト サービスを使用して、トリガーをプログラムで作成および削除することもできます。まず、ScriptApp.newTrigger(functionName) を呼び出して TriggerBuilder を返します。

次の例は、2 つの時間ベースのトリガーを作成する方法を示しています。1 つは 6 時間ごとにトリガーされ、もう 1 つは毎週月曜日の午前 9 時にトリガーされます(スクリプトが設定されているタイムゾーン)。

triggers/triggers.gs
/**
 * Creates two time-driven triggers.
 * @see https://developers.google.com/apps-script/guides/triggers/installable#time-driven_triggers
 */
function createTimeDrivenTriggers() {
  // Trigger every 6 hours.
  ScriptApp.newTrigger('myFunction')
      .timeBased()
      .everyHours(6)
      .create();
  // Trigger every Monday at 09:00.
  ScriptApp.newTrigger('myFunction')
      .timeBased()
      .onWeekDay(ScriptApp.WeekDay.MONDAY)
      .atHour(9)
      .create();
}

次の例は、スプレッドシート用にインストール可能なオープン トリガーを作成する方法を示しています。単純な onOpen() トリガーとは異なり、インストール可能なトリガーのスクリプトはスプレッドシートにバインドする必要はありません。スタンドアロン スクリプトからこのトリガーを作成するには、SpreadsheetApp.getActive()SpreadsheetApp.openById(id) の呼び出しに置き換えます。

triggers/triggers.gs
/**
 * Creates a trigger for when a spreadsheet opens.
 * @see https://developers.google.com/apps-script/guides/triggers/installable
 */
function createSpreadsheetOpenTrigger() {
  const ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger('myFunction')
      .forSpreadsheet(ss)
      .onOpen()
      .create();
}

既存のインストール可能なトリガーをプログラムで変更するには、トリガーを削除して新しいトリガーを作成する必要があります。トリガーの ID を以前に保存している場合は、ID を引数として次の関数に渡すことで削除できます。

triggers/triggers.gs
/**
 * Deletes a trigger.
 * @param {string} triggerId The Trigger ID.
 * @see https://developers.google.com/apps-script/guides/triggers/installable
 */
function deleteTrigger(triggerId) {
  // Loop over all triggers.
  const allTriggers = ScriptApp.getProjectTriggers();
  for (let index = 0; index < allTriggers.length; index++) {
    // If the current trigger is the correct one, delete it.
    if (allTriggers[index].getUniqueId() === triggerId) {
      ScriptApp.deleteTrigger(allTriggers[index]);
      break;
    }
  }
}

トリガーのエラー

インストール可能なトリガーがトリガーされたものの、関数から例外がスローされた場合や、関数が正常に実行されなかった場合、画面にエラー メッセージは表示されません。時間ベースのトリガーが実行されたり、別のユーザーがフォーム送信トリガーを有効にしたりしても、パソコンの前にいないこともあります。

代わりに、次のようなメールが送信されます。

From: noreply-apps-scripts-notifications@google.com
Subject: Summary of failures for Google Apps Script
Your script has recently failed to finish successfully.
A summary of the failure(s) is shown below.

このメールには、トリガーを無効にするか再構成するためのリンクが記載されています。スクリプトが Google スプレッドシート、ドキュメント、フォームのファイルにバインドされている場合、そのファイルへのリンクもメールに含まれます。これらのリンクを使用すると、トリガーを無効にしたり、スクリプトを編集してバグを修正したりできます。

Google アカウントに関連付けられているすべてのトリガーを確認し、不要なトリガーを無効にする手順は次のとおりです。

  1. script.google.com にアクセスします。
  2. 左側の [トリガー] をクリックします。
  3. トリガーを削除するには、トリガーの右側にあるその他アイコン > [トリガーを削除] をクリックします。

アドオンのトリガー

インストール可能なトリガーに加えて、アドオンでマニフェスト トリガーを使用できます。詳しくは、Google Workspace アドオンのトリガーをご覧ください。