Google Chat で連絡先を収集、管理する

このチュートリアルでは、Google Chat ユーザーが個人用とビジネス用の連絡先を管理するのに役立つ Google Chat 用アプリを構築する方法について説明します。情報を収集するために、Chat 用アプリはカード メッセージとダイアログで連絡先フォームの入力を行うようユーザーに促します。

Chat 用アプリの動作を確認する:

  • スラッシュ コマンドからのお問い合わせフォーム。
    図 1: Chat 用アプリは、スラッシュ コマンド /about に対して、連絡フォームを開くテキスト メッセージとボタンで応答します。
  • ダイアログ内の問い合わせフォーム。
    図 2. Chat 用アプリで、ユーザーが連絡先に関する情報を入力できるダイアログが開きます。
  • 確認とレビューのダイアログ。
    図 3. Chat 用アプリは確認ダイアログを返します。ユーザーは、送信前に情報を確認できます。
  • 新しい連絡先を確認するテキスト メッセージ。
    図 4. ユーザーがフォームを送信すると、Chat 用アプリから非公開のテキスト メッセージが送信され、送信が確認されます。
  • カード メッセージの問い合わせフォーム。
    図 5. また、Chat 用アプリでは、メッセージ内のカードから連絡先を追加するようユーザーに求めることもできます。

前提条件

目標

アーキテクチャ

Chat 用アプリは Google Apps Script で構築され、インタラクション イベントを使用して Chat ユーザーを処理し、応答します。

以下に、ユーザーが Chat 用アプリを操作する一般的な方法を示します。

  1. ユーザーが Chat 用アプリとのダイレクト メッセージを開くか、既存のスペースに Chat 用アプリを追加します。

  2. Chat 用アプリは、連絡先フォームを card オブジェクトとして作成して表示することで、ユーザーに連絡先の追加を促します。連絡先フォームを表示するために、Chat 用アプリはユーザーに次のように応答します。

    • @メンションとダイレクト メッセージに、お問い合わせフォームを含むカード メッセージで応答します。
    • スラッシュ コマンド /addContact に応答して、お問い合わせフォームを含むダイアログを開きます。
    • スラッシュ コマンド /about に応答して、ユーザーがクリックして連絡フォームのダイアログを開くことができる [連絡先を追加] ボタンを含むテキスト メッセージを返します。
  3. お問い合わせフォームが表示されたら、ユーザーは次のフィールドとウィジェットに連絡先情報を入力します。

    • 姓と名: 文字列を受け入れる textInput ウィジェット。
    • 生年月日: 日付のみを受け入れる dateTimePicker ウィジェット。
    • 連絡先の種類: ユーザーが 1 つの文字列値(Personal または Work)を選択して送信できるラジオボタンの selectionInput ウィジェット。
    • [確認して送信] ボタン: ユーザーが入力した値を送信するためにクリックする button ウィジェットを含む buttonList 配列。
  4. Google Chat アプリは CARD_CLICKED インタラクション イベントを処理して、ユーザーが入力した値を処理し、確認カードに値を表示します。

  5. ユーザーは確認カードを確認し、[送信] ボタンをクリックして連絡先情報を確定します。

  6. Google Chat アプリから、送信を確認する非公開のテキスト メッセージが送信されます。

環境を準備する

このセクションでは、Chat 用アプリの Google Cloud プロジェクトを作成して構成する方法について説明します。

Google Cloud プロジェクトを作成する

Google Cloud コンソール

  1. Google Cloud コンソールで、メニュー > [IAM と管理] > [プロジェクトを作成] に移動します。

    [Create a Project] に移動

  2. [プロジェクト名] フィールドに、プロジェクトのわかりやすい名前を入力します。

    省略可: プロジェクト ID を編集するには、[編集] をクリックします。プロジェクトの作成後にプロジェクト ID を変更することはできないため、プロジェクトのライフタイムを考慮してニーズに合った ID を指定してください。

  3. [ロケーション] フィールドで、[参照] をクリックして、プロジェクトの候補となるロケーションを表示します。[選択] をクリックします。
  4. [作成] をクリックします。Google Cloud コンソールが [ダッシュボード] ページに移動し、数分以内にプロジェクトが作成されます。

gcloud CLI

次のいずれかの開発環境で、Google Cloud CLI(gcloud)にアクセスします。

  • Cloud Shell: gcloud CLI がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。
    Cloud Shell をアクティブにする
  • ローカルシェル: ローカル開発環境を使用するには、gcloud CLI をインストールして初期化します。
    Cloud プロジェクトを作成するには、gcloud projects create コマンドを使用します。
    gcloud projects create PROJECT_ID
    作成するプロジェクトの ID を設定して、PROJECT_ID を置き換えます。

