はじめに
最近GASなる存在を知った私、あまりに何でもできることに気が付き、朝起きては夜寝るまで毎日GASのことについて考える 変態 人間になってしまいました。どうも @Keichan_15 と申します。
そういえば最近 ChatGPT API が公開されましたね!
GPT-3.5-turbo
と呼ばれるモデルを新たに採用し、価格は1,000トークン辺り0.002ドルという破格の値段設定。
同様に Whisper と呼ばれる音声合成モデルについてもAPIが提供開始されたようです!(私は Whisper については未キャッチアップ分野…。ちょっと触ってみたさはある)
そこで今回は、このできたてホヤホヤのChatGPT APIを GASから叩いてみようぜ! さらに飽き足らず、そのままSlackBotにしてみようぜ! といった記事になります!
ここ数週間でGASをガンガン触っているものの、JavaScriptを書くこと自体がほとんど初めてであるが故かなり変なコードになっています…。ビシバシコメント欄にてご指導頂けますと幸いです!
完成品
このように、あるチャンネル内で質問したい内容をメッセージで投稿すると、そのメッセージのスレッドにChatGPT_Bot君が答えてくれるよ!といった内容です。
大まかな流れとしては、
- 事前準備(SlackBot用のアプリ作成 & APIキー取得)
- Outgoing Webhookで投稿したメッセージを取得
- GAS側で、2.で取得したメッセージを設定したうえでAPIにリクエスト
- レスポンスの内容から、ChatGPTの返答内容が記載されている部分を抜き出し、Slack App(ライブラリ)でスレッドにBotがメッセージ送信
となります。もう少しシンプルにできる方法ってあるのかな…?
1. 事前準備
1-1. Slackアプリの作成
まずはSlackBotのアプリを作成します! SlackAPIのページ にアクセスし、画面中央に表示されている Create an App
をクリックします!
クリックすると下記の画面が表示されるので、From scratch をクリックします!
次に下記の画面が表示されると思います!
作成するアプリ名を App Name の欄に入力しましょう!(Botの名前になるヨ)
併せて作成したアプリを導入するworkspaceを Pick a workspace to develop your app in: のプルダウンから選択してください!
どちらも入力が完了すれば Create App
のボタンが 緑色 に変わったのを確認し、クリックを押しましょう!
※今回はApp NameをChatGPT_Bot、導入するworkspaceはtestとします。
次に権限周りの設定を行います!
左の一覧の中から、 OAuth & Permissions を探し、クリックしましょう!
Scopes
まで画面をスクロールしてください。今回はBotからメッセージを送りたいので、Bot Token Scopes
を編集していきます。
今回追加するScopeは2つです。Add an OAuth Scope
のボタンをクリックし、下記の2つのScopeを追加しましょう!
- channels:history
- chat:write
追加後、下記のような表示になっていればOKです!
最低限の設定が完了したので、workspaceと接続します。
上にスクロールして頂くと、 OAuth Tokens for Your Workspace の項目があると思います。その画面内にある Install to Workspace
をクリックしてください!
内容を確認し、許可する
をクリックします!
下の写真のように Bot User OAuth Token が発行されていればOKです!
このTokenは後に必要になりますのでメモしておいてくださいね!
1-2. OpenAI のAPIキー取得
OpenAI のAPIキー取得にはchatGPTのアカウントが必要になります。アカウント作成方法は下記の記事をご覧ください。
※今回はアカウントを作成していることを前提で進めていきます。
まずこちらにアクセスします。
写真のような画面に遷移します。Log in
が済んでいなければログインしておきましょう。
ログインすると右上に自身のアカウントが表示されます。クリックすると写真のような一覧が表示されるので、その中の View API keys
をクリックしてください。
以下の写真のような画面が開いたら、 + Create new secret key
をクリックしてください。
APIキーが発行されるので、このAPIキーもメモしておきましょう!
以上で事前準備は完了です!
2. Outgoing Webhookの準備
簡単にOutgoing Webhookについて解説します。Slack APIのドキュメントには以下のように記載されています。
Outgoing Webhooks
Outgoing Webhooks are a legacy method of sending notifications to an app about two specific activities:
1. A message was posted in a particular public Slack channel.
2. A message was posted in any public Slack channel containing specific trigger words.
要するに、特定のキーワードを含めたメッセージが送信された際に、外部サーバーやアプリにその情報を転送することができます。
今回であれば、 最初にユーザーが入力した文章全部をキーワード としてメッセージの情報をGASへ送ってあげる必要があります。
早速設定していきましょう!
まずは1.で作成したSlackアプリを導入したworkspaceを開きます。
workspaceの右横の v
をクリックし、設定と管理 -> アプリを管理する
をクリックしてください。
次に右上のフォームに Outgoing Webhook と入力してください!
Slackに追加
をクリック!
Outgoing Webhook インテグレーションの追加
をクリック!
このような画面が出ればOKです!
こちらのページは後ほど使用しますので、ブックマークに登録するなどして消さないようにしておきましょう!
3. GAS
それでは本題のGASに移っていきましょう!内容が多いため、4章に分けて解説します。
3-1. GASの準備
まずはGASを開きます!
今後スプレッドシートと連携する可能性を考慮し、スプレッドシートの拡張機能タブからGASを開くことをおススメします!
新しいスプレッドシートを開き、拡張機能
のタブから Apps Script をクリックします!
GASが開けばOKです!
3-2. Slack Appライブラリの追加
次にライブラリを追加します。
今回はGASからSlackのチャンネル内にメッセージを送る為に、Slack Appと呼ばれるライブラリを活用します。
左側の ライブラリ
横の +
をクリックし、下記のスクリプトIDを入力して検索します!
1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq
上の写真のように表示されれば 追加
ボタンをクリックしてください!
これでSlack Appライブラリの導入は完了です。
3-3. スクリプトプロパティの設定
次にスクリプトプロパティを設定します。スクリプトプロパティはkeyとvalueの対でデータを保管します。
SlackBotのTokenやAPIキーなどをGASのコードに直接入力するとセキュリティの観点から望ましくないことから、このスクリプトプロパティが用いられます。
左側の歯車(プロジェクトの設定) マークをクリックし、「プロジェクトの設定」画面を開きます。
一番下までスクロールすると、スクリプト プロパティ の項目が表示されるので、スクリプトプロパティを追加
ボタンをクリックします。
このように入力画面に切り替わります。今回は2つスクリプトプロパティを追加します。
- プロパティ: SLACK_BOT_TOKEN 値: 1-1でメモしておいたSlackアプリのToken
- プロパティ: OPEN_AI_KEY 値: 1-2でメモしておいたOpenAIのAPIキー
このように設定できればOKです!
3-4. GASでAPIを叩いてみる
API ReferenceのCurlコマンドでのrequestを参考にコードを作成していきます。
事前にcurlで叩いてみて返答が返ってくるか確認してみると正確だと思います。
早速chatGPT APIをGAS側から叩いて、レスポンスが問題無く返ってくるか確認してみます。
コード.gsを下記のように編集してください。
const prop = PropertiesService.getScriptProperties().getProperties();
function doTest() {
let app = SlackApp.create(prop.SLACK_BOT_TOKEN);
const apiKey = prop.OPEN_AI_KEY;
const url = "https://api.openai.com/v1/chat/completions";
const payload = {
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": "Hello!"}]
};
const options = {
"method": "post",
"contentType": "application/json",
"headers": {
"Authorization": "Bearer " + apiKey
},
"payload": JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(url, options);
const content = JSON.parse(response);
Logger.log(content);
}
処理内容としては doTest()
関数を定義し、「Hello!」とメッセージを送った際のAPIのレスポンスを content
変数に格納しています。その後、Logger.log(content);
で content
の中身をログ出力しています。
コードを書き終えたら、上の 実行
ボタンをクリックしましょう。
初回実行時は下記のようなアラートが出ると思います。 権限を確認
ボタンをクリックします。
自身のアカウントをクリック。
左側の 詳細
をクリックし、(安全ではないページ)に移動
をクリック。
許可
をクリック。
記述に問題が無ければ、下記のようなログが出力されることが確認できると思います。
ここまで完了すればGASでAPIを叩く編は終了です!お疲れ様でした!
ここから先はChatGPTのSlackBot作成に移っていきましょう!!
出力されるログの内、chatGPTが質問内容を受け取って返信している項目は、message
の content
に入っていることが分かります。この content
部分を取り出し、返信時のメッセージとして当ててあげれば、よしなに動いてくれそう…。
ということで、コードを少し弄ります。
const prop = PropertiesService.getScriptProperties().getProperties();
const lock = LockService.getScriptLock();
function doPost(e) {
let app = SlackApp.create(prop.SLACK_BOT_TOKEN);
let message = e.parameter.text;
let userID = e.parameter.user_id;
if (userID === prop.BOT_ID) return;
lock.tryLock(10000);
const apiKey = prop.OPEN_AI_KEY;
const url = "https://api.openai.com/v1/chat/completions";
const payload = {
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": message}]
};
const options = {
"method": "post",
"contentType": "application/json",
"headers": {
"Authorization": "Bearer " + apiKey
},
"payload": JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(url, options);
const content = JSON.parse(response);
// contentオブジェクトにAPIから返された情報が含まれる
const message2 = content.choices[0].message.content;
app.postMessage("your channel_name", message2, {
thread_ts: e.parameter.timestamp
});
lock.releaseLock();
}
BOT_ID
はBOTのユーザーIDを前述のスクリプトプロパティで組み込んでいます。
メンバーID
をコピーして頂き、BOT_ID
というプロパティ名でスクリプトプロパティを設定してください。
確認方法ですが、Slackのworkspaceに導入されたBotをDMから開きます。
この中の メンバーID の部分が BOT_ID
となります!忘れずコピーしてGASに貼り付けましょう!
さらにここで重要なポイントが2つあります!
ポイント①
if (userID === prop.BOT_ID) return;
今回の実装ではOutgoing Webhookのトリガーワードを空白にしているため、送信したメッセージ全てをトリガーとしてGASに送っています。そのため、上記の記述が無いとBotの返信をトリガーで受け取って、更にその返信を受け取って…といった無限ループが発生します。 僕はこれで大多数の方にご迷惑をお掛けすることに…
ポイント②
Slack Appライブラリの postMessage()
を使用してメッセージを送信します。第1引数には送信したいチャンネル名、第2引数には送信したいメッセージを設定します。
app.postMessage("your channel_name", message2, {
thread_ts: e.parameter.timestamp
});
your channel_name
には導入したいSlackのチャンネル名を入力してください。例えばbotというチャンネルに導入したい場合は下記のようになります。
app.postMessage("#bot", message2, {
thread_ts: e.parameter.timestamp
});
ここまで実装完了したらアプリケーションをデプロイします。
画面右上の デプロイ
をクリック → 新しいデプロイ
をクリック → 歯車マークから ウェブアプリ
を選択 → アクセスできるユーザーを 必ず 全員
に変更してデプロイ
デプロイ後、ウェブアプリのURLをコピーしてメモしておきましょう!
4. デプロイURLをOutgoing Webhookに設定
2.で設定したOutgoing Webhookのページに戻ります。
スクロールすると インテグレーションの設定 の項目があると思います。
- チャンネル → メッセージを取得したいチャンネル
- URL → GASのデプロイURL
の2つを選択して 設定を保存
ボタンをクリックします。
これで全ての準備が整いました!
5. アプリをチャンネルに召喚!
Outgoing webhookで設定したチャンネルにアプリを追加します。
Slack上部にあるチャンネル横の V
を選択し、 インテグレーション をクリックします。
アプリを追加する
をクリックし、Bot名を検索して 追加
をクリックします。
あとは好きなように質問すると、Bot君がスレッドに返信してくれます!
以上です!お疲れ様でした~~!
おわりに
GASって本当に便利ですね…。逆に今まで活用しなかったことを悔やむレベルです。笑
また別件にはなるのですが、自動リアクションBot(リアクションするのはBotではなくユーザー自身)もGASで作成できたので近々記事にしていきたいと思います。
ひとまずChatGPT、末恐ろしいAIでした…。
おしまい。