【GAS×ChatGPT】Slackリマインド文言を毎日変えてお風呂の大切さを伝える

:::note info
私の所属している「どすこい塾」のSlackで、とある人が毎日21時にお風呂リマインドを設定していました。

ただ、毎日同じ文言で同じ時間にリマインドが来てしまうと、飽きが生じてしまいます。

そこでChatGPTのAPIを用いて、毎日違う文言でリマインドするように変更を行なったのでその備忘録です。
:::

![スクリーンショット 2024-06-12 2.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/887fde39-2b8b-ac19-0f79-eed207f25331.png)

![スクリーンショット 2024-06-27 14.52.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/399f31c1-d987-f766-3e8f-958f65a6cb78.png)

# かかる費用について

**ChatGPTのAPIを用いるので少しだけお金が発生します。連続実行にはご注意ください。**

ChatGPTのモデルによりますが、GPT-3.5で**毎日実行すれば、1Bot100円/月かからないくらい**です。

間違えて何度も実行してしまわないように確実に1回しか通らないことをご確認ください。

設定で金額が超えたらAlertが出る設定もあると思うので、使用することをお勧めします。

# そもそもGASとは
そもそもGASを知らない人もいるかと思うのでGASについて説明します。

GASはGoogle App Scriptの略称です。

簡単にいうと、GmailやGoogleスプレットシートやgoogle Slideと連携したりしてGoogle Workspaceを自動化および拡張できます。

詳細は以下にございますので興味ある方は以下をご覧ください。
https://developers.google.com/apps-script?hl=ja

# 今回作るもの
どすこい塾では「お風呂絶対くん」というBotを作成しました。

毎日9時~10時あたりにslack通知が飛んで、
毎回chatGPTを用いてお風呂の大切さを伝えるようになっています。

# Bot作成手順
以下にbotの作成方法を書いたのでそれを参考に作ってみてください！

## 1. 専用のスプシファイルを作成
GASではスプシを擬似DBとして扱うことができます。
今回は使いませんが、今後加えたい時のためにも加えておきます。
スプシを何でもいいので作成してください。

## 2. そのスプシファイルに紐づくGASファイルを作成
スプシの拡張にある、App Scriptsに遷移してそこでGASファイルを変更できます。

![スクリーンショット 2024-04-28 1.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/28f39204-aa65-a7e8-84a9-d90755b20b2d.png)

## 3. GASファイルに以下のコードを記載する
「お風呂入ったか！」の後にスレッドでお風呂の大切さを返します。

```ruby
const SLACK_BOT_TOKEN = 'xoxb-{TOKENを入れてください}';
const SLACK_CHANNEL_ID = '{チャンネルID}';
const CHATGPT_API_KEY = 'sk-{chatGPT Token}';
const NAME_MENSION = '@{メンバーID}'

function process() {
    // Send email subject or first 50 characters of the body to Slack
    const response = sendToSlack('<NAME_MENSION>\nお風呂入ったか!!!!!🚿🛀\n');
    const promptMailToType = 
`# 条件\n- 100文字程度で返答をお願いします。\n- 怒るようにお願いします\n- お風呂入ってない??を始めに入れる\n- 語尾は優しい人のように\n- お風呂に入らないデメリットを入れる`
    // Generate a response using ChatGPT and post it to the same Slack thread
    const chatGptResponse = generateResponseWithChatGPT('```' + promptMailToType + '```');
    sendToSlack(chatGptResponse, response.ts);
  }

function sendToSlack(text, threadTs) {
  const payload = {
    channel: SLACK_CHANNEL_ID,
    text: text,
    thread_ts: threadTs
  };

  const options = {
    method: 'post',
    contentType: 'application/json; charset=utf-8',
    headers: { Authorization: `Bearer ${SLACK_BOT_TOKEN}` },
    payload: JSON.stringify(payload)
  };

  const response = UrlFetchApp.fetch('https://slack.com/api/chat.postMessage', options);
  return JSON.parse(response.getContentText());
}

function generateResponseWithChatGPT(prompt) {
  const data = {
    max_tokens: 150,
    model: 'gpt-3.5-turbo-1106', // TODO ここでモデル変更してください！高い精度&速度出すならgpt4oかな
    messages: [
      { role: 'user', content: prompt }
    ],
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: { Authorization: `Bearer ${CHATGPT_API_KEY}` },
    payload: JSON.stringify(data)
  };

  const response = UrlFetchApp.fetch('https://api.openai.com/v1/chat/completions', options);
  const jsonResponse = JSON.parse(response.getContentText());
  Logger.log(response);
  return jsonResponse.choices[0].message.content.trim();
}