認証と権限付与の設定

Google Chat アプリでは、ユーザーが Google Chat などの Google Workspace アプリケーションでアプリを承認できるように、OAuth 同意画面を構成する必要があります。

このチュートリアルでは、テストと内部使用のみを目的とした Chat 用アプリをデプロイするため、同意画面にプレースホルダ情報を使用しても問題ありません。Chat 用アプリを公開する前に、プレースホルダ情報を実際の情報に置き換えます。

  1. Google Cloud コンソールで、メニュー > > [ブランディング] に移動します。

    [ブランディング] に移動

  2. をすでに構成している場合は、[ブランディング]、[対象ユーザー]、[データアクセス] で次の OAuth 同意画面の設定を構成できます。[ まだ設定されていません] というメッセージが表示された場合は、[使ってみる] をクリックします。

    1. [アプリ情報] の [アプリ名] に「Contact Manager」と入力します。
    2. [ユーザー サポートメール] で、メールアドレスまたは適切な Google グループを選択します。
    3. [次へ] をクリックします。
    4. [対象] で [内部] を選択します。[内部] を選択できない場合は、[外部] を選択します。
    5. [次へ] をクリックします。
    6. [連絡先情報] で、プロジェクトに対する変更の通知を受け取るメールアドレスを入力します。
    7. [次へ] をクリックします。
    8. [完了] で、Google API サービスのユーザーデータに関するポリシーを確認し、同意する場合は [Google API サービス: ユーザーデータに関するポリシーに同意します] を選択します。
    9. [続行] をクリックします。
    10. [作成] をクリックします。
    11. ユーザータイプとして [外部] を選択した場合は、テストユーザーを追加します。
      1. [オーディエンス] をクリックします。
      2. [テストユーザー] で [ユーザーを追加] をクリックします。
      3. メールアドレスと他の承認済みテストユーザーを入力し、[保存] をクリックします。

Chat 用アプリを作成してデプロイする

次のセクションでは、Chat 用アプリに必要なすべてのアプリケーション コードを含む Apps Script プロジェクト全体をコピーして更新するため、各ファイルをコピーして貼り付ける必要はありません。

必要に応じて、GitHub でプロジェクト全体を確認できます。

GitHub で表示

各ファイルの概要は次のとおりです。

main.gs

ユーザーが Chat 用アプリにメッセージを送信したとき、Chat 用アプリのメッセージのボタンをクリックしたとき、ダイアログを開閉したときなどのインタラクション イベントを含む、すべてのアプリロジックを処理します。

main.gs コードを表示する

apps-script/contact-form-app/main.gs
/**
 * Copyright 2024 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Responds to a MESSAGE interaction event in Google Chat.
 *
 * @param {Object} event the MESSAGE interaction event from Chat API.
 * @return {Object} message response that opens a dialog or sends private
 *                          message with text and card.
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1:
        // If the slash command is "/about", responds with a text message and button
        // that opens a dialog.
        return {
          text: "Manage your personal and business contacts 📇. To add a " +
                  "contact, use the slash command `/addContact`.",
          accessoryWidgets: [{
            buttonList: { buttons: [{
              text: "Add Contact",
              onClick: { action: {
                function: "openInitialDialog",
                interaction: "OPEN_DIALOG"
              }}
            }]}
          }]
        }
      case 2:
        // If the slash command is "/addContact", opens a dialog.
        return openInitialDialog();
    }
  }

  // If user sends the Chat app a message without a slash command, the app responds
  // privately with a text and card to add a contact.
  return {
    privateMessageViewer: event.user,
    text: "To add a contact, try `/addContact` or complete the form below:",
    cardsV2: [{
      cardId: "addContactForm",
      card: {
        header: { title: "Add a contact" },
        sections:[{ widgets: CONTACT_FORM_WIDGETS.concat([{
          buttonList: { buttons: [{
            text: "Review and submit",
            onClick: { action: { function : "openConfirmation" }}
          }]}
        }])}]
      }
    }]
  };
}

/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

/**
  * Validates and submits information from a dialog or card message
  * and notifies status.
  *
  * @param {Object} event the interactive event with parameters.
  * @return {Object} a message response that opens a dialog or posts a private
  *                  message.
  */
