discord.py チュートリアル
注:以下コードは古い場合があります。
discord.py 2.1.0でも動作を確認していますが、基本的にはdiscord.py 1.6.0 ver 対応のコードです。
他にも思い出したり面白い応用コードがあれば追記します。
基本操作
ログイン
1.6.0 ver
import discord
# Discord botクライアント
client = discord.Client()
# botが起動したときの処理
@client.event
async def on_ready():
print("Botが立ち上がったよ!")
# Discord APIトークン
DISCORD_API_TOKEN = "discord developerで取得したトークンをこちらに"
# botを起動
client.run(DISCORD_API_TOKEN)
2.1.0 ver
import discord
# Discord botクライアント
client = discord.Client(intents=discord.Intents.all())
# botが起動したときの処理
@client.event
async def on_ready():
print("Botが立ち上がったよ!")
# Discord APIトークン
DISCORD_API_TOKEN = "discord developerで取得したトークンをこちらに"
# botを起動
client.run(DISCORD_API_TOKEN)
タスク作成
import discord
from discord.ext import commands, tasks
# botが起動したときの処理
@client.event
async def on_ready():
print("Botが立ち上がったよ!")
loops.start()
# 10秒おきに「やあ」というだけ
@tasks.loop(seconds=10)
async def loops():
print("やあ")
discord上で誰かがしゃべった時の処理
import discord
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
# 「おはよう」に対して「うるせえ」と返すだけ
if message.content.startswith("おはよう"):
await message.channel.send("うるせえ")
discord上で誰かがリアクションした時の処理
import discord
from discord.utils import get
# リアクション追加時の処理
@client.event
async def on_raw_reaction_add(payload):
#📝のリアクションが特定のメッセージで2回以上押された場合、「📝のリアクションが2回以上押されたよ!」と言う
if payload.emoji.name == "📝" :
channel = client.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
reaction = get(message.reactions, emoji=payload.emoji.name)
if reaction and reaction.count > 2:
print("📝のリアクションが2回以上押されたよ!")
embed送信
import discord
import datetime
embeds=discord.Embed(title="テスト", url="https://www.google.com/",description="これはテストです", color=0x000000)
embeds.add_field(name="ぶんぶんはろー", value="ゆうちゅーぶ",inline = True)
embeds.set_footer(text=str(datetime.datetime.now().strftime('%Y.%m.%d, %H:%M:%S')))
msg = await client.get_channel("INT形式のチャンネルID").send(embed=embeds)
名前やIDの取得
import discord
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
print(message.author) #あああ#1111
print(message.author.id) #12345678909887
print(message.author.name) #あああ
実際に使用した応用編
期間中にたくさん喋った人を確認する
import discord
import datetime
from discord.utils import get
import collections
channel = client.get_channel(int("チャンネルID"))
before = await channel.fetch_message(int("このメッセージIDと以前のメッセージを取得する"))
after = await channel.fetch_message(int("このメッセージIDと以降のメッセージを取得する"))
chat_list = []
async for i in channel.history(after=after.created_at+ datetime.timedelta(seconds=-1),before=before.created_at+ datetime.timedelta(seconds=1)):
chat_list.append(i.author.id)
chat_ranking = collections.Counter(chat_list).most_common()
for count,userdata in enumerate(chat_ranking):
user = await server.fetch_member(int(userdata[0]))
if count == 0:
print(f"{user.name}さんは{userdata[1]}回発言し全体の1位です!")
else:
print(f"{user.name}さんは{userdata[1]}回発言しました")
画像を保存してzipファイルにしてあげなおす
import discord
import requests
import shutil
import os
def download(url, file_name):
r = requests.get(url, stream=True)
if r.status_code == 200:
with open(file_name, 'wb') as f:
f.write(r.content)
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
# !imageという呪文で開始
if message.content.startswith('!image'):
os.mkdir("pic")
message = channel.fetch_message(int("メッセージID"))
for i in message.attachments:
# 拡張子
ext = i.url.split(".")[-1]
# discordimg.拡張子 というネームで画像を保存する
download(i.url,f"./pic/discordimg.{ext}")
#フォルダをフォルダをzipに変換し送信
shutil.make_archive('./discordpic', 'zip', root_dir='./pic')
await message.channel.send(file=discord.File("discordpic.zip"))
shutil.rmtree("pic")
会話を無限に継続する
import discord
import asyncio
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
if message.content.startswith('!talk'):
await message.channel.send("ずっとオウム返ししてやるよ!")
while True:
try:
# 話してるのが該当ユーザーか確認し、30秒たつと自動的にエラーを返す
msg = await client.wait_for("message",check=lambda m: m.author == message.author, timeout=30.0)
# 会話を抜け出す
if msg.content == "!end":
await message.channel.send("もうギブアップかい!")
break
else:
await message.channel.send(msg.content)
except asyncio.TimeoutError:
await message.channel.send('時間だよ!')
break
return
特別なロールの人からしか受け付けない
import discord
admin = ["admin"]
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
if message.content.startswith('!check') and list(set([z.name for z in message.author.roles])&set(admin)):
await message.channel.send("youは管理者だね")
サーバーで登録した絵文字をリアクションとして使う
import discord
from discord.utils import get
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
if message.content.startswith('!addreact'):
#サーバーにkaomojiという名前で登録した絵文字を使う
react = get(message.guild.emojis, name='kaomoji')
await message.add_reaction(react)
リアクションで反応するスライド式embedを作成
意外と説明書だったり使えるのがこれ
import discord
# メッセージが送信されたときの処理
@client.event
async def on_message(message):
if message.content.startswith('!read'):
#embedを事前に作成
embed_1 =discord.Embed(title="やあ", description="こんにちは", color=0x000000)
embed_2 =discord.Embed(title="Hi", description="Hello", color=0x000000)
embed_3 =discord.Embed(title="你好", description="你好", color=0x000000)
#最初にembed_1を表示
page = "🇯🇵"
msg = await message.channel.send(embed=embed_1)
#リアクションを追加
await msg.add_reaction("🇯🇵")
await msg.add_reaction("🇺🇸")
await msg.add_reaction("🇨🇳")
#リアクションやユーザーが正しいかを確認
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["🇯🇵", "🇺🇸", "🇨🇳"]
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
#違うページから押された場合は該当のembedに更新。リアクションのカウントを戻す
if str(reaction.emoji) == "🇯🇵" and page != "🇯🇵":
page = "🇯🇵"
await msg.edit(embed=embed_1)
await msg.remove_reaction(reaction, user)
elif str(reaction.emoji) == "🇺🇸" and page != "🇺🇸":
page = "🇺🇸"
await msg.edit(embed=embed_2)
await msg.remove_reaction(reaction, user)
elif str(reaction.emoji) == "🇨🇳" and page != "🇨🇳":
page = "🇨🇳⚾"
await msg.edit(embed=embed_3)
await msg.remove_reaction(reaction, user)
except asyncio.TimeoutError:
#タイムアウトするとメッセージを削除
await msg.delete()
break