ChatGPTと一緒にゴミ出しLINE BOTを作ってみた

最近なにかと話題のChatGPTを使って、その日のゴミ出しを教えてくれるLINE BOTをGAS(Google Application Script)で実装してもらいました。
この記事ではChatGPTにどういう指示を出して、アプリケーションを実装したかについて書いています。
LINE Messaging APIとGASを使ってLINE BOTを作成する方法などは割愛するので参考記事をご参照ください。

## 経緯

まず、なぜこのようなことをやってみたかについてですが、理由としては２つあります。
- ゴミ出しの曜日を写真で毎回確認するのがめんどくさかったから
- ChatGPTを使ってアプリケーションを作成できるのか検証したかったから

ユーザーの課題と知的好奇心によって生まれたものです。

## ChatGPTとは

>ChatGPTは、GPT（Generative Pre-training Transformer）という言語モデルのバリエーションであり、対話文脈で人間のようなテキストを生成するように設計されています。
OpenAIによって開発されました。
特定のタスクやデータセットに合わせて微調整することで、人間が対話で返答するかのようにプロンプトに対する応答を生成できます。
ChatGPTは、チャットボットの開発、会話生成、言語翻訳などのタスクに使用できます。
人間の対話データセットを大量に使って学習されており、文章がコヒーレントで文脈に適したものを生成できます。

ちょっと機械っぽさを感じませんか？
実はこの文章もChatGPTに **「ChatGPTとはどういうものか200文字程度で教えて下さい」** と指示した回答になります。
要するにOpenAIというところが開発したAIのチャットボットです。
Wikipediaみたいな使い方からソースコードまで教えてくれるみたいなので、その能力がどれくらいなのかを検証してみます。

https://openai.com/blog/chatgpt/

## 仕様
今回のLINE BOTの仕様としては以下のものとしました。
- 何のゴミの日かを教えてくれる
    - 月曜日と金曜日は可燃ごみ
    - 毎月第1火曜日と第3火曜日はペットボトル
    - 毎月第2火曜日と第4火曜日は不燃ごみ
    - 土曜日は資源ゴミ
    - 水木日はなし
- 毎日6〜7時頃にLINEにて通知
- サーバーレス

## ChatGPTとのやり取り
ゴミ出しの仕様を元にChatGPTにプログラムを実装してもらいました。
最初に以下の指示を出しました。
> LINE Messaging APIを使って以下の要件で実装してください
月曜日と金曜日は可燃ごみ、毎月第1火曜日と第3火曜日はペットボトル、毎月第2火曜日と第4火曜日は不燃ごみ、土曜日は資源ゴミとなるようなスクリプトをGoogle Apps Scriptで実装してください

※ChatGPTの仕様として1回の回答で返ってくる文字数に上限があるようなので途中で途切れてしまいますが、『続きを教えて下さい』と指示することで途切れていたあとの処理を回答してくれました。
最初はコードブロックで見やすかったですが、途中からの処理はただのテキストになって少しわかりづらかったです。
このあたりはChatGPTへの指示の仕方でなんとかなる部分かなと思います。
![スクリーンショット 2022-12-28 16.39.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464231/3b252f2c-ce43-56ef-82b7-bf815d43be23.png)
そして返ってきた回答がこちら↓

```javascript
// LINE Messaging APIを使用するためのアクセストークンやチャンネルIDなどを設定する
var ACCESS_TOKEN = "アクセストークン";
var CHANNEL_ID = "チャンネルID";

// Google Calendar APIを有効化し、必要な権限を付与する
var calendar = CalendarApp.getCalendarById("primary");

// 現在の日付を取得する
var now = new Date();

// 現在の日付から曜日を取得する
var dayOfWeek = now.getDay();

// 出すべきゴミの種類を格納する変数
var trashType;

// 曜日に応じて出すべきゴミの種類を判定する
switch (dayOfWeek) {
    case 1: // 月曜日
    case 5: // 金曜日
        trashType = "可燃ごみ";
        break;
    case 2: // 火曜日
        // 現在の月の月初日からの経過日数を取得する
        var dayOfMonth = now.getDate();
        if (dayOfMonth == 1 || dayOfMonth == 3) {
            trashType = "ペットボトル";
        } else {
            trashType = "不燃ごみ";
        }
        break;
    case 6: // 土曜日
        trashType = "資源ゴミ";
        break;
    default:
        trashType = "不明";
}

// LINE Messaging APIを使用して、出すべきゴミの種類を通知するメッセージを送信する
var message = "今日は" + trashType + "の日です。";

UrlFetchApp.fetch("https://api.line.me/v2/bot/message/push", {
    "headers": {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + ACCESS_TOKEN
    },
    "method": "post",
    "payload": JSON.stringify({
        "to": CHANNEL_ID,
        "messages": [{
            "type": "text",
            "text": message
        }]
    })
});
```
大体できているように思いますが、3点気になった箇所がありました。
- 使っていないGoogle Calendarを呼び出している
- 第1、第3火曜日のところで、週ではなく日数で条件分岐している
- ゴミ出しがない日は「今日は不明の日です」という文になる