function submitForm(event) {
  const contactName = event.common.parameters["contactName"];
  // Checks to make sure the user entered a contact name.
  // If no name value detected, returns an error message.
  const errorMessage = "Don't forget to name your new contact!";
  if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  }
  if (!contactName) {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }

  // The Chat app indicates that it received form data from the dialog or card.
  // Sends private text message that confirms submission.
  const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: { actionStatus: {
          statusCode: "OK",
          userFacingMessage: "Success " + contactName
        }}
      }
    };
  }
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

/**
 * Extracts form input value for a given widget.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @param {String} widgetName a unique ID for the widget, specified in the widget's name field.
 * @returns the value inputted by the user, null if no value can be found.
 */
function fetchFormValue(event, widgetName) {
  const formItem = event.common.formInputs[widgetName][""];
  // For widgets that receive StringInputs data, the value input by the user.
  if (formItem.hasOwnProperty("stringInputs")) {
    const stringInput = event.common.formInputs[widgetName][""].stringInputs.value[0];
    if (stringInput != null) {
      return stringInput;
    }
  // For widgets that receive dateInput data, the value input by the user.
  } else if (formItem.hasOwnProperty("dateInput")) {
    const dateInput = event.common.formInputs[widgetName][""].dateInput.msSinceEpoch;
     if (dateInput != null) {
       return dateInput;
     }
  }

  return null;
}

/**
 * Converts date in milliseconds since epoch to user-friendly string.
 *
 * @param {Object} millis the milliseconds since epoch time.
 * @return {string} Display-friend date (English US).
 */
function convertMillisToDateString(millis) {
  const date = new Date(millis);
  const options = { year: 'numeric', month: 'long', day: 'numeric' };
  return date.toLocaleDateString('en-US', options);
}
contactForm.gs

ユーザーからフォームデータを受け取るウィジェットが含まれます。これらのフォーム入力ウィジェットは、メッセージやダイアログに表示されるカードに表示されます。

contactForm.gs コードを表示する

