alt

Discord Botを作ろう① オウム返しBot

今日の目標!

Discord Botってなんだ?

Discordのサーバーに、名前の横に「アプリ」と書かれたユーザーがいるのを見たことある?

決まった時間にお知らせを送ってくれたり、音楽を流してくれたり、ゲームの戦績を教えてくれたりする、あいつらが Discord Bot(ディスコード・ボット)

discord bot

Botも見た目は普通のDiscordユーザーみたいだけど、中では人間のかわりにプログラムが動いている。

今回はPythonを使って、送られてきたメッセージをそのまま返す オウム返しBot を作ってみよう!

自分:こんにちは
Bot:こんにちは

「なにそれwwwつまんなwww」と思うかもしれないけど、まずはこれが超大事。

Botがメッセージを受け取って、Pythonで処理して、Discordに返す。この流れができれば、返す文章を変えたり、特定の言葉にだけ反応させたりして、いろんなBotに発展させることができる。今回はそのはじめの一歩

Botの中で起きていること

まずは、メッセージがどんなふうに移動しているのか見てみよう。

Discord Botのメッセージの流れ

今回のプログラムでは、③で取り出した文章をそのまま⑤で送り返す。

だから「オウム返し」になるわけだね。

APIとは

今回、Pythonが勝手にDiscordの中をのぞいたり、直接Discordの画面をクリックしたりするわけではない。これができちゃうと、discordをハッキング仕放題で、とんでもないことになっちゃうからね

Discordは、外部のプログラムに対して「この情報・この機能なら自由に使っていいよ!」という窓口を用意している。このような窓口や、やり取りのルールを API(エーピーアイ) というよ。
※API:Application Programming Interfaceの略

たとえばレストランで考えると、こんな感じ。

今回は discord.py というライブラリが、pythonが「こういう返信を返して!」というお願いをdiscordに伝えているわけ。それに対してdiscord君が「しゃーねーな」といって返信を返してくれる。

準備しよう

VSコードを開いて、discord_botディレクトリを作ろう

ディレクトリの中は、こんな感じ。

discord_bot
├── bot.py
├── .env
└── .gitignore

ライブラリのインストール

VSCodeでターミナルを開いて、次のコマンドを実行しよう。

pip install discord.py python-dotenv

エラーが出ずにインストールが終わればOK!

Bot Tokenは「Botのパスワード」

BotがDiscordへログインするときには、Bot Token(ボット・トークン) という秘密の文字列を使う。

これはBot専用のパスワードみたいなもの。

Tokenを知っている人は、そのBotを勝手に動かせる可能性がある。だから、次のことは絶対にしないようにしよう。

Tokenは先生の指示にしたがって、.env ファイルへ書こう。

DISCORD_BOT_TOKEN=ここに先生から指定されたToken

.env の中身は、授業中もほかの人に見せないように!

.gitignoreには、次の1行が入っていることも確認しよう。

.env

これは「.envをGitの記録に入れないでね」という設定だよ。

まずは完成コードを動かそう

bot.pyを開いて、次のコードを入力しよう。

今回はDiscordとの接続部分が多いので、コピペでOK。

import os

import discord
from dotenv import load_dotenv


# .envファイルを読み込む
load_dotenv()
token = os.getenv("DISCORD_BOT_TOKEN")

# Botが受け取りたいDiscordの情報を設定
intents = discord.Intents.default()
intents.message_content = True

# Discordに接続するBotを作る
client = discord.Client(
    intents=intents,
    allowed_mentions=discord.AllowedMentions.none()
)


# Botのログインが完了したときに実行
@client.event
async def on_ready():
    print(f"{client.user} でログインしました!")


# Discordにメッセージが投稿されたときに実行
@client.event
async def on_message(message):
    # Botが送ったメッセージには反応しない
    if message.author.bot:
        return

    # Discordに投稿された文章を取り出す
    text = message.content

    # 同じ文章をDiscordへ送り返す
    await message.channel.send(text)


# Tokenを使ってBotを起動
client.run(token)

Botを起動しよう

ターミナルで次のコマンドを実行しよう。

python bot.py

ターミナルに、

○○Bot でログインしました!

と表示されたらログイン成功!

教室のDiscordサーバーにある、指定されたBot練習用チャンネルを開こう。

こんにちは

と送って、Botも「こんにちは」と返してきたらオウム返しBotの完成!

コードとデータの流れを確認しよう

今回、特に注目するのは on_message の中。ここ以外の部分は今回は無視してOK。

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

    text = message.content
    await message.channel.send(text)

①メッセージが届く

async def on_message(message):

Discordにメッセージが投稿されると、on_message が実行される。

届いたメッセージの情報は、messageという変数に入るよ。

messageの中には、文章以外にもいろんな情報が入っている。

書き方 入っている情報
message.content 投稿された文章
message.author 投稿した人
message.channel 投稿されたチャンネル

②Botのメッセージを止める

if message.author.bot:
    return

これは、

もし、メッセージを送ったのがBotなら
    ここで処理を終了する

という意味。

