💬

Google Chat を RAG システムの UI として利用する方法 - Apps Script編 -

2024/08/06に公開

1. はじめに

株式会社 Hogetic Lab のエンジニア、古川です。
私は Collectro というデータ収集・分析プラットフォームのプロダクトマネージャ(PdM)として、企画・仕様検討を主に担当しています。

過去 2 つの記事では、RAG システムの検索・問い合わせの UI として Slack と Google Chat を利用する方法について説明しました。

どちらも「連携サーバー」としてバックエンドのサーバーを用意する必要がありましたが、Google Chat では Apps Script を使用すればサーバーを特別に用意しなくてもChat アプリを開発することができます。

今回は Apps Script を利用して、サーバーレスで Google Chat と連携する方法を紹介します。
全体構成図
全体構成図

2. Google Chat アプリの設定方法

前提条件

  • Google Chat が使える Google Workspace のアカウントを持っていること。
  • 同じ Google Workspace のアカウントでログインできる GCP プロジェクトを持っており、API 設定の権限があること。(Google Chat アプリの構成を管理するために必要です。)
  • Apps Script を使用するための権限があること。

権限がない場合は、組織内の管理者にご相談ください。

2.1 Google Cloud の準備 [Google Cloud]

  1. Google Cloud Console で Google Chat API にアクセスし、有効にします。
    Google Chat API の有効化
    Google Chat API の有効化
  2. OAuth 同意画面の設定を行います。(後半の サービスアカウント認証 のために必要な設定です。)
    1. アプリ名:作成するアプリ名を入力します。
    2. ユーザーサポートメール:自分のメールアドレスまたはグループのメールアドレスを入力します。
    3. デベロッパー連絡先情報:自分のメールアドレスを入力します。
    4. ユーザーの種類:内部で設定します。

2.2 Google Chat アプリの準備 [Apps Script]

  1. Apps Script の はじめに にある チャットアプリ を選択します。
    Apps Script - テンプレート一覧画面
    Apps Script チャットアプリのテンプレートを選択
  2. テンプレートとして、オウム返しをする簡単なスクリプトが表示されます。まずはこのスクリプトに名前を付けてそのまま使用します。
  3. 左の歯車アイコン プロジェクトの設定 を選択し、右側の Google Cloud Platform(GCP)プロジェクトで、Apps Script を動作させる GCP プロジェクトの番号を設定します。(GCP プロジェクト名や ID とは異なります。注意書きのリンク先で確認できます。)
    プロジェクトの設定
    Apps Script - プロジェクトの設定
  4. 右上のデプロイからデプロイをテストを選択し、ヘッドデプロイ IDの値をコピーします。(この値は次の手順で使用します。)

2.3 Google Chat API の設定 [Google Cloud]

Google Cloud に戻って、Google Chat API の設定を行います。

  1. 構成をクリックし、以下を設定します。(後から変更可能です。)
    1. アプリケーション情報アプリ名 に任意のアプリ名を入力、説明に機能や使い方を記載します。アバターのURL にアプリのアイコン画像(PNG)の URL を入力します。
      構成 - アプリケーション情報
      Google Chat API の構成 - アプリケーション情報
    2. インタラクティブ機能:インタラクティブ機能を有効にし、アプリの使い方に合わせて以下を設定します。
      • スペースとグループの会話に参加する:スペースでの会話でアプリを使用する場合はチェックを入れます。
      • 1:1 のメッセージを受信する:ダイレクトメッセージ(DM)での会話でアプリを使用する場合はチェックを入れます。
        構成 - インタラクティブ機能
        Google Chat API の構成 - インタラクティブ機能 ( Apps Script プロジェクト)
    3. 接続設定Apps Script プロジェクト を選択し、前の手順で取得したヘッドデプロイIDを入力します。
    4. 公開設定:特定のユーザーとグループが使用できるように設定を有効にし、ユーザーおよびグループのメールアドレスを入力します。
    5. ログ:エラーを記録するように設定します。
  2. 「保存」をクリックして設定を保存します。

