LoginSignup
5
3

More than 1 year has passed since last update.

DiscordのBotを作ってみよう!②メッセージとコマンドに反応するBot

Posted at

はじめに

こんにちは、とみーです。
前回の記事を見てくださった皆さん、ありがとうございました!
初めての投稿だったのに自分の想像以上の方が見てくださって、うれしかったです。ありがとうございました!
前回に開発環境を整えたため、今回からいよいよ実装を行っていきたいと思います。
興味のある方よろしければ最後までご覧ください。

注意すること

  • これより先の記事では、Ruby開発環境、discordrbをインストールしていること前提でお話していきたいと思います。まだの方は、前記事準備編をご覧ください。
  • 自分の解釈が間違ってる可能性もあります。ご了承ください。
  • タグにもつけていますが、Rubyにて開発を行っていきます。
  • フォルダの名前などは任意ですが、予期しないエラーや不具合を避けるため、すべて半角英数で入力してください。

Rubyやプログラミング言語を触ったことがない方へ

今回から解説していく記事ですが、Rubyや他のプログラミング言語を全く触ったことがない方には意味が分からず難しいかもしれません。
自分もはじめたてのため、できるだけ優しく解説するつもりですが、基礎は飛ばしてしまうかもしれません。
プログラミング言語を全く触ったことがない方は、まずはこの記事を読む前に、オンライン教材などで基礎を習得することをお勧めします。

はじめてのBotを起動してみよう!

まずは、Botを起動するためのコードを入力していきましょう。
フォルダを作成して(フォルダの名前はなんでも構いません。ここではexamplebotという名前で作成しました。)
次にコードエディタなどでbot.rbファイルを作成します。(ファイルの名前はなんでも構いません。)
それでは、bot.rbを開いていきましょう!

bot.rb
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'ここにBotのトークンを入力', client_id: ここにBotidを入力 , prefix: 'Botに設定したいPrefixを入力'
bot.run

まずはGemを使うためにrequire 'discordrb'を入力します。
bot変数にインスタンスを作成します。 token: 'トークン'のところにトークンを入力して、
client_id: BotのIDここに、BotのIDを入力していきます。
prefix: 'prefix'ここにプレフィックスを入力します。ここで、Botのコマンド入力の際のプレフィックスが決まります。
プレフィックスとは、コマンドの前についてくる記号!とか?とか/とかの事です。
本記事では、$を使うことにします。
最後にbot.runで起動します。

書けたら、保存して、起動してみましょう!

コマンドプロンプト・ターミナル
ruby bot.rb
[INFO : websocket @ 2021-05-16 11:40:24.838] Discord using gateway protocol version: 6, requested: 6

はじめまして!

quita8.jpg
やった!、初めての起動がうまくいきました!
でも、起動するプログラム以外を書いていないのでまだ起動しただけ...
メッセージを入力しても何も返してくれません...

メッセージに反応してくれるBotを作成する

これでは、何もできないので、メッセージを送信したら返してくれる機能を作りましょう!
いったん終了します。(現時点ではまだ終了するプログラムを作成していないのでCtrl+Cキーで終了してください。)
Discord側も少し遅れてBotがオフラインになります。

何かメッセージが送られてきたら実行する

まずは、どんなメッセージにも反応する機能を作ってみましょう

書き方

bot.rb
# discordrbを使うために必要
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'ここにBotのトークンを入力', client_id: ここにBotidを入力 , prefix: 'Botに設定したいPrefixを入力'

# メッセージが送られてきたら実行
bot.message do |変数|
  #処理
end

bot.run

Hello World!

bot.rb
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'ここにBotのトークンを入力', client_id: ここにBotidを入力 , prefix: 'Botに設定したいPrefixを入力'

# 何かメッセージが送信されたら実行
bot.message do |event|
  event.respond 'Hello, world!'
end

bot.run

書けたら、保存して、起動してみましょう!

コマンドプロンプト・ターミナル
ruby bot.rb
[INFO : websocket @ 2021-05-16 11:58:16.945] Discord using gateway protocol version: 6, requested: 6

起動しましたか?
起動したら何かメッセージを送信してみましょう!
quita9.jpg
上で設定したメッセージを返してくれてますね!成功です!

どんなことしたの?

先ほどのプログラムは

bot.rb
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'ここにBotのトークンを入力', client_id: ここにBotidを入力 , prefix: 'Botに設定したいPrefixを入力'

# 何かメッセージが入力されたら実行
bot.message do |event|
  event.respond 'Hello, world!'
end

bot.run

と入力しました。これは何かというと、
まず

bot.message do |event|
  event.respond 'Hello, world!'
end

