ChatGPTの出力結果を保存するブックマーク機能を実装する

# はじめに  
皆さんChatGPTとの会話を楽しんでいますか？
私はGoogle先生あらためChatGPT先生というくらいにChatGPTと遊んでいます。  
ChatGPT先生から素晴らしい回答を頂いて、それを保存する機能があったらいいなと思いました。そう、Google（ブラウザ）にブックマーク機能があるように。  
ChatGPT先生に聞いてみたところ、ブックマーク機能は無いみたいです。  

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/bc5e12db-5788-b0b4-8d53-8ef233ccc758.jpeg width="700">  

  
無いなら作ってしまいましょう！  

# 実装方針
* [PyChatGPT](https://github.com/rawandahmad698/PyChatGPT)（ChatGPTのPythonパッケージ）をベースにする
* 日本語への対応を行う
* ブックマーク保存機能を追加する

## PyChatGPTを使う
[こちらのQiita記事](https://qiita.com/ekusiadadus/items/3304c4832106b244a60f)を参考にPyChatGPTを使えるようにしました。  
どうやらログ機能はあるみたいです。しかしながら下記の2点が問題になります。  
* 日本語には対応していない（ログが文字化けしてしまう）
* すべての結果が1つのログファイルに記載される

## 日本語への対応
[PyChatGPTの元コード](https://github.com/rawandahmad698/PyChatGPT/blob/master/src/pychatgpt/main.py)を見てみたところencodingの問題で日本語に対応していないことがわかりました。
Chatクラスを継承し、ログを保存するsave_dataメソッドをオーバーライドし、encoding="utf-8"に変更することで日本語に対応させます。
また、デストラクタを追加し、終了時にメッセージを表示するようにします。

```python:chatgpt_bookmark.py（前半）
from pychatgpt import Chat, Options
import os
import datetime

class Chat(Chat):
    """
    PyChatGPTパッケージのChatクラスを継承し、以下の機能を加える
    ・ログ保存の日本語への対応（そのままだと文字化けしてしまうため）
    ・終了時に「ブックマークが保存されました」というメッセージを表示する
    """
    def save_data(self):
        """
        ログを保存するsave_dataメソッドをオーバーライドし、encoding="utf-8"に変更することで日本語に対応させる
        """
        if self.options.track:
            try:
                with open(self.options.chat_log, "a", encoding="utf-8") as f:
                    f.write("\n".join(self.__chat_history) + "\n")

                with open(self.options.id_log, "w") as f:
                    f.write(str(self.previous_convo_id) + "\n")
                    f.write(str(self.conversation_id) + "\n")

            except Exception as ex:
                self.log(f"{Fore.RED}>> Failed to save chat and ids to chat log and id_log."
                      f"{ex}")
            finally:
                self.__chat_history = []

    def __del__(self):
        """
        デストラクタに終了時メッセージの表示を追加
        """
        print("ブックマークが保存されました")
```

## ブックマーク名を取得
ブックマーク名を標準入力から取得し、ChatGPTとの会話が終わったあとにブックマークフォルダに保存します。
以上でソースコードが完成です。
```python:chatgpt_bookmark.py（後半）
def chat(log_path):
    """
    ChatGPTを呼び出すメインルーチン
    """
    options = Options()
    options.track = True
    options.chat_log = log_path

    # emailとpasswordはOpenAIに登録したものを入力してください。
    email = "your_mail@gmail.com"
    password = "your_password"
    chat = Chat(email=email, password=password, options=options)
    chat.cli_chat()

def main(dir_path="bookmarks"):
    # ブックマークを保存するディレクトリを作成
    os.makedirs(dir_path, exist_ok=True)

    # ブックマークのファイル名を作成する
    dt_now = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') # 現在の時刻
    name = dt_now + "_" + input("ブックマーク名を入力してください：現在の時刻_ブックマーク名.txt\n") + ".txt" # 現在の時刻_ブックマーク名.txt
    
    # ログの保存先
    log_path = os.path.join(dir_path, name) 

    # ChatGPTのメインルーチンを呼び出す
    chat(log_path=log_path)


if __name__ == "__main__":
    main()
```
:::note warn
emailとpasswordはOpenAIに登録したものを入力してください。
    email = "your_mail@gmail.com"
    password = "your_password"
:::

# 使い方📖
* chatgpt_bookmark.pyを実行するとChatGPTとの対話が始まります。
```
$ python chatgpt_bookmark.py
```
* ブックマーク名を入力します
```
ブックマーク名を入力してください：現在の時刻_ブックマーク名.txt
2023年の目標
```
* ChatGPTとの対話を行い、exitで終了すると対話内容がブックマークフォルダに保存されます。
```
You: 来年の目標は何がいいでしょう？
Chat GPT: 目標は個人によって異なりますが、何か自分にとって有意義なことを達成することがよいでしょう。例えば、健康やフィットネスを向上させること、新しいスキルを習得すること、人との関係を深めること、または新しい冒険を
することなどが考えられます。確かに、来年の目標は自分自身にとって達成しやすいものがよいでしょう。
You: exit
ブックマークが保存されました
```

# ソースコード
ソースコードはGitHubで公開しています。参考になれば嬉しいです。
https://github.com/Isaka-code/chatgpt-bookmark