slack botとVOICEVOXを組み合わせて聞くことができるチャットボット

## はじめに
最近の自分の生活においてチャットGPTなど生成系AIを用いて適当に会話を行う機会が多くなってきた。
しかし会話をしている気があまりしないと思うようになりなぜかと考えると文字を打って帰ってきた返答を見るだけなので会話している感が薄いのではないだろうかと思った。
そこでAPIを用いて生成系AIに音声機能を追加すれば良いのではないだろうかと思い作成した。
## 使用するAPI
VOICEVOX　API:
出力された文章を読み上げるために使用

Llama2:
文字を出力させるための大規模言語モデル

```
USER--first-bolt-app--main.py

                    --modules
                       |
                       --Llama.py
                       --voice.py
```

## プログラム一覧
main.py
```python
import os
from dotenv import load_dotenv
from typing import Final
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from modules.Llama import Llama_chat
from modules.voice import post_audio_query, post_synthesis, play_wavfile

# 読み込み
load_dotenv()
slack_app_token = os.environ['SLACK_APP_TOKEN']
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))

# ボイスID選択
speaker = 3

# 出力用意
@app.message("")
def chat(message: dict, say):
    # Use Llama_chat to get the response text
    output: Final[str] = Llama_chat(message['text'])
    print(output)

    # Use voice.py to convert the response text to voice
    query_data = post_audio_query(output)
    wav_data = post_synthesis(query_data)

    # Play the synthesized voice
    play_wavfile(wav_data)

    # Send the original text response to Slack
    say(output)

# main
if __name__ == "__main__":
    SocketModeHandler(app, slack_app_token).start()
```
Llama.py
```python
import replicate

# 返答
def Llama_chat(message : str):
    output = replicate.run(
        "<Llamaモデルのバージョン>",
        input={"prompt": message}
    )
    res = ""
    for item in output:
        res += item
    return str(res)

# main
if __name__ == "__main__":
    res =Llama_chat("Hello, I'm Llama. I'm a bot.")
    print(res)
```
voice.py
```python
import requests
import json
import sounddevice as sd
import numpy as np
from rich import print

host = "127.0.0.1"
port = "50021"
speaker = 3

def post_audio_query(text: str) -> dict:
    params = {"text":text,"speaker":speaker}
    res = requests.post(
        f"http://{host}:{port}/audio_query",
        params=params,
    )
    query_data = res.json()
    return query_data

def post_synthesis(query_data:dict)->bytes:
    params = {"speaker":speaker}
    headers = {"content-type":"application/json"}
    res = requests.post(
        f"http://{host}:{port}/synthesis",
        data = json.dumps(query_data),
        params=params,
        headers=headers,
    )
    return res.content

def play_wavfile(wav_data:bytes):
    sample_rate = 24000
    wav_array = np.frombuffer(wav_data,dtype=np.int16)
    sd.play(wav_array,sample_rate,blocking=True)

def text_to_voice():
    while True:
        text = input("テキストを入力してください：")
        if text == "q":
            exit()
        res = post_audio_query(text)
        wav = post_synthesis(res)
        play_wavfile(wav)

def get_speakers():
    res = requests.get(f"http://{host}:{port}/speakers")
    print(res.json())

if __name__ == "__main__":
    text_to_voice()
```

## 結果
私：「おはよう」

bot:「Ohayou gozaimasu! Ogenki desu ka? (Good morning! How are you?)
I'm here to help you with any questions or tasks you may have. Is there anything specific you need assistance with today?」

私：「日本語でおはようって言ってみて」

bot：「Ohayou gozaimasu! Ogenki desu ka? (おはようごます！お元気ですか？)
* Ohayou gozaimasu (おはようごます) - Good morning
* Ogenki desu ka (お元気ですか) - How are you?
I'm here to help you with any questions or tasks you may have. Is there anything specific you would like me to assist you with today?」
## まとめ
今回実行してみると日本語で話しても英語になってしまい、日本語で喋るようお願いしても英語になってしまい"おはようごます"と日本語が怪しい部分がある。対策として後日日本語で喋るように対策したいと思う。対策内容として英語だとしっかり返答することができるため翻訳機能があるAPIを用いてみようと思う。