さっき上で作成したbotの変数を使って、なにか、メッセージが来たら実行するというプログラムを作成しました。
変数.respondでメッセージを送信できます。(他の方法もありますが、今回は割愛します。)
ですのでHello, Worldのところを変えると、メッセージが変わります。(ダブルクオーテーションでも構いません。ダブルクオーテーションでくくると変数展開が使えます。)

ちょっと応用編

ちょっとプログラムを変えてみましょう!

bot.message do |event|
  event.respond event.user.name
end

event.respondの部分をevent.user.nameに変えました。実行してみましょう!
quita10.jpg
自分の名前が返ってきました!

もう一つ。

bot.message do |event|
  event.respond "#{event.user.name}さん、#{event.server.name}へようこそ!"
end

変数展開を用いて、ようこその文章を作りました。実行してみましょう!
quita11.jpg
名前さん、サーバ名へようこそ!と返ってきました!
このように 変数.user.name変数.server.nameなどを使えば、送信したユーザに応じて名前を変えるコマンドの実行に成功しました!

メッセージから値を色々とってみよう!

他にもいろんな値が取得することができます。

変数 取得できる値 備考
変数.user.name メッセージを送信したユーザーの名前
変数.user.id メッセージを送信したユーザのID
変数.user.display_name メッセージを送信したユーザのサーバ上のニックネーム ニックネーム未設定時はユーザの名前で返ってくる
変数.user.server.name メッセージを送信したサーバの名前
変数.user.server.id メッセージを送信したサーバのID
変数.channel.name メッセージを送信したサーバのチャンネル
変数.channel.id メッセージを送信したサーバのチャンネルID
変数.user.voice_channel.name メッセージを送信したユーザが入っているボイスチャンネル ボイスチャンネルに入っていないときは NoMethodErrorが出ます。
変数.user.voice_channel.id メッセージを送信したユーザが入っているボイスチャンネルのID ボイスチャンネルに入っていないときはNoMethodErrorが出ます。

特定のメッセージに反応してくれる機能を作成する

さて、今の状態では、メッセージの内容に関係なく、実行してしまいます。
このままでは、どんなメッセージでも返信してしまうため、とてもうるさくなってしまいます。
そこで、特定のメッセージのみに反応するBotを作ってみましょう!

bot.rb
# はじめましてと入っていれば実行
bot.message(containing: "はじめまして") do |event|
  event.respond "#{event.user.name}さん、#{event.server.name}へようこそ!"
end

保存して、実行してみましょう!
※ここから、ターミナルの実行画面省略します。ruby [ファイル名]で実行できます。
quita12.jpg
はじめまして、という文章が入っていれば実行されるようになりました!
ちなみに、

bot.rb
# はじめましてか初めましてと入っていれば実行
bot.message(containing: ["はじめまして","初めまして"]) do |event|
  event.respond "#{event.user.name}さん、#{event.server.name}へようこそ!"
end

containing:["対象メッセージ1","対象メッセージ2"]でくくって配列にすると複数条件の指定ができます。
image.png

コマンドで動く機能を作ってみよう

さて、先ほどはメッセージに反応する機能を作成しました。
次は、コマンドを作成して、コマンドが入力されたら、実行するプログラムを作成していきましょう。

bot.command :設定したいコマンド do |変数|
  # 処理
end

$helloと入力されたら実行するコマンド

bot.rb
bot.command :hello do |event|
  event.respond "#{event.user.name}さん、こんにちは"
end

実行してみます。
コマンドは、bot変数に入れたprefix引数がコマンドの前に入れる記号となります。
ここでは、$を設定したので
$helloになります。
image.png

helpコマンドについて

コマンドBotを作る際によく、helpコマンドが作ってありますが、helpコマンドはすでに用意されています。
一度、$helpと入力してみましょう(prefixの値を変えている場合は頭文字もそれに変更してください。)
image.png
List of commands:というものが出てきました、ここにプログラムしたコマンドの一覧が表示されます。(今回は、helloコマンドしか作っていないため、helloしか出ていませんが、他のコマンドも作成したらここに表示されます。)
helloの欄を見ると、No description availableと書かれています。つまり、helloコマンドの説明を書いてやる必要があります。

helpに説明文が出てくるようにしよう。

bot.rb
bot.command(:hello, description: "こんにちはメッセージを返します。", usage: "表示するだけです。引数はありません") do |event|
  event.respond "#{event.user.name}さん、こんにちは"
end

descriptionに表示したい内容を書きます。 usageには、help [コマンド]とか、間違えて使ったときに表示される内容を書きます。
image.png
helpコマンドを使うと説明が出てくるようになりました!

オプションハッシュいろいろ

