googletransを使ってDiscordで動く翻訳BOTを作ってみた

#まえがき
なんか唐突に英文を翻訳したくなったんですが、PCでchromeをつけてgoogle翻訳ひらいて文字打つのが面倒くさく感じました。
しかしDiscordはなぜか常についているので、じゃあDiscordの翻訳BOTを使おうと思ったんですが、そのままダウンロードするのはなんか違う気がしたので、じゃあ作ろうと思い立ちここに至りました。
人生二作目のBOTです。

#やりたいこと
- 日本語を英語に翻訳してくれる
- 英語を日本語に翻訳してくれる
- 日本語以外の言語を指定なしに日本語に翻訳してくれる
- 言語の指定をすれば任意語から任意語に翻訳してくれる

#できたもの
- `!trans [日本語以外の文字列]`で日本語に翻訳する
- `!trans [日本語の文字列]`で日本語を英語に翻訳する
- `!trans [言語名A]-[言語名B]-[A語の文字列]`でA語をB語に翻訳する
- `!detect [任意の文字列]`でその文字列の言語コードを取得する

#環境
- Windows10
- Discord.py 1.2.3
- Python 3.7.3
- googletrans 2.4.0

#事前準備
- Pythonを使える環境
- Pythonの基礎的な知識
- botの簡単な作り方

>ここがわかりやすいです。
[Pythonで簡単なDiscord Botの作り方](https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f)
[Discord Bot 最速チュートリアル【Python&Heroku&GitHub】](https://qiita.com/1ntegrale9/items/aa4b373e8895273875a8)

#googletransとは
Google翻訳のAPIを利用して翻訳したり言語の検出をしたりできる無料のライブラリです。
しかし安定性があまり良くなく、Googleにいつブロックされてもおかしくないので、安定性が欲しいのであればGoogle Cloudの正式なAPIを使用することをお勧めします。

###インストール
`pip install googletrans`
でインストールできます。

`Successfully installed googletrans-(任意のバージョン)`
が出たら完了です。

###コード例
例として日本語を英語に変換するプログラムを作ってみます。

```python:trans_test.py
from googletrans import Translator

translator = Translator()

japanese = translator.translate('おはようございます。')
print(japanese.text)
#>> Good morning.
```

またtranslete()で返される値はtext以外にも変換元の言語や変換後の言語などがあります。

```python:trans_test.py
from googletrans import Translator

translator = Translator()

japanese = translator.translate('おはようございます。')
print(japanese)
#>> Translated(src=ja, dest=en, text=Good morning., pronunciation=None, extra_data="{'translat...")
```

言語検出をするにはdetect()のカッコの中に検出したい文章や単語を入れます。

```python:trans_test.py
from googletrans import Translator

translator = Translator()

detect = translator.detect('おはようございます。')
print(detect)
#>> Detected(lang=ja, confidence=1.0)
```
langの後の英語二文字で表されてるのが言語名、confidenceは確度を表しています。

なんて便利なライブラリ！！
今回はこのライブラリを使って翻訳BOTを作ります。

#BOTの作成
まずできたものを下に置きます。

```python:main.py
import discord
from googletrans import Translator

TOKEN = 'トークンは伏せます'

client = discord.Client()
translator = Translator()

@client.event
async def on_ready():
    print('--------------')
    print('ログインしました')
    print(client.user.name)
    print(client.user.id)
    print('--------------')

@client.event
async def on_message(message):
    if message.author.bot:
        return

    if message.content.startswith('!trans'):
        say = message.content
        say = say[7:]
        if say.find('-') == -1:
            str = say
            detact = translator.detect(str)
            befor_lang = detact.lang
            if befor_lang == 'ja':
                convert_string = translator.translate(str, src=befor_lang, dest='en')
                embed = discord.Embed(title='変換結果', color=0xff0000)
                embed.add_field(name='Befor', value=str)
                embed.add_field(name='After', value=convert_string.text, inline=False)
                await message.channel.send(embed=embed)
            else:
                convert_string = translator.translate(str, src=befor_lang, dest='ja')
                embed = discord.Embed(title='変換結果', color=0xff0000)
                embed.add_field(name='Befor', value=str)
                embed.add_field(name='After', value=convert_string.text, inline=False)
                await message.channel.send(embed=embed)
        else:
            trans, str = list(say.split('='))
            befor_lang, after_lang = list(trans.split('-'))
            convert_string = translator.translate(str, src=befor_lang, dest=after_lang)
            embed = discord.Embed(title='変換結果', color=0xff0000)
            embed.add_field(name='Befor', value=str)
            embed.add_field(name='After', value=convert_string.text, inline=False)
            await message.channel.send(embed=embed)

    if message.content.startswith('!detect'):
        say = message.content
        s = say[8:]
        detect = translator.detect(s)
        m = 'この文字列の言語はたぶん ' + detect.lang + ' です。'
        await message.channel.send(m)

client.run(TOKEN)
```

複雑に見えるかどうかはわかりませんが、やっていることはとても単純です。

①
`!trans ~`
から始まる命令の時、命令の`!trans`と半角一文字分を命令から取り除く。
↓
detect()でその文章の言語を検出。
↓
その言語が日本語なら英語に、それ以外なら日本語に翻訳する。

②(すでに!trans は取り除かれているとして)
`!trans [A]-[B]-[C]`
の命令の時、Aを変換前の言語名、Bを変換後の言語名、Cを文字列とする。
↓
A、B、CからCをBの言語に翻訳する。

③
`!detect ~`
ではじまる命令の時、命令の`!detect`と半角一文字分を命令から取り除く。
↓
detect()でその文章の言語を検出して出力

全体的な動きは以上です。
いろんなところで`embed~`と書いてあるところがありますが、これはDiscordで発言させるときに埋め込みで発言させるために必要なところです。埋め込みの方が見やすそう。

#結果
翻訳する内容に他意はないです。適当に選んでます。

- 日本語から英語へ
![翻訳１.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/1504de76-38af-6a23-27c2-361fa955616a.png)

- 英語から日本語へ
![翻訳２.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/c9c51fff-e605-0d1a-b5f7-16723c83fe29.png)

- ドイツ語から日本語へ
![翻訳３.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/036a6724-1bf4-7810-b210-82b412cc7f92.png)

- 日本語からドイツ語へ
![翻訳４.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/211d3f58-59f7-848a-ab2f-75a51ebfc8a1.png)

- 言語検出
日本語
![翻訳５.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/ed87bbe2-4e2c-274d-6913-d593b0d436d0.png)


フランス語
![翻訳６.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481328/58b0bf22-2eae-a5a2-a37d-792c34bd3780.png)

やろうとしてたことは全部実装できました！

#おわりに・感想
翻訳の出来はgoogle翻訳には劣ると思いますが、やろうとしてたことはできたので満足です。
まだまだやっていることは初歩なので、これからボイスチャット関係であったり、メンバーの取得、Webスクレイピングと組み合わせたりとやりたいことは山積みです。

みんなもBOTつくるのたのしいからつくろう！！

なにか間違いだったり改善点があれば気軽に[Twitter](https://twitter.com/hasegawa2718)でもなんでも言ってくれればなと思います。