1つ目と３つ目はプログラム自体に影響はなさそうですが、２つ目はバグなので指示を変えて再度試してみました。
> LINE Messaging APIを使って以下の要件で実装してください
月曜日と金曜日は可燃ごみ、毎月第1週目の火曜日と第3週目の火曜日はペットボトル、毎月第2週目の火曜日と第4週目の火曜日は不燃ごみ、土曜日は資源ゴミとなるようなスクリプトをGoogle Apps Scriptで実装してください

「第1火曜日」としていたところを「第1週目の火曜日」と意味をはっきりさせて指示しました。
その回答がこちら↓

```javascript
// LINE Messaging APIを使用するためのアクセストークンやチャンネルIDなどを設定する
var ACCESS_TOKEN = "アクセストークン";
var CHANNEL_ID = "チャンネルID";

// Google Calendar APIを有効化し、必要な権限を付与する
var calendar = CalendarApp.getCalendarById("primary");

// 現在の日付を取得する
var now = new Date();

// 現在の日付から曜日を取得する
var dayOfWeek = now.getDay();

// 現在の日付から週番号を取得する
var weekNumber = Math.floor((now.getDate() - 1) / 7) + 1;

// 出すべきゴミの種類を格納する変数
var trashType;

// 曜日と週番号に応じて出すべきゴミの種類を判定する
switch (dayOfWeek) {
    case 1: // 月曜日
    case 5: // 金曜日
        trashType = "可燃ごみ";
        break;
    case 2: // 火曜日
        if (weekNumber == 1 || weekNumber == 3) {
            trashType = "ペットボトル";
        } else {
            trashType = "不燃ごみ";
        }
        break;
    case 6: // 土曜日
        trashType = "資源ゴミ";
        break;
    default:
        trashType = "不明";
}

// LINE Messaging APIを使用して、出すべきゴミの種類を通知するメッセージを送信する
var message = "今日は" + trashType + "の日です。";

UrlFetchApp.fetch("https://api.line.me/v2/bot/message/push", {
    "headers": {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + ACCESS_TOKEN
    },
    "method": "post",
    "payload": JSON.stringify({
        "to": CHANNEL_ID,
        "messages": [{
            "type": "text",
            "text": message
        }]
    })
});
```
以下2点が変更された箇所です。
```javascript
// 現在の日付から週番号を取得する
var weekNumber = Math.floor((now.getDate() - 1) / 7) + 1;
```
```javascript
if (weekNumber == 1 || weekNumber == 3) {
      trashType = "ペットボトル";
} else {
      trashType = "不燃ごみ";
}
```
その日の週番号を取得する処理が足されています。
ChatGPTが実装してくれたコードを少しだけ修正して実際にGASで動かしてみましたが、問題なく動いていそうでした。
細かくデバッグしたわけではないですが、12月でいろいろ試してみまてちゃんとその日のゴミを教えてくれました。
![スクリーンショット 2022-12-28 17.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464231/401d94da-615d-145e-2dd7-cf17997bfa43.png)

## 感想
まず、LINE BOTを実際に動かしてみて毎朝の「今日は何ゴミの日？」と考える手間が省けたのは作ってよかったなと思いました。
ゴミ出しのカレンダーが体に染み付くまではこのLINE BOTにお世話になろうと思います。

また、ChatGPTを使ってみた感想ですが「すげー」「便利！」でした。
このLINE BOTを作成するにあたって僕がコードを書いた時間は、ChatGPTが実装したコードを少し修正するくらいでほとんどありません。
指示を出せばものの数秒で実装してくれたのはシンプルにすごいなと思いました。
指示の仕方１つで回答が変わってくるので、いかにAIが回答しやすい質問をするかという力が求められてくるのだと思います。
どこかでこれからは「ググる」から「GPTる」になると見ましたが、本当にそうなっていくかもしれません。
今後どのスピードでAIが進化していくかわかりませんが、エンジニアとしては仲良くしていければいいなと思います。

## 参考記事
GASとLINE BOTを使うにあたって参考にさせていただきました。

https://qiita.com/kanta_yamaoka/items/dd830cf23ff59353824d