ハッシュ 属性 説明 備考
:permisson_level Integer このコマンドを使用するための最小の権限レベル 権限レベルは、Discordのロール権限とは異なります。詳しくは、こちらの記事が参考になります。
:permission_level String,false コマンドを実行する際に上記の:permission_levelの設定に対して、ユーザが十分な権限を持っていないときに表示されるメッセージです。 同上
:required_permissons Array コマンドを使用するために、必要なDiscord権限 おそらくDiscordの権限だと思いますが、自分もはっきりわかっていません。
:required_roles Array このコマンドを使用するために必要なロール(記入したロールすべて必要です) 自分もはっきりわかっていません。
:allowed_roles Array このコマンドを使用するために必要なロール(1つ以上必要です) 自分もはっきりわかっていません。
:channels Array このコマンドを使用できるチャンネル
:chain_usable true,false コマンドチェーン?やサブチェーンでの可否を設定する 自分もはっきりわかっていません。
:help_available true,false helpコマンドを入力したときに、一覧に表示されるかどうか デフォルトはtrue(表示する)
:description String helpコマンドを入力した際に、出てくる説明文
:usage String コマンドの詳細説明 help [コマンド名]などで表示される説明
:min_args Integer このコマンドを実行するために必要な最小の引数の数
:max_args Integer このコマンドが持つべき引数の最大数

その他のハッシュはこちら
※属性について

  • String 文字列型
  • Integer 整数型
  • Arrey 配列
  • true,false 有効か無効です

Botのステータスを変えてみよう!

さて、次にステータスを変更する方法です。
Botも状態をオンライン、退席中、取り込み中、オンライン状態を隠すなどプログラムで変更可能です!あまりつかわないけど...

オンラインに変更

変数.onlineでステータスをオンラインにできます。
ステータスを変更する際に、だれでも変更できてしまうと、さすがにマズイので、コマンドを実行したユーザIDと、configatron.ownerid(ここに自分のIDが設定されています。後程説明します。)の一致を確認しています。

bot.rb
# ステータスをオンラインに変更する
bot.command(:online, help_available: false) do |event|
  if event.user.id == configatron.ownerid
    bot.online
    event.respond "Botはオンラインになりました。"
  end
end

configatron.owneridは後程説明します。
image.png

退席中に変更

変数.idleでステータスを退席中に変更できます。

bot.rb
# ステータスを退席中に変更する
bot.command(:idle, help_available: false) do |event|
  if event.user.id == configatron.ownerid
    bot.idle
    event.respond "Botは退席中になりました。"
  end
end

image.png

取り込み中に変更

変数.dndでステータスを取り込み中に変更できます。

bot.rb
# ステータスを取り込み中に変更する
bot.command(:dnd, help_available: false) do |event|
  if event.user.id == configatron.ownerid
    bot.dnd
    event.respond "Botは取り込み中になりました"
  end
end

image.png

オンライン状態を隠す

変数.invisibleでオンライン状態を隠せます。
※ちなみに\nをつかうと改行できます!

bot.rb
# ステータスをオンライン状態を隠すに変更する
bot.command(:invisible, help_available: false) do |event|
  if event.user.id == configatron.ownerid
    bot.invisible
    event.respond "Botはオンライン状態を隠しています\nこのコマンドを入力しても実際にシャットダウンされたわけではありません。\n終了するときはshutdownコマンドを入力してください。"
  end
end

image.png

ステータスメッセージを変更してみよう

メンバーの欄に出てますよね...*helpをプレイ中とかのやつですよ...
あれもプログラムで自在に変更できるようにしてみましょう!

〇〇をプレイ中

変数.gameで変更できます。
すこしややこしいので、解説。
do |event,message|のところです。
Discordでコマンドを送信する際、半角スペースを空けると引数となります。
したの画像を見ていただくと、$set_game $helpと送信しています。
$set_gameのスペースの後、$helpmessage変数が受け取っています。

bot.rb
# Botのステータスメッセージを変更する
# ~~をプレイ中
bot.command(:set_game, help_available: false) do |event,message|
  if event.user.id == configatron.ownerid
    bot.game = message # message変数は(Discordで半角スペースを空けたところからの文字を受け取る[次の半角スペースまで])
    event.respond "Botステータスメッセージを#{message}に変更しました。"
  end
end
# ちなみに、変数.game に nilを入れると、ステータスメッセージを消去出来ます。

image.png
うまく変わりました!
image.png

〇〇を視聴中

変数.watchingで変更できます。

bot.rb
# ~~を視聴中
bot.command(:set_watch, help_available: false) do |event,message|
  if event.user.id == configatron.ownerid
    bot.watching = message
    event.respond "Botステータスメッセージを#{message}に変更しました。"
  end
end

image.png
image.png

〇〇を再生中

変数.listeningで変更できます。

bot.rb
# ~~を再生中
bot.command(:set_play, help_available: false) do |event,message|
  if event.user.id == configatron.ownerid
    bot.listening = message
    event.respond "Botステータスメッセージを#{message}に変更しました。"
  end
