始めに
本記事は
【生配信】ゲーマー向けプラットフォームdiscordでbotを作ろう【サポーターズCoLab】
で使用するためのチートシートです。
環境構築
テキストチャンネル編
参考資料
事前に用意しておくもの
- Discordアカウント
- 管理者権限を持っているDiscordサーバー
- pythonが実行可能な適当なサーバー(自PCが動いているときだけbotが動作していればいいだけなら自前のPCでも可)
ボット登録
- BOTを作成する。ブラウザでDiscordにログインして、https://discordapp.com/developers/applications/ にアクセスする。
- Create an applicationから新規アプリケーションを作成する。名前は適当に決める。このとき「CLIENT ID」が確認できるので、どこかにメモしておく。これは他の人に見られるとボットを乗っ取られる恐れがあるので注意して保管する。
- SettingsのBotタブからAdd BOTをクリックしてBOT作成する。ポップアップウィンドウが表示されるので「Yes, do it!!」を選択する。
- BOTが作成されたら「TOKEN」をどこかにメモしておく。これも他人に見られないように注意して保管する。必要に応じてbotに権限を選択して付与する。また、自分だけがbotをチャンネルに参加できるようにしたければ、public botをオフにする。
- BOTをDiscordサーバに追加する。SettingsのOAuth2タブのScopesからbotを選択して、bot追加のためのURLを取得して、アクセスする。または、以下のURLのxxxの部分を先ほど取得した「CLIENT ID」に置き換えて任意のブラウザでアクセスする。botに付与された権限によってpermissionsの数字が変化する。 https://discordapp.com/api/oauth2/authorize?client_id=xxx&scope=bot&permissions=0
- 自分が管理者権限を持つサーバー一覧から追加するDiscordサーバを選択して認証する。
- 無事、認証に成功すると、選択したDiscordサーバにBOTがオフライン一覧に追加されている。
botの実装/起動
- 実行するサーバーにpython(3.5以上)をインストールする
-
discord.pyとそのラッパーライブラリをインストールする。
pip install discord
- 必要があればbotを置くディレクトリを作成する。
- discord.py公式ドキュメントのクイックスタートに沿って、サンプルプログラムを作成する。
- コードを実行して、botを起動する。
python exmaple_bot.py
- botの起動を止めるときは、pythonスクリプトの実行を停止させる。
ボイスチャンネル編
をインストールする
参考資料
musicbotであればupdateバッチを実行すれば必要なものが自動でインストールされるはず。やや過剰にインストールされる。
詰まった場合は、ドキュメントページにOS別のインストールガイドがあるので足りないライブラリはそれを参考にインストールする。
チートシート
discord.py APIリファレンス
ボットのテンプレート
import discord
client = discord.Client()
@client.event
async def on_ready():
# 起動時の処理
@client.event
async def on_message(message):
# テキストチャンネルにメッセージが送信されたときの処理
client.run(client_id)
ユーザー情報の取得
説明 |
コード例 |
ボットの情報 |
client.user |
メッセージの送信者の情報 |
message.author |
ボットのID |
client.user.id |
メッセージの送信者のID |
message.author.id |
テキスト送信
説明 |
コード例 |
テキストを送信する |
await message.channel.send(text) |
ボイス
ボイスチャンネルの状態取得
説明 |
コード例 |
戻り値 |
メッセージの送り主のボイスチャンネルの情報の有無 |
message.author.voice |
/None |
メッセージの送り主のボイスチャンネルの情報を取得する |
channel = message.author.voice.channel |
|
チャンネル情報を取得する |
channel = client.get_channel(channel_id) |
|
チャンネル内のメンバー一覧 |
members = channel.members |
type:List , hash(members) でメンバーのdiscord id , str(members) でユーザー名+#4桁のID |
ボイスチャンネルに接続/離脱する
説明 |
コード例 |
ボイスチャンネルに接続する |
await voice = channel.connect() |
ボイスチャンネルから離脱する |
await voice.disconnect() |
オーディオソースのボイスチャンネルの状態を取得
説明 |
コード例 |
戻り値 |
接続中か |
voice.is_connected() |
True/False |
オーディオソースを生成/再生する
説明 |
コード例 |
オーディオソースを生成する |
audio_source = discord.FFmpegPCMAudio(filepath) |
オーディオソースを再生する |
voice.play(audio_source, after=None) |
オーディオソースのステータスを確認する
説明 |
コード例 |
戻り値 |
実行中かどうか |
voice.is_playing() |
True/False |
一時停止中かどうか |
voice.is_paused() |
True/False |
オーディオソースを一時停止する/再開する/停止する
説明 |
コード例 |
一時停止する |
voice.pause() |
再開する |
voice.resume() |
停止する |
voice.stop() |
オーディオソースのボリュームを調節する
説明 |
コード例 |
戻り値 |
ボリュームを取得する |
volume = discord.PCMVolumeTransformer(voice.source).volume |
|
ボリュームを上げる(下げる) |
volume +(-)= value type:float
|
|
実装例
from gtts import gTTS
def make_by_gtts(text, filepath):
tts = gTTS(text=text, lang='ja')
tts.save(filepath + '.mp3')
import subprocess
from pydub import AudioSegment
def make_by_jtalk(text, filepath='voice_message'):
open_jtalk = ['open_jtalk']
mech = ['-x', '/usr/local/Cellar/open-jtalk/1.10_1/dic']
htsvoice = ['-m', '/usr/local/Cellar/open-jtalk/1.10_1/voice/mei/mei_normal.htsvoice']
speed = ['-r', '1.0']
outwav = ['-ow', filepath + '.wav']
cmd = open_jtalk + mech + htsvoice + speed + outwav
c = subprocess.Popen(cmd, stdin=subprocess.PIPE)
c.stdin.write(text.encode())
c.stdin.close()
c.wait()
audio_segment = AudioSegment.from_wav(filepath + '.wav')
os.remove(filepath + '.wav')
audio_segment.export(filepath + 'mp3', format='mp3')
aplay = ['afplay', filepath + '.mp3']
wr = subprocess.Popen(aplay)
def after_play(e):
print(e)
import discord
client = discord.Client()
client_id = '***'
voice = None
volume = None
@client.event
async def on_ready():
# 起動時の処理
print('Bot is wake up.')
@client.event
async def on_message(message):
# テキストチャンネルにメッセージが送信されたときの処理
global voice, volume
if client.user != message.author:
if message.content.startswith('ログイン'):
channel = message.author.voice.channel
voice = await channel.connect()
source = discord.PCMVolumeTransformer(voice.source)
volume = source.volume
message.channel.send('ボイスチャンネルにログインしました')
elif message.content.startswitch('ログアウト'):
await voice.disconnect()
message.channel.send('ボイスチャンネルからログアウトしました')
elif message.content.startswitch('接続状態'):
if voice.is_connected():
message.channel.send('ボイスチャンネルに接続中です')
elif message.content.startswitch('再生'):
filepath = 'music.mp3'
audio_source = discord.FFmpegPCMAudio(filepath)
voice.play(audio_source, after=lambda e: after_play(e))
message.channel.send('{}を再生します'.format(filepath))
elif message.content.startswitch('一時停止'):
voice.pause()
message.channel.send('再生を一時停止しました')
elif message.content.startswitch('再開'):
voice.resume()
message.channel.send('再生を再開しました')
elif message.content.startswitch('停止'):
voice.stop()
message.channel.send('再生を停止しました')
elif message.content.startswitch('音量アップ'):
volume += 0.1
message.channel.send('音量を上げました')
elif message.content.startswitch('音量ダウン'):
volume -= 0.1
message.channel.send('音量を下げました')
elif message.content.startswitch('しゃべって'):
text = 'こんにちは'
filepath = 'voice_message'
if 'gtts' in message.content:
make_by_gtts(text, filepath)
audio_source = discord.FFmpegPCMAudio(filepath + '.mp3')
voice.play(audio_source, after=lambda e: after_play(e))
elif 'jtalk' in message.content:
make_by_jtalk(text, filepath)
audio_source = discord.FFmpegPCMAudio(filepath + '.mp3')
voice.play(audio_source, after=lambda e: after_play(e))
message.channel.send(text)
client.run(client_id)
ボイスチャンネルの音声を取得する
discord.pyでは未実装
https://github.com/Rapptz/discord.py/issues/1094
discord.jsならインタフェースが実装済み。
sttは有料みたいなのでローカルでJuliusを実行する。
認識精度はsttの方が優秀らしい。