fortnitepyでFortniteのBotを作る

# はじめに
<font color=RED>！！！Botを作成してFortniteのアカウントが停止されたりしても責任は負いません！！！</font>
この記事は、fortnitepyを使ってBotを作成するチュートリアルです。
何回かに分けて解説していこうと思っています。
あまり細かくは書かないので、しっかり作りたいなら["fortnitepy docs"](https://fortnitepy.readthedocs.io/en/latest/index.html)を読んでください。

#fortnitepyって？
[Terbau](https://github.com/Terbau)さんが作成したdiscord.pyライクな fortniteと通信ができるライブラリです。

# 環境
* Windows 11
* Python 3.9.5
* pip 21.1.3
* fortnitepy 3.6.2

# 必要なもの
* Python 3.5 ~ 3.9
* fortnitepy
* エディタ
* いらないEpic Games アカウント

#Device Authの取得
## Device Authって？
Device AuthはDiscordのTokenのようなものです。
かなり取得がめんどくさいので、サンプルを用意しました。
以下のコードをauth.pyという名前で保存してください。

```python:auth.py
import requests
import json

def authorization():
    content_type = "application/x-www-form-urlencoded"
    client = "MzQ0NmNkNzI2OTRjNGE0NDg1ZDgxYjc3YWRiYjIxNDE6OTIwOWQ0YTVlMjVhNDU3ZmI5YjA3NDg5ZDMxM2I0MWE="
    #authorization codeでアクセストークンを取得
    code = input(f"https://www.epicgames.com/id/api/redirect?clientId=3446cd72694c4a4485d81b77adbb2141&responseType=code にアクセスして、fnauth/?code= の後の文字列をコピーし、貼り付けてください ")
    authorization_code = requests.post("https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token",
        headers={"Content-Type":content_type,"Authorization":f"basic {client}"},
        data={"grant_type":"authorization_code","code":f"{code}"}
    ).json()
    #device authを作成
    create_device_auth = requests.post(f"https://account-public-service-prod.ol.epicgames.com/account/api/public/account/{authorization_code['account_id']}/deviceAuth",
        headers={"Authorization":f"Bearer {authorization_code['access_token']}"}
    ).json()
    device_auth = {
        "device_id":f"{create_device_auth['deviceId']}","account_id":f"{create_device_auth['accountId']}","secret":f"{create_device_auth['secret']}"
    }
    #save
    with open("device_auths.json","w") as f:
        json.dump(device_auth,f)

if __name__ == "__main__":
    authorization()
```
実行したら、[このサイト ](https://www.epicgames.com/id/api/redirect?clientId=3446cd72694c4a4485d81b77adbb2141&responseType=code)にアクセスして、下の画像の赤枠で囲っている部分をコピーして、コンソールに貼りつけてください。
![image via fortnitepy](https://cdn.discordapp.com/attachments/839542685156769806/866620203458232320/authorization_code.png)
問題なくdevice authが生成されたら、device_auths.jsonというファイルが作成されます。

#Bot本体を作っていく
まず、fortnitepyをインストールします。

```shell:pipインストール済みの場合
pip install fortnitepy
```
```shell:pip未インストールの場合
py -3 -m pip install fortnitepy
```
完了したら、以下のコードをfortnite_bot.pyという名前で保存してください。

2021/9/29  コードに重大なミスがありましたので修正しました。

```python:fortnite_bot.py
#必要なライブラリを読み込む
import fortnitepy
import json
from fortnitepy.ext import commands

with open("device_auths.json","r",encoding="UTF-8") as f:
    device_auth = json.load(f)

bot = commands.Bot(command_prefix='!',auth=fortnitepy.DeviceAuth(device_auth['device_id'],device_auth['account_id'],device_auth['secret'],case_insensitive=True))

#起動時の動作
@bot.event
async def event_ready():
    print(f"アカウント '{bot.user.display_name}' にログインしました")

#フレンドリクエスト時の動作
@bot.event
async def event_friend_request(request):
    await request.accept()

#コマンド
@bot.command(name="hello")
async def hello(ctx):
    await ctx.send(f"こんにちは {ctx.author.display_name} さん。")

bot.run()
```
Botを起動します。

```shell:起動(batにしてもOK)
py -3 fortnite_bot.py
```
起動後、Botに`!hello`と送信すると、
Botが`こんにちは (あなたの名前) さん` と返信してくれます。
![bot_reply](https://cdn.discordapp.com/attachments/866200286363516940/866639309879771136/unknown.png)

#ログを作る
Botに来たメッセージを表示させるために ログを作成します。
`fortnite_bot.py`のどこかに、以下のコードを追加してください。

```python:ログ作成
#パーティーメッセージのログ
@bot.event
async def event_party_message(message):
    print(f"パーティーメッセージ: '{message.author.display_name}'{message.content}")

#ささやきのログ
@bot.event
async def event_friend_message(message):
    print(f"ささやき: '{message.author.display_name}'{message.content}")
```
これでログが出るようになります。

#終わり
私の記事を読んでくださりありがとうございました。
次回はコスチューム変更等を作成しようと考えています。

参考にさせていただいた記事
Pythonで実用Discord bot(discord.py解説) [https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f](https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f)
discord.pyのBot Commands Frameworkを用いたBot開発 [https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f](https://qiita.com/Lazialize/items/81f1430d9cd57fbd82fb)