end

image.png
image.png

終了するプログラム

最後にBotを終了してみましょう。
いままでは、Ctrl+Cで終わっていましたが、今度は、終了するコマンドを作ってみましょう。

bot.rb
# shutdownコマンドが入力されたとき
bot.command(:shutdown, help_available: false) do |event|
  # コマンド入力している人がオーナーかチェックします
  if event.user.id == configatron.ownerid
    # 終了しましたと送信(先に送信しておかないと切断されてしまう為)
    event.respond "終了しました"
    # botを切断
    bot.stop
  end
end

image.png

Botがオフラインになり、プログラムが終了しました。

ちょっと応用してみよう

時間に応じた挨拶をしてくれる機能を作ってみよう

ここまでの知識で、ちょっとだけ時間の表示と、時間によって違ったあいさつをしてくれるプログラムを作ってみましょう
Time.nowで現在時刻を取得することができます。それをtime変数にインスタンスを作成します。
変数.hourで時だけ取得できます。
変数.minで分だけ取得できます。
取得した時で、朝、昼、夕、夜を判断、それによってif文でメッセージを条件分岐します。

bot.rb
bot.command(:hello, description: "こんにちはメッセージを返します。", usage: "表示するだけです。引数はありません") do |event|
  # 現在時刻を取得
  time = Time.now
  message = ""
  # 時間を確認、メッセージ分岐
  if time.hour < 6
    message = "遅くまでおつかれさま"
  elsif time.hour < 12
    message = "おはよう!"
  elsif time.hour < 17
    message = "こんにちは!"
  else
    message = "こんばんは"
  end
  # Discordに送信
  event.respond "#{event.user.name}さん、#{message} 今の時間は#{time.hour}#{time.min}分だよ"
end

image.png
時間に応じて挨拶が変わり、現在時刻を表示されるようになりました。

Tokenの安全な取り扱いかた

さいごにですが、今回のBotプログラムは直接、トークンを書いています。
前回も書きましたが、トークンはBotにログインするための重要なコードです!
したがって、トークンを直接記述する方法はあまりよくない上に、GitやGitHubにするときに色々不便です。
そこで、別に設定ファイルを作り、ついでに、IDやプレフィックス、オーナIDなどもそちらに設定していきましょう。
まず、Gemをインストールしていきましょう。

コマンドプロンプト・ターミナル
$ gem install configatron

Fetching configatron-4.5.1.gem
Successfully installed configatron-4.5.1
Parsing documentation for configatron-4.5.1
Installing ri documentation for configatron-4.5.1
Done installing documentation for configatron after 0 seconds
1 gem installed

$は不要です、gemから入力してください。
gem install configatronと入力し、最後に1 gem installedが出ればOKです。
次に、config.rbを作成します。

config.rbの中身

config.rb
configatron.token = 'YOUR_TOKEN' # 'YOUR_TOKENのところに、自分のトークンを入力。
configatron.botid = #自分の使用するBotのIDをここに入力
configatron.prefix = 'prefix' # 'prefix'のところに、使いたいプレフィックスを入力する。
configatron.ownerid = # Botの管理するユーザのIDを入力

ここにそれぞれ設定するIDやトークン、プレフィックスを入力します。
ちなみに、ステータスメッセージのところで出てきた、configatron.owneridはここから値をとっています。

configatronを使う

さっきのBotを書いていたファイルに戻ります

bot.rb
# gemの読み込み
require 'configatron'
# さっきのトークンを書き込んだファイルです
requere_relative 'config.rb'
# token:とclient_id:とprefix:をそれぞれ書き換えます。
bot = Discordrb::Commands::CommandBot.new token: configatron.token, client_id: configatron.botid , prefix: configatron.prefix

これで、Botの設定ファイルを別にすることに成功しました。
configatron.メゾットで、config.rbに書いた内容を呼び出すことができます。
あ、GitやGithubとかで保管したい方は、.gitignoreconfig.rbを例外設定するのをわすれないようにしてね!

.gitignore
# トークンとか書いてあるため、除外
config.rb

ここまでお疲れさまでした!

おわりに

ここまで、長い記事を見てくださって本当にありがとうございました!
説明がうまくできているかわかりませんが、見てくださったみなさんの開発のヒントになればとてもうれしいです。
さて、まだ自分が説明しきれていない機能がもうちょっとあります。次回はそこのところを説明できればと思います。
よろしくお願いします。

今回作ったBotのプログラムはこちら

今回作ったBotのプログラムのソースコードです。よろしければご覧ください。
bot.rbの中に入っています。

参考にしたもの

DiscordのBotを作ってみよう バックナンバー

  • 1.準備編(インストールまで)
  • 2.メッセージとコマンドに反応するBot(この記事です)
  • 3.(準備中)
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3