【忘備録】SlackチャンネルにChatGPTを組み込んでみた!【Google Apps Script】

スポンサーリンク
SlackAPI
スポンサーリンク

はじめに

前回の記事でGoogleColab上でChatGPTを動かしてみました。

それなりの応答が返ってくるので、SlackチャンネルにBOTとしていれば面白いのでは?と思ったので組み込んでみました。

なるべく全ての手順を記載しているので、恐らく誰で再現できる。。。はず。

実際の動作

実装

個人的な利用だけなので、SlackAPIとGoogle Apps Script(以後GAS)を使い、サクッと無料で作成しました。

主な手順は以下の4つです。

  1. GASでイベント受信用URLを作成する
  2. SlackBotsを作成する
  3. GASからSlackにメッセージを送信する
  4. 任意のチャンネルにSlackBotsを追加する

GASでイベント受信用URLを作成する

GASにアクセスして、「新しいプロジェクトを作成」もしくは「APPS SCRIPTを作成」をクリックしプロジェクトを作成します。

プロジェクトを作成すると、元々コードがありますが、次のコードで上書きします。(元のコードは消してください。)

function doPost(e) {
  //受信データをパース
  const params = JSON.parse(e.postData.getDataAsString());
  
  //Challenge認証用
  if (params.type === 'url_verification') {
    return ContentService.createTextOutput(params.challenge);
  }

  return;
}

プロジェクトをデプロイしてURLを発行する

以下の手順で、SlackBotsのイベント送信先URLを作成します。

  1. 「デプロイ」をクリックし「新しいデプロイ」を選択する
  2. 「種類の選択(歯車マーク)」をクリックし「ウェブアプリ」を選択する
  3. 「アクセスできるユーザー」を「全員」に設定し、「デプロイ」をクリックする
  4. 「URL」をどこかに残しておく
「デプロイ」をクリックし「新しいデプロイ」を選択する
「種類の選択(歯車マーク)」をクリックし「ウェブアプリ」を選択する
「アクセスできるユーザー」を「全員」に設定し、「デプロイ」をクリックする
「URL」をどこかに残しておく

これでSlackBotsからイベントを受信することができるようになりました。

SlackBotsを作成する

SlackAPIにアクセスし、以下の手順でSlackBotsを作成します。少し手順が長くなったので、ゆっくり進めてください。

  1. 「Create an App」をクリックする
  2. 「From scratch」を選択する
  3. アプリ名とワークスペースを選択して「Create App」をクリックする
  4. サイドバーで「Event Subscriptions」を選択し、「Enable Events」のトグルボタンを「On」にする
  5. 「Request URL」に「GASで作成したURL」を張り付ける
  6. 下にスクロールして「Subscribe to bot events」の折り畳みを開き、「Add Bot User Event」をクリックし「message.channels」を選択する
  7. 「Save Changes」をクリックする
  8. サイドバーから「OAuth & Permissions」を選択する
  9. 下にスクロールして「Bot Token Scopes」の「Add an OAuth Scope」をクリックする
  10. 「chat:write」を選択する
  11. 上にスクロールして「Install to Workspace」をクリックする
  12. 確認画面が出るので「許可する」をクリックする
  13. 「Bot User OAuth Token」をコピーしてどこかに残しておく
「Create an App」をクリックする
「From scratch」を選択する
アプリ名とワークスペースを選択して「Create App」をクリックする
サイドバーで「Event Subscriptions」を選択し、「Enable Events」のトグルボタンを「On」にする
「Request URL」に「GASで作成したURL」を張り付ける
下にスクロールして「Subscribe to bot events」の折り畳みを開き、「Add Bot User Event」をクリックし「message.channels」を選択する
「Save Changes」をクリックする
サイドバーから「OAuth & Permissions」を選択する
下にスクロールして「Bot Token Scopes」の「Add an OAuth Scope」をクリックする
「chat:write」を選択する
上にスクロールして「Install to Workspace」をクリックする
確認画面が出るので「許可する」をクリックする
「Bot User OAuth Token」をコピーしてどこかに残しておく

これでSlackBotsが作成できました。

GASからSlackにメッセージを送信する

前提としてOpenAIのAPIKey取得は行っているものとします。取得していない場合は、前回の記事を参考に取得してください。

SlackAPI向けライブラリの読み込み

最初に作成したGASプロジェクトを開き、以下の手順でライブラリを読み込みます。

  1. 「ライブラリのプラスマーク」をクリックする
  2. 「スクリプトID」に「SlackAppのスクリプトID」をコピペして「検索」をクリックする
  3. 「追加」をクリックする

SlackAppのスクリプトIDは以下です。

1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq
「ライブラリのプラスマーク」をクリックする
「スクリプトID」に「SlackAppのスクリプトID」をコピペして「検索」をクリックする
「追加」をクリックする

スクリプトプロパティの設定

スクリプトプロパティを設定する前に、Slackを開き「App」に追加されているSlackBotsのメンバーIDを取得しておきます。

「App」に追加されているSlackBotsを選択する
「メンバーID」をどこかに残しておく

以下の手順で、スクリプトプロパティを設定します。

  1. 「サイドバーの歯車マーク」をクリックする
  2. 「スクリプトプロパティを追加」をクリックする
  3. 「プロパティ」と「値」をそれぞれ設定する※スクリプトプロパティ割当テーブル参照
  4. 「括弧マーク」をクリックしてエディタ画面に戻る