apps-script/contact-form-app/contactForm.gs
/**
 * Copyright 2024 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];
appsscript.json

Chat 用アプリの Apps Script プロジェクトを定義して構成する Apps Script マニフェスト

appsscript.json コードを表示する

apps-script/contact-form-app/appsscript.json
{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "chat": {}
}

Cloud プロジェクトの番号と ID を確認する

  1. Google Cloud コンソールで、Cloud プロジェクトに移動します。

    Google Cloud コンソールに移動

  2. 設定とユーティリティ > [プロジェクトの設定] をクリックします。

  3. [プロジェクト番号] フィールドと [プロジェクト ID] フィールドの値を書き留めます。これらは、以降のセクションで使用します。

Apps Script プロジェクトを作成する

Apps Script プロジェクトを作成して Cloud プロジェクトに接続するには:

  1. 次のボタンをクリックして、Google Chat で連絡先を管理する Apps Script プロジェクトを開きます。
    プロジェクトを開く
  2. [概要] をクリックします。
  3. 概要ページで、コピーを作成するためのアイコン [コピーを作成] をクリックします。
  4. Apps Script プロジェクトのコピーに名前を付けます。

    1. [Copy of Manage contacts in Google Chat] をクリックします。

    2. [プロジェクト タイトル] に「Contact Manager - Google Chat app」と入力します。

    3. [名前を変更] をクリックします。

Apps Script プロジェクトの Cloud プロジェクトを設定する

  1. Apps Script プロジェクトで、プロジェクト設定のアイコン [プロジェクトの設定] をクリックします。
  2. [Google Cloud Platform(GCP)プロジェクト] で、[プロジェクトを変更] をクリックします。
  3. [GCP プロジェクト番号] に、Cloud プロジェクトのプロジェクト番号を貼り付けます。
  4. [プロジェクトを設定] をクリックします。これで、Cloud プロジェクトと Apps Script プロジェクトが接続されました。

Apps Script のデプロイを作成する

すべてのコードが配置されたので、Apps Script プロジェクトをデプロイします。デプロイ ID は、Google Cloud で Chat 用アプリを構成するときに使用します。

  1. Apps Script で、Chat 用アプリのプロジェクトを開きます。

    Apps Script に移動

  2. [Deploy] > [New deployment] をクリックします。

  3. [アドオン] がまだ選択されていない場合は、[種類の選択] の横にあるデプロイタイプ プロジェクト設定のアイコン をクリックして、[アドオン] を選択します。

  4. [説明] に、このバージョンの説明(例: Test of Contact Manager)を入力します。

  5. [デプロイ] をクリックします。Apps Script はデプロイの成功をレポートし、デプロイ ID を提供します。

  6. [コピー] をクリックしてデプロイ ID をコピーし、[完了] をクリックします。

Google Cloud コンソールで Chat 用アプリを構成する

このセクションでは、Google Cloud コンソールで Google Chat API を構成する方法について説明します。この構成には、Chat 用アプリに関する情報(Apps Script プロジェクトから作成したデプロイの ID など)が含まれます。

  1. Google Cloud コンソールで、メニュー > [その他のプロダクト] > [Google Workspace] > [プロダクト ライブラリ] > [Google Chat API] > [管理] > [構成] をクリックします。

    Chat API の構成に移動

  2. [アプリ名] に「Contact Manager」と入力します。

  3. [アバターの URL] に「https://developers.google.com/chat/images/contact-icon.png」と入力します。

  4. [説明] に「Manage your personal and business contacts」と入力します。

  5. [インタラクティブ機能を有効にする] 切り替えボタンをクリックしてオンにします。

  6. [機能] で、[スペースとグループの会話に参加する] を選択します。

  7. [接続設定] で [Apps Script] を選択します。

  8. [デプロイ ID] に、前のセクションで Apps Script デプロイを作成したときにコピーした Apps Script デプロイ ID を貼り付けます。

  9. [コマンド] で、スラッシュ コマンド /about/addContact を設定します。

    1. [スラッシュ コマンドを追加] をクリックして、最初のスラッシュ コマンドを設定します。
    2. [名前] に「About」と入力します。
    3. [コマンド ID] に「1」と入力します。
    4. [説明] に「Learn how to use this Chat app to manage your contacts」と入力します。
    5. [コマンドのタイプ] で、[Slash command] を選択します。
    6. [スラッシュ コマンド名] に「/about」と入力します。
    7. [ダイアログを開く] を選択します。
    8. [完了] をクリックします。
    9. [コマンドを追加] をクリックして、別のスラッシュ コマンドを設定します。
    10. [名前] に「Add a contact」と入力します。
    11. [コマンド ID] に「2」と入力します。
    12. [説明] に「Submit information about a contact」と入力します。
    13. [コマンドのタイプ] で、[Slash command] を選択します。
    14. [スラッシュ コマンド名] に「/addContact」と入力します。
    15. [ダイアログを開く] を選択します。
    16. [完了] をクリックします。
  10. [公開設定] で、[YOUR DOMAIN 内の特定のユーザーおよびグループにこの Chat 用アプリの利用を許可する] チェックボックスをオンにして、メールアドレスを入力します。

  11. [ログ] で、[エラーを Logging にロギング] を選択します。

  12. [保存] をクリックします。構成が保存されたことを示すメッセージが表示されます。

これで、Chat で Chat 用アプリをインストールしてテストする準備が整いました。

Chat アプリをテストする

Chat 用アプリをテストするには、Chat 用アプリとのダイレクト メッセージ スペースを開いてメッセージを送信します。

  1. 信頼できるテスターとして登録した際に指定した Google Workspace アカウントを使用して、Google Chat を開きます。

    Google Chat にアクセスする

  2. [ 新しいチャット] をクリックします。
  3. [ユーザーを 1 人以上追加] フィールドに、Chat 用アプリの名前を入力します。
  4. 結果から Chat 用アプリを選択します。ダイレクト メッセージが開きます。

  1. Chat アプリの新しいダイレクト メッセージに、「/addContact」と入力して Enter キーを押します。

  2. 表示されるダイアログで、連絡先情報を入力します。

    1. [First and last name](姓と名)テキスト フィールドに名前を入力します。
    2. [生年月日] の日付選択ツールで日付を選択します。
    3. [連絡先の種類] で、[仕事] または [個人] ラジオボタンをオンにします。
  3. [確認して送信] をクリックします。

  4. 確認ダイアログで、送信した情報を確認し、[送信] をクリックします。Chat 用アプリは、CONTACT NAME has been added to your contacts. というテキスト メッセージを返します。

  5. 必要に応じて、次の方法で連絡先フォームをテストして送信することもできます。

    • /about スラッシュ コマンドを使用します。チャットアプリは、テキスト メッセージと Add a contact と表示されたアクセサリ ウィジェット ボタンで返信します。ボタンをクリックすると、お問い合わせフォームのダイアログが開きます。
    • スラッシュ コマンド(Hello など)を含まないダイレクト メッセージを Chat 用アプリに送信します。Chat 用アプリは、お問い合わせフォームを含むテキストとカードで返信します。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、Cloud プロジェクトを削除することをおすすめします。

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。メニュー アイコン > [IAM と管理] > [リソースの管理] をクリックします。

    Resource Manager に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。