2.4 Google Chat アプリをスペースに追加 [Google Chat]

  1. Google Chat でアプリを追加したいスペースを開きます。
  2. スペースの設定から「アプリと統合」をクリックします。
    アプリの追加
    Google Chat アプリの追加
  3. 右上の「+アプリを追加」をクリックし、Google Chat API の構成で設定したアプリを追加します。
  4. アプリをメンションして話しかけるとイベントが発生し、設定した Apps Script で処理が実行されます。
    実行結果
    Google Chat アプリからの返信(オウム返し)

2.5 Google Chat アプリの開発 [Apps Script]

テンプレートのコードでオウム返しができることが確認できたら、Google Chat の API を使った処理を追加します。
Google Chat の API の実行の認可を得るには ユーザー認証サービスアカウント認証 の二つがあり、API によってはどちらかの認証方法でしか使用できません。
詳細は公式サイト Chat アプリと Google Chat API リクエストの認証と認可 を参照してください。

ここでは簡単な例として、ユーザーからの問い合わせに対してスレッド内に回答する方法を紹介します。

2.5.1 認証用サービスアカウントの秘密鍵の作成

  1. 公式ドキュメントの手順 に従って、認証に必要なサービスアカウントを作成します。
  2. 手順に従い作成した秘密鍵のファイルをダウンロードします。このファイルの中身は次の手順で使用します。

2.5.1 OAuth2 for Apps Script ライブラリの追加

サービスアカウント認証を使って Google API を利用するために OAuth2 for Apps Script を使用します。

  1. スクリプトエディタの左の リソースライブラリ の右の + をクリックします。
  2. スクリプト ID: 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF で検索します。
  3. 検索結果の OAuth2 を追加します。

OAuth2 ライブラリの追加
OAuth2 ライブラリの追加

2.5.2 サービスアカウントの秘密鍵をスクリプトプロパティに保存

  1. スクリプトエディタの左の プロジェクトの設定 を選択し、右画面下の スクリプト プロパティスクリプト プロパティの追加 をクリックします。
  2. プロパティ名に JSON_SECRET_KEY と入力し、値にサービスアカウントの秘密鍵ファイルの内容を貼り付けて保存します。

2.5.3 スクリプトの追加

スクリプトエディタでコードを追加します。

  1. 認証用のトークンを取得するための関数を追加します。
/**
 * サービスアカウント認証のアクセストークン取得のサービス作成
 */

function createChatService(key = 'JSON_SECRET_KEY') {
  const jsonSecretKey = getJsonSecretKey(key);
  const service = OAuth2.createService('chat')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')
      .setPrivateKey(jsonSecretKey.private_key)
      .setClientId(jsonSecretKey.client_email)
      .setPropertyStore(PropertiesService.getUserProperties())
      .setScope('https://www.googleapis.com/auth/chat.bot');
  if (!service.hasAccess()) throw 'Authentication error: %s', service.getLastError();
  return service;
}

function getJsonSecretKey(key = 'JSON_SECRET_KEY') {
  const file = PropertiesService.getScriptProperties().getProperty(key);
  if (!file) throw `スクリプトプロパティにキー「${key}」で、JSON形式の秘密鍵を追加してください。`;
  return JSON.parse(file);
}
  1. スレッド内に回答する関数を追加します。
/**
 * スレッド内に返信する
 */
function replyInThread(answer, spaceId, threadId){
  /**
   * https://developers.google.com/chat/api/reference/rest/v1/spaces.messages/create
   */
  const apiBase = 'https://chat.googleapis.com/v1/'+spaceId+'/messages';
  var requestUrl= apiBase + '?messageReplyOption=REPLY_MESSAGE_OR_FAIL'

  // サービスアカウント認証
  const service = createChatService();
  var headers = {
    'Authorization': 'Bearer ' + service.getAccessToken()
  }

 // 返信先のスレッドと返信内容を設定
  var payload = {
    'text': answer,
    'thread': {'name': threadId},
    'sender': {'type': 'BOT'}
  };

  var options = {
    'method':'post',
    'contentType' : 'application/json; charset=utf-8',
    'headers':headers,
    'payload':JSON.stringify(payload) 
  }
  var res = UrlFetchApp.fetch(requestUrl,options);

  res = JSON.parse(res.getContentText());
  return res
}
  1. イベントを受信したときに処理を実行する関数を以下のように変更します。