プロパティ
slackBotTokenSlackBotsを作成したときに取得した「Bot User OAuth Token」
openApiKeyOpenAPIで取得した「APIKey」
slackBotIdSlackBotsの「メンバーID」
スクリプトプロパティ割当テーブル
「サイドバーの歯車マーク」をクリックする
「スクリプトプロパティを追加」をクリックする
「プロパティ」と「値」をそれぞれ設定する
「括弧マーク」をクリックしてエディタ画面に戻る

再デプロイ

まず、次のコードに上書きします。

function doPost(e) {
  //受信データをパース
  const json = JSON.parse(e.postData.getDataAsString());
  
  //Challenge認証用
  if (json.type === 'url_verification') {
    return ContentService.createTextOutput(json.challenge);
  }

  //イベント再送回避
  //キャッシュに積まれていれば処理済
  //未処理の場合はキャッシュに積む(有効期間5m)
  const event_id = json.event_id;
  const cache = CacheService.getScriptCache();
  const isProcessed = cache.get(event_id);
  if (isProcessed) return;
  cache.put(event_id, true, 601);

  //サブタイプが設定されたイベント
  if('subtype' in json.event) return;

  //ChatGPTBotが送信した場合
  //ChatGPTで応答メッセージを作成し、Slackに送信する
  const botId = PropertiesService.getScriptProperties().getProperty('slackBotId');
  if (json.event && json.event.user !== botId) {
    const channel = json.event.channel;
    const text = json.event.text;
    const message = requestChatGPT(text);
    sendSlack(channel, message);
  }

  return;
}

//SlackBotsを通してメッセージを送信する
function sendSlack(channel, message) {
  const slackToken = PropertiesService.getScriptProperties().getProperty('slackBotToken');
  const slackApp = SlackApp.create(slackToken);
  slackApp.postMessage(channel, message);
}

//ChatGPTにテキストを送信し、応答メッセージを取得する
function requestChatGPT(message) {
  const apiKey = PropertiesService.getScriptProperties().getProperty('openApiKey');
  const apiUrl = 'https://api.openai.com/v1/completions';
  
  //リクエストデータの設定
  const headers = {
    'Authorization':'Bearer '+ apiKey,
    'Content-type': 'application/json'
  };
  const options = {
    'headers': headers, 
    'method': 'POST',
    'payload': JSON.stringify({
      'model': 'text-davinci-003',
      'max_tokens' : 256,
      "temperature": 0,
      'prompt': message})
  };

  //リクエストを送信し、結果取得
  const response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());
  const resMessage = response.choices[0].text;
  return resMessage;
}

上記コードについてですが、「text-davinci-003」を「gpt-3.5-turbo-instruct」に置き換える必要があるようです。以下、コメントにて連絡いただきました。

有益な情報ありがとうございます。
text-davinci-003は2024年1月4日より非推奨となったため、gpt-3.5-turbo-instructに置き換えることで返信がこない問題が解決しました。

Cookie-Monster様より

次の手順で再デプロイします。再デプロイの方法を間違えるとSlackBotsを作成するときに設定したURLと別のURLになり、動かなくなるので注意してください。

  1. 「デプロイ」をクリックし「デプロイを管理」を選択する
  2. 「鉛筆マーク」をクリックする
  3. 「バージョンの三角マーク」をクリックし、「新バージョン」を選択する
  4. 「デプロイ」をクリックする
  5. 警告が出るので「アクセスを承認」をクリックする
  6. 「Advanced」をクリックする
  7. 「Go to XXX(unsafe)」をクリックする
  8. 「Allow」をクリックする
「デプロイ」をクリックし「デプロイを管理」を選択する
「鉛筆マーク」をクリックする
「バージョンの三角マーク」をクリックし、「新バージョン」を選択する
「デプロイ」をクリックする
警告が出るので「アクセスを承認」をクリックする
「Advanced」をクリックする
「Go to XXX(unsafe)」をクリックする
「Allow」をクリックする

任意のチャンネルにSlackBotsを追加する

以下の手順で、任意のチャンネルにSlackBotsを追加します。

  1. 「チャンネル名」をクリックする
  2. 「インテグレーション」タブの「アプリを追加する」をクリックする
  3. 作成したアプリの「追加」をクリックする
「チャンネル名」をクリックする
「インテグレーション」タブの「アプリを追加する」をクリックする
作成したアプリの「追加」をクリックする

これで完了です。

動作確認

適当な質問を投げて、ちゃんと応答が返ってきました。めでたしめでたし。

最後に

結構即レスしてくれてうれしい。

SlackAPI自体は1年ぶりくらいに触ったのですが、再送ルールとかイベントの種類とか記憶の片隅にしかなく、結構大変でした。。。

そして、記事にするのも結構時間がかかり。。。翌日の仕事に影響しそうな。

コメント

  1. Cookie-Monster より:

    有益な情報ありがとうございます。
    text-davinci-003は2024年1月4日より非推奨となったため、gpt-3.5-turbo-instructに置き換えることで返信がこない問題が解決しました。

タイトルとURLをコピーしました