Discord.pyの備忘録(1.3.2対応版)

ドラビレの攻略ブログと化しそうなので、ここら辺で別の話題でも。

Discordでドラビレサーバーを立てて、Botが作れる事を教えてもらい
触ったことの無いPythonで勉強がてらBotを作成してます。

なんでPythonを選んだかって?ヘビが可愛いからでs

様々な機能を実装するために、見慣れぬリファレンスを読んだり
Bot開発してる方のブログを見たり・・・

あった!と思ったら古い情報で使えなかったりするので
現行バージョン(1.3.2)で動作しているうちの子のコードを
いくつか小分けに紹介しておきます。

・Pythonの開発環境が揃っている。
・Discord上でテストレベルのBotが動かせる状態にある。
(token取得済み、Discord.pyがインストール済み等)
が前提となります。

独学の趣味レベルなのでコードの汚さはご容赦下さい・・・!

基本

Discord.pyを導入して、Botに働いてもらうにあたって
Discord側で特定のアクションが起こったら走るプログラムを記述します。

自分が使ってるイベントを下に記載しておきます。
リアクションを受けたら動くイベントは最近導入したけど汎用性が高そう。
ただ情報が少ない・・・

#Discord.pyのライブラリを読み込む。必須。
import discord

#Bot自身のデータをclientに格納する。
#必須では無いが後々使えるので入れておくが吉。
client = discord.Client()

@client.event
async def on_ready():
	#Botが起動した際に1回だけ走る。
	#起動時のメッセージ等表示させたい場合はココに仕込む

@client.event
async def on_reaction_add(reaction, user):
	#自分の送信したメッセージに対してリアクションが付く度に走る。
	#新規ユーザーに対して、サーバー規約の同意を求めるためにリアクションを使用する際に使える。
	#Botとの意思疎通(YES,NOクエスチョン)などでリアクションを使用するのにも使える。

@client.event
async def on_message(message):
	#誰かがメッセージを発言する度に走る。これが無いとBotが始まらない。
	#特定のメッセージを受けたら〇〇をするためにに使う。
	
@tasks.loop(seconds=60)
async def timeloop():
	#無くても動く。seconds=60により60secに1回走る。
	#timeloopは別の名前に変えてもOK。
	#定時で喋る時報とか実装するのに使える。

#上記で作成したtimeloop(仮名)を動かし始めるのに必要。使わない場合は要らない。
timeloop.start()

#Discord Developer Portalで取得したTOKENを記述しておく。必須。
client.run("取得したTOKENを記述")

メッセージの受信、リアクションの受信、一定時間のloop処理があれば
大抵のことが出来そうです。

後は各イベントで使えそうなネタを・・・

Botの発言編

様々な方法がありますが、今回はプログラムから強制的に発言させる方法と
メッセージに反応する2パターンをご紹介しておきます。

Botに発言させる

まずはBotに何か発言させてみましょう。

自分のプログラム通りにBotが動くと一層の愛着が沸くはず!

任意のチャンネルに発言する

記述位置

on_ready内への記述を想定しています。
タブは設置場所に応じて適切に打ち込んで下さい。

@client.event
async def on_ready():
	#ココに記述

Botの起動が完了したらDiscordに発言してくれるようにしてみましょう。

#任意のチャンネルIDを記述
ch_id = ****************
#入力されたチャンネルIDからチャンネル情報を取得してchannelに格納する。
channel = client.get_channel(ch_id)
#channelに指定されたワードをポストする。
await channel.send("起動完了!")

チャンネルIDはDiscordの開発者モードをONにすることでコピー可能になります。

開発者モードをONにしたら、任意のチャンネルを右クリックしてコピーしましょう。

発言のあったチャンネルに発言する

このコード単体で使用するとBotが暴走するので

if message.author.bot:
	return

を使用して回避してください。

記述位置

on_message内への記述を想定しています。
タブは設置場所に応じて適切に打ち込んで下さい。

@client.event
async def on_message(message):
	if message.author.bot: #自身や他Botの発言に反応しないようにする。
		return
	#ここに記述

Botの所属するサーバー内のチャンネルでBotを含む誰かが発言すると
on_messageが起動してプログラムが走ります。
それに合わせてBotが発言するとまた、on_messageが起動して・・・
の無限ループに陥るので、メッセージの送り主がBotだった場合はreturn(終了)で回避します。

await message.channel.send("メッセージを受信!")

メッセージを受信した際に、messageに受信した内容が格納されているため
そこから送信元のチャンネルを取得して「メッセージを受信!」と送ります。

メッセージを受けたら返事をする

おはようと言われたらおはよ!と返すような典型的なやつ。

発言内容を読み取る方法が何パターンかあるのでそれぞれ紹介しておきます。
用途に応じて使い分けましょう。

記述位置

on_message内への記述を想定しています。
タブは設置場所に応じて適切に打ち込んで下さい。

@client.event
async def on_message(message):
	if message.author.bot: #自身や他Botの発言に反応しないようにする。
		return
	#ここに記述

startswithを使用する

startswithを使って前方一致の比較を行う方法。
疑似プレフィックスなるものが出来る。
初心者的に使い勝手が良いけど乱用するとコードがゴテゴテになるので注意。


if message.content.startswith("おはよう"):
	await message.channel.send("おはよ!")
	return

message.contentに発言内容が格納されているので、
startswithで文字列の前方が比較対象と一致するかを確認。
一致ならTrue、違えばFalseを返します。

findを使用する

検索対象(文字列)のどこに比較対象があるか確認するfindメゾットを使用する方法。
Botに反応して欲しいワードがメッセージの途中にあっても反応してくれる。

後述の「in」でも同じような事が出来る。


if message.content.find("おはよう") != -1:
	await message.channel.send("おはよ!")
	return

findメゾットは比較対象の文字列が見つかったら
頭文字の位置を0から始まる整数で返します。

その特性を利用した方法です。
見つからない場合は-1を返すため、
「!」を付けて「-1じゃ無かったらTrue」で比較します。

inを使用する

個人的にはこれが一番簡単かなぁーと。

findと同様に発言内容のいずれかに対象のワードが含まれていれば反応させることができます。

この他にも様々な変数を比較できる使える子らしい。

E

if "おはよう" in message.content:
	await message.channel.send("おはよ!")
	return

Excelみたいにワイルドカードを使用する必要も無い!すごい!

今日の所はこの辺で!
もっと良い方法もあるだろうけど、分からないなりに色々と組み合わせて
様々な機能を持たせる事が出来たので順次紹介出来れば・・・お楽しみに!

コメントを残す

メールアドレスが公開されることはありません。