こんばんは。りーぜんとです。
題名の通りです。経緯↓
Teams絶対課題見逃すから課題管理用discordBOTつくる
— りーぜんと (@50m_regent) May 13, 2020
流行りのオンライン授業が弊学でも始まりました。草ですね。
もはやオンライン授業の代名詞となっているZoomではなくMicrosoftのTeamsというものを使って授業が行われています。このTeams、学生側は課題が絶望的に管理しづらいです。(個人の意見)
じゃあクラスのDiscordに管理用Bot作って入れれば良いじゃん。(名案)
他の高校生たちがクラスDiscordを運用してるかは知りませんが、うちはあるので活用するまでです。
要は、この記事ではPythonを使ってdiscordのbotを作る方法を説明します。
作成したコードはGitHubに載っているので参考にしてみてください。
目次
Discord上でBotアプリを作る
新しいBotをDiscordに登録します。Discord Developer Portalにアクセスします。
右上のNew Applicationをクリックして好きな名前(Botの名前になります)で新しいアプリケーションを作成しましょう。
次に左のタブのBotからAdd Botします。
Usernameの下にTokenというところがあるのでCopyしてどこかに保存しておきましょう。
今度はOAuth2タブに移動します。Scopesの中のbotにチェックマークを入れて、Bot PermissionのSend messagesとManage messagesにチェックを入れます。
出てきたリンクを開いてBotを自分が参加しているDiscordサーバーに追加することができます。
Discordを開いて確認してみましょう。
とりあえず接続してみる
今回はPythonを使ってコードを書きます。discord.pyを使うので各自使えるようにしておいてください。
とりあえずメッセージに反応するようにします。
import discord
TOKEN = '***'
client = discord.Client()
@client.event
async def on_message(message):
if message.content == 'hello':
await message.channel.send('hi')
client.run(TOKEN)
TOKENはDiscord上でBotアプリを作るでコピーした文字列に置き換えてください。
かわいいですね。
client.run()でBotを実行してます。
on_message()は何かメッセージが送信されたときに実行されます。送られてきた内容がhelloだったときにhiと返すだけのBotです。
次はよくある**!p**のようなコマンドを実装してみます。
コマンドを追加してみる
コマンドの数だけif文を書くのはセンスがないのでコマンドリストを作っておいてそこからコマンドを読むようにしましょう。
import discord
assignment_list = []
client = discord.Client()
async def kadaihelp(message):
string = 'コマンドリスト\n'
for command in COMMANDS:
string += '------------------------\n'
string += '{}: {}\n'.format('!' + command, COMMANDS[command]['description'])
string += ' 使い方: {}\n'.format(COMMANDS[command]['use'])
string += ' 省略形: {}\n'.format(COMMANDS[command]['alias'])
string += '------------------------'
await message.channel.send(string)
async def newkadai(message):
msg = message.content.split(' ')
try:
title, deadline, memo = msg[1:]
assignment_list.append({
'title': title,
'deadline': deadline,
'memo': memo
})
await message.channel.send('課題を追加しました!')
except:
await message.channel.send('入力形式が間違っています。')
async def deletekadai(message):
msg = message.content.split(' ')
for i in range(len(assignment_list)):
if assignment_list[i]['title'] == msg[1]:
assignment_list.pop(i)
await message.channel.send('課題を削除しました')
async def kadailist(message):
string = '課題一覧\n'
for i, assignment in enumerate(assignment_list):
string += '------------------------\n'
string += '{}. {}\n'.format(i + 1, assignment['title'])
string += '締切: {}\n'.format(assignment['deadline'])
string += '備考: {}\n'.format(assignment['memo'])
string += '------------------------\n'
string += '現在、{}個の課題が出されています。'.format(len(assignment_list))
await message.channel.send(string)
async def close(message):
await client.close()
TOKEN = '***'
COMMANDS = {
'kadaihelp': {
'description': 'このリストを表示します。',
'use': '!kadaihelp',
'alias': '!kh',
'func': kadaihelp
},
'newkadai': {
'description': '新しい課題を追加します。',
'use': '!newkadai \{タイトル\} \{締切\} \{備考\}',
'alias': '!nk',
'func': newkadai
},
'deletekadai': {
'description': '課題削除',
'use': '!deletekadai \{課題名\}',
'alias': '!dk',
'func': deletekadai
},
'kadailist': {
'description': '登録されている課題一覧を表示します。',
'use': '!kadailist',
'alias': '!kl',
'func': kadailist
},
'exit': {
'description': 'Botを終了します。',
'use': '!exit',
'alias': '!ex',
'func': close
}
}
@client.event
async def on_ready():
print('KadaiShosu起動')
@client.event
async def on_message(message):
msg = message.content.split(' ')
if message.author.bot:
return
for command in COMMANDS:
if msg[0] in ['!' + command, COMMANDS[command]['alias']]:
await COMMANDS[command]['func'](message)
client.run(TOKEN)
とりあえず5つコマンドを追加してみました。
COMMANDSの中に辞書形式でコマンドリストを作成しました。on_message()の中で全てのコマンドに対して呼び出されたかどうかを判別して実際にその動作を行う関数を実行します。
それぞれのコマンドに省略形としてaliasを用意しました。もっと良い書き方があるかもしれません。是非いろいろ試してみてください。
ここまででとりあえず課題管理Botとしては機能します。しかし、このままではプログラムを閉じたときに課題がリセットされてしまいます。
最後に変数を保存、読み込む部分だけ書いてみます。
import pickle
async def close(message):
pickle.dump(assignment_list, open('assignments.pkl', 'wb'))
await message.channel.send('Bye^^')
await client.close()
def load_assignments():
global assignment_list
assignment_list = pickle.load(open('assignments.pkl', 'rb'))
load_assignments()
新しくpickleというモジュールを使います。このモジュールは変数の保存を実現してくれます。
close()は書き換えて、他は書き足してください。
!exitでBotを終了したときにassignments_listが保存されて、起動時に読み込まれます。
まとめ
今回はここまでとします。他にもいろいろな機能があると嬉しいと思うので、自分で実装してみてください。
よければTwitterフォローしてください。じゃあね。