```

## 4. 通知するslackチャンネルのIDを取得
通知するslackメンションIDを取得します。
![スクリーンショット 2024-04-28 19.41.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/bc26ff75-412e-83fd-fa53-bcf227b027e4.png)

取得方法はslackのチャンネルの詳細を開いて一番下までスクロールしたら出てくるのでそれをコピーして、コードの`SLACK_CHANNEL_ID`に指定してください。

## 5. メンションも必要であれば、メンションするメンバーのIDも取得
メンバーのプロフィール詳細に飛んで、そこからメンバーIDをコピーできます。

![スクリーンショット 2024-04-28 19.47.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/6586a87c-998e-6035-370c-cc7cae0bd4b5.png)

## 5. Slack App(bot)を作成する。

こちらのURLから登録してください。
https://api.slack.com/

URLに遷移すると以下のような画面に遷移すると思うので、「Your apps」をクリックします。

![スクリーンショット 2024-06-12 1.46.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/bec10e43-9886-9b48-328e-c21e8d3c023e.png)

遷移するとこのような画面に出ると思うので、「Create New App」をクリックします。

この画面では、「From scratch」を選択します。

![スクリーンショット 2024-06-12 1.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/238d260a-0280-1f4c-23b8-063deca1d455.png)

![スクリーンショット 2024-06-12 1.51.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/0dfb1d20-c145-7daf-a183-b32ef4e804d8.png)

最後にアプリの名前とworkspaceを指定して「Create App」をクリックします。
![スクリーンショット 2024-06-12 1.51.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/57bcae1a-ce66-02c7-17f2-3e5bc6cf9471.png)

これでBotを作成できます。

## 6. Bot(Slack App)に権限を付与する

「0Auth&Permission」に移動してください。そこで下にスクロールすると2枚目のようにScopesが表示されていると思います。
そこで必要になる権限をbotに付与してください。

メッセージを送るためには```chat:write```が必要ですし、チャンネルの情報を読み取って欲しい場合は```channels:read```が必要で、メンバーへのメンションが必要なら、```app_mentions:read```が必要です。

詳しくは調べてみてください。

![スクリーンショット 2024-06-12 2.05.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/0ecc3c2c-a35c-b413-8eef-56c583621835.png)

![スクリーンショット 2024-06-12 2.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/291e57de-d765-59a5-2be3-baee4c8b160d.png)

## 7. Bot(Slack App)の基本情報を設定する
これ忘れがちなんですが、基本情報を設定しないとワークスペースにインストールできないです。

Botの表示名と名前を入力してください。
他の写真などの諸々の設定は、「Basic Information」で設定できます。
![スクリーンショット 2024-06-12 2.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/5a4f8b3b-d7f1-b3a7-1e40-e348e311fd34.png)

## 8. ワークスペースにアプリをインストールする

権限を付与し、基本情報を入力した後で、disableになっていたアプリインストールが可能になります。
「Install to Workspace」を押して該当のチャンネルにインストールしてください。

![スクリーンショット 2024-06-12 2.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/f4ffad8c-4690-241b-63a7-d126f4c5149e.png)

![スクリーンショット 2024-06-12 2.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/c9b19ca3-f1aa-0042-63a5-c17c1216d03c.png)

## 9. slackBotのTokenを取得してコードに設定しておく
これでOAuth&Permissionsに移動すればBot User OAuth Tokenを取得できるのでコードの```SLACK_BOT_TOKEN```に設定してください。

![スクリーンショット 2024-06-12 2.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/b99e6fd6-708b-8ef6-8ed4-975b1a85b0a3.png)

## 8. ChatGPTのAPIを使えるようにする

最後に上で挙げたGASコードにChatGPTのAPIKeyを設定する必要があります。
以下のURLにアクセスしてください。
※アカウントがない場合は作成してください。

https://platform.openai.com/api-keys

右上のCreate New Secret Keyをクリックしてください。

![スクリーンショット 2024-06-27 13.54.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/a297ed53-7143-5de8-778c-0cc8e3bfccad.png)

悪用を防ぐために、Permissionは必要なもののみチェックするようにした方がいいかもしれません。

![スクリーンショット 2024-06-27 13.55.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/7a90d598-dec6-8a31-191b-1fbc75500dfb.png)

**完了したら、API Keyをコピーして{CHATGPT_API_KEY}に貼り付けて完了です。**

モデルは自分で値段と出したい精度と相談して決めてください。コード上で指定できます。
[APIの料金はこちら](https://openai.com/api/pricing/)

※たまに使えないことがあるのですが、数ドルチャージすればそこから使用できるようになると思います。

### API Keyを守るために
**※ここでは簡易的にこのようにしていますが、使われるとお金が発生してしまうKeyになるので、以下のように環境変数として定義しておくことをお勧めします。**

```
// 以下で取得できます
function getKey() {
  PropertiesService.getScriptProperties().getProperty("{KEY名}");
}
```

![スクリーンショット 2024-06-27 14.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/d4fea7b8-1fac-398a-c2f8-13cb08410ee3.png)


## 9. 動くかどうかを実行してテストする
まずは実行してみて出力されるか試してみてください。
slackに通知が来れば成功です。

![スクリーンショット 2024-06-27 14.14.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/fed6f4cd-49f6-9479-1490-e9d4e1cc22f6.png)

## 10.実際にスケジューリングの設定をする
gasでは9時ちょうどに定期実行するというのが面倒です。
実行数を増やして、その中で今の時刻を取得する処理を書いて、該当の時刻だったら通知することなどはできますが、面倒なので今回はピッタシに通知するのはやりません。

GASでは1日の定期実行の時間を1時間の幅で選択することになっているので、9~10時で設定すれば、その間のどこかで通知がきます。
ただし、１度目で9時35分に通知されれば次回以降の定期実行も同じ9時35分に実行されます。

その後にスケジューリング設定をするためにAppsScriptでトリガーを開きます。

![スクリーンショット 2024-06-27 14.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/e3755f38-5501-ec9c-741d-9b55feed2435.png)

画像のように設定して保存すれば9時から10時のどこかで毎日通知されます。

![スクリーンショット 2024-06-27 14.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/fb9d4469-1f09-9024-0a34-44c1f0216dd2.png)

# まとめ
これでどすこい塾の人が1人救われました。
途中で切れてますがこれはプロンプト変えるなどして各自工夫してくださいw

![スクリーンショット 2024-06-27 14.53.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670224/9af968a0-335b-e7bd-b6f1-2c9ba91fff78.png)


APIの料金結構かかるので気をつけてください。
https://openai.com/api/pricing/

# もっと応用
スプシをDBにして、前回の回答内容をもとに回答を得たりすることもできますので興味ある方はお試しください。