コマンドを打つとチャンネルを作ってくれるdiscordbotをPythonで作ろう #2

[前回](https://qiita.com/confrict/items/101a0fb273d3f275af53)の続きです。


# メッセージを受けた上でのアクション
次は、Message内での特定のメッセージに反応するプログラムを書いてみましょう。

`!` や `;;` などではじめるbot機能は皆さん使ったことがあると思います。
この文字を Prefix といいます。これについてのコードを書くと長くなるので使わないやり方を説明します。(それを使ったサイトもいつか作ろうと思います。)

```python
@client.event
async def on_ready():
    print(f'Logged in as: {client.user.name}')
    print(f'With ID: {client.user.id}')

# ここに書いていきます

client.run('TOKEN')
```

`on_ready()` と `client.run()`
の間に


```python
@client.event
async def on_message(message:discord.Message):
    if message.content.startswith('.txt'):
        :
        :
```

と書きます。

`on_message(message:discord.Message)` は
![cc032e6bc8516881b4f1d073e3f9870f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581903/4e1e6d52-2386-7a2c-8a6b-795df448056e.png)

ここに書かれたメッセージが送信されたとき、以下のプログラムを実行します。というもので、基本的にここにいろいろ付け足していく感じです。
`if message.content.startswith('.txt'):` は、`.txt` でメッセージが始まっていたら、以下のことをします、という意味です。

逆に、`if message.content.endswith('。'):` は、`。` で終わっていた文章が発せられた場合、以下のことをします、という意味です。

## 受け取ったメッセージで行動を決定する
例えばRythmの時は、 `!p (曲の名前やURL)` や `!loopqueue` というコマンドがありました。
これと同じように、空白を空けた時のメッセージで分解します。

```python
# on_message内
async def on_message(message: discord.Message):
    msg=message.content.split()
    # '.txt (新しいチャンネル名)' で新しいテキストチャンネルを作る
    if message.content.startswith('.txt'):
        # try文でエラーが出る部分を例外処理
        try:
            if len(msg[1]) > 0:
                await message.channel.send(f'{message.author.mention}がテキストチャンネルを作成しました。\n'
                                       f'チャンネル名は、{msg[1]} です。')

        # エラーが出た時の対処
        except:
            await message.channel.send(f':thinking: ,{message.author.mention} チャンネル名を入力してください。')
```





## コードの解説

`msg=message.content.split()` から説明します。
`.split()` はカッコの中身で文を区切るという意味です。ここでは空白なので区切りの文字は使わない、という感じでとらえてください。

`message.content` は、if文解説の時でもやったようにチャンネルに書かれたメッセージの内容です。


この場合、`.txt` で始まったメッセージについて、['.txt', (チャンネル名)] の2つに分けています。`msg=` の下にprint(msg)と入れてみると、写真の例では
`['.txt', 'wow']` となります。

![e21dd577e258d90768c16548ac2cea97.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581903/6ff5ce1a-0ca3-ec26-23d5-8c8de595f9b5.png)

次に、try 文以下の説明です。
try 文は、プログラムを実行したときにエラーが出た場合、その例外が起きた時だけどのような処理をするかを別で書いたものです。
[参考(tryについて)](https://www.sejuku.net/blog/23044)

## チャンネルを作る

チャンネルを作るには、[`discord.Guild`](https://discordpy.readthedocs.io/ja/latest/api.html#discord.Guild)クラスの中の[`create_text_channel()`](https://discordpy.readthedocs.io/ja/latest/api.html#discord.Guild.create_text_channel), [`create_voice_channel()`](https://discordpy.readthedocs.io/ja/latest/api.html#discord.Guild.create_voice_channel) を使います。

チャンネルは基本的にどこかしらのカテゴリに所属しています。

```python
# msg[1] に入っている文字列をチャンネル名にする
await message.guild.create_text_channel(name=msg[1])
```
これを上のtry文の一番下につなげます。

↓

```python
if message.content.startswith('.txt'):
    msg = message.content.split()

    #チャンネルを作る
    try:
        # チャンネル名が存在した時
        len(msg[1]) > 0
        await message.channel.send(f'{message.author.mention}がテキストチャンネルを作成しました。'
                                       f'\nチャンネル名は、{msg[1]} です。')
        # メッセージの発せられたカテゴリに新しいチャンネルを作る
        await message.guild.create_text_channel(name=msg[1])
        # 2021/12/27追記
        # 同じカテゴリに作りたい場合、(name=msg[1], category=message.channel.category)としてください

    except:
        # チャンネル名が入っていない時
        await message.channel.send(f':thinking: ,{message.author.mention} チャンネル名を入力してください。')
```

## 解説

\>> `await message.channel.send(f'{message.author.mention}がテキストチャンネルを作成しました。…` : 

> (成功時)

> (メッセージ送信者)がテキストチャンネルを作りました。
チャンネル名は(チャンネル名)です。

---
> (失敗時)

> :thinking: ,{message.author.mention} チャンネル名を入力してください

---
![e21dd577e258d90768c16548ac2cea97.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581903/6ff5ce1a-0ca3-ec26-23d5-8c8de595f9b5.png)

このようになります。

次はボイチャの作成とカテゴリ作成について書きます。

[次回](https://qiita.com/peco_2282/items/56ec9a81a5e99c7a8959)はこちら