function onMessage(event) {
  var answer = event.message.text;
  if (event.space.type == "DM") {
    return { "text": answer };
  } else {

    var spaceId = event.space.name; // スペースIDの取得
    var threadId = event.message.thread.name; // スレッドIDの取得

    replyInThread(answer,spaceId,threadId);        
  }
}
  1. アプリに問いかけるとスレッド内に返信されることを確認します。
    実行結果
    Google Chat アプリからの返信(スレッド内にオウム返し)
    なお、初回は以下のような表示が出ます。「設定」を押すと、OAuth同意画面が表示され、同意することでチャットできるようになります。
    初回の設定リクエスト
    Google Chat アプリ 初回の設定リクエスト

2.6 本番デプロイ [Apps Script]

デプロイをテスト の状態では、他のユーザーが利用できません。他のユーザーでも利用できるようにするためにのデプロイを行います。

  1. 右上の デプロイ から 新しいデプロイ を選択します。
  2. デプロイしたコードの内容がわかる説明文を入力します。
  3. デプロイが完了するとデプロイ ID が表示されます。この ID を Google Chat API の設定で指定します。
    デプロイ画面
    Apps Script - デプロイ画面

3. 注意・考慮すべきポイント

Google Chat アプリとしての注意点や考慮すべきポイントとして、Apps Script 固有ものは以下の通りです。

  • ヘッドデプロイ ID は自分でのテストでしか使用できません。作成したアプリを他のユーザーでも使用できるようにする場合は、新しいデプロイ でデプロイした ID が必要になります。

前回、ご紹介した内容は Apps Script か否かにかかわらず有効であるため、こちらも併せて参照してください。

4. まとめ

今回は、Google Chat を RAG システムの検索・問い合わせの UI として利用するための方法について、App Script を使用する場合を紹介しました。Google Cloud、Apps Script、Google Chat の 3 箇所を行き来して設定する必要があるので多少煩雑ですが、連携サーバーを立ち上げる必要がない点は魅力的です。ぜひ一度お試しください。

引き続き、他のチャットツールの使い方についても記事にしていきたいと考えています。お楽しみに。

※ データ分析や AI 活用に関するご相談は、以下よりお気軽にお問い合わせください。
お問い合わせフォーム

参考リンク

今回の記事を作成するにあたり、以下のサイトを参考にさせていただきました。より詳細な説明もありますので、詳しく知りたい方は参照してください。

おまけ

Gemini を使うためのコードを紹介します。(Gemini の API キー取得方法等は記載しません。)

/**
 * LLM として Gemini を使用する 
 */
function askGemini(question) {
  // Gemini APIのエンドポイント
  const API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent'; 

  // リクエストのペイロード
  const payload = {
    contents: [{
      parts: [{
        text: question
      }]
    }]
  };
  
  // リクエストオプション
  const options = {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
      'x-goog-api-key': getGeminiApiKey()
    },
    payload: JSON.stringify(payload)
  };
  
  try {
    // APIリクエストを送信
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseData = JSON.parse(response.getContentText());
    
    // レスポンスから回答テキストを抽出
    const answer = responseData.candidates[0].content.parts[0].text;
    
    return answer;
  } catch (error) {
    console.error('Error calling Gemini API:', error);
    return 'エラーが発生しました。もう一度お試しください。';
  }
}

function getGeminiApiKey(key = 'GEMINI_KEY'){
  const apiKey = PropertiesService.getScriptProperties().getProperty(key);
  if (!apiKey) throw `スクリプトプロパティにキー「${key}」で、GeminiのAPIキーを追加してください。`;
  return apiKey;
}

あとは、onMessage 関数の中を以下のように変更します。

  // var answer = event.message.text;
  var answer = askGemini(event.message.text);

これだけで、今まではオウムだった Google Chat アプリが、急に人間らしい回答をするようになります。

Gemini が回答

同様に ChatGPT や他の LLM を使うことも可能です。お役に立ちましたら幸いです。

Hogetic Lab

Discussion