この処理がないと、Botのメッセージに別のBotが返事をして、その返事にまたBotが返事をして……と、Bot同士のおしゃべりが止まらなくなる可能性がある。

ヤバそうだよね。

urusee

③文章を取り出す

text = message.content

Discordに投稿された文章を取り出して、textという変数に入れている。

Discordへの投稿:おはよう

message.content:おはよう

text:おはよう

④文章を送り返す

await message.channel.send(text)

textに入っている文章を、メッセージが投稿されたチャンネルへ送っている。

つまり、

受け取った文章 → text → 送り返す文章

となっているから、同じ文章が返ってくるわけだ!

オウム返しを改造しよう

ここからが今日の本番。

次の1行を改造して、Botの返事を変えてみよう。

await message.channel.send(text)

コードを書き換えたら、一度Botを止めてから再起動するよ。

ターミナルで Ctrl + C を押すとBotを止められる。

コードを書き換える
        ↓
Ctrl + CでBotを止める
        ↓
もう一度 python bot.py
        ↓
Discordで試す

改造①:文章を付け足す

reply = text + "!!!"
await message.channel.send(reply)
自分:こんにちは
Bot:こんにちは!!!

textに文字列を足してから、replyに入れている。

replyは「返事」という意味だよ。

改造②:語尾を変える

reply = text.replace("です", "だニャ")
await message.channel.send(reply)
自分:今日は元気です
Bot:今日は元気だニャ

.replace()を使うと、文字列の一部を別の文字列に置き換えられる。

このBot、文章によっては日本語がちょっとおかしくなるけど、それも含めて試してみよう。

改造③:特定の言葉に反応する

if文などをつかっていろいろ工夫してみよう

if "リッキー" in text:
    reply = "リッキーがカッコイイのはわかりみが深い"
else:
    reply = "ふーん(無関心)"

await message.channel.send(reply)
自分:リッキーってかっこいいよね
Bot:ッキーがカッコイイのはわかりみが深い

自分:今日はカレーです
Bot:ふーん(無関心)

文字列操作・改造アイデア一覧

細かい書き方を全部覚えなくてOK!

やってみたいものを一覧から選んで、replyを作るところに使ってみよう。

やりたいこと 書き方 入力例 結果例
後ろに付ける text + "!!!" やった やった!!!
前に付ける "Bot:" + text こんにちは Bot:こんにちは
大文字にする text.upper() hello HELLO
小文字にする text.lower() HELLO hello
逆から並べる text[::-1] こんにちは はちにんこ
置き換える text.replace("です", "だニャ") 元気です 元気だニャ
文字数を数える len(text) こんにちは 5
最初の3文字 text[:3] プログラミング プログ
最後の3文字 text[-3:] プログラミング ミング
2回くり返す text * 2 わーい! わーい!わーい!
含まれるか調べる "宿題" in text 宿題忘れた True
空白で分ける text.split() 赤 青 黄 ["赤", "青", "黄"]

文字数を文章として返す場合

len(text)の結果は数字なので、文章の中に入れるには f-stringを使うと便利。

reply = f"そのメッセージは{len(text)}文字です!"
await message.channel.send(reply)
自分:こんにちは
Bot:そのメッセージは5文字です!

自由改造タイム!

ここからは、自分だけのオウム返しBotに改造してみよう。

まずは、次の中から1つ選んで作ってみてね。

ミッションA:キャラクターBot

どんな文章にも、決まったキャラクターっぽく返事をするBot。

例:

自分:今日は晴れです
Bot:今日は晴れだニャ🐈
自分:おなかすいた
Bot:おなかすいたでござる⚔️

ミッションB:悲報Bot

どんな文章も悲報にするBot。

例:

自分:消しゴムを忘れた
Bot:【悲報】消しゴムを忘れた!!!!!!

ミッションC:逆さまBot

送った文章を逆から返すBot。

例:

自分:カレーライス
Bot:スイラーレカ

ミッションD:特定ワード反応Bot

特定の言葉が入っていたときだけ、特別な返事をするBot。

例:

自分:今日の給食はカレーです
Bot:カレー!?大盛りでお願いします!!

ミッションE:好きにふざける

一覧にある文字列操作を組み合わせて、リッキーが思いつかないような返事を作ろう。

ただし、ほかの人が嫌な気持ちになる言葉や、個人情報を使うのはナシ!みんなが笑える範囲でふざけよう。

今日のまとめ

今日のチャレンジ

自分のBotについて、次の3つを説明してみよう。

  1. どんなメッセージを送ると反応する?
  2. Pythonで文字列をどのように変えている?
  3. どこを変えたら、別のキャラクターBotになる?

次回は、メッセージの最初に書かれた命令を読み取って、

!reverse こんにちは
!count こんにちは
!title リッキー

のように、1つのBotへいろんな機能を追加していくよ!


家でもう一度Botを作りたい人へ

自分のDiscordサーバーに、自分専用のBotを最初から用意したい人は、次のマニュアルを見ながら設定しよう。

▶ Discord Botを自分で準備するマニュアル(画面見本つき)

Bot Tokenはパスワードと同じ。作業するときは、おうちの人にも声をかけてね。