#はじめに
結構前からDiscordを使ってチャットやボイスなどを使って会話しながらゲームしたり、情報を共有や打ち合わせしたり、スタンプ押したりなどTwitterと同じかそれ以上くらい使っています。半年くらい前から、Discordはいれてないが、LINEは入ってる。Discordいれてるけど、LINEしか見ない。などといった人たちが多くなって、いちいちDiscordとLINE両方にメッセージを送信するのが面倒だったので、DiscordのメッセージをLINEにも送るbotを作ることにしました。
あと、LINEbotやDiscordbotを作ったことがない。Rubyを書いたことがない人でも簡単に作れました。
最終的なコードはこちら
やったこと
動作確認とか色々テストしながらやってきたので、最終的にはやらなくても良い箇所が存在します。
- LINEbotを作成しオウム返しbotの作成
- 送りたいuserIdまたはgroupIdの確認
- プッシュメッセージを送る
- Discordbotの作成
- コマンドを入力したらLINEに転送するようにした
LINEbotの作成
最終的にはbotを作るだけでよい。Webhookとかこれからやる作業を省いてもできますが、初めてbotを作る人は一通りやっておいた方が良いです
オウム返しbotの作成
-
Heroku+Ruby+SinatraでReplyにオウム返しするLineBotを作ったを参考にしてオウム返しbotを作成します。
-
ただし、Gemfileは以下のように記述すること
$ vi Gemfile
source "https://rubygems.org"
gem 'sinatra'
gem 'line-bot-api'
gem 'discordrb'
- インストール
$ bundle install --path=vendor/bundle
- Herokuに環境変数を設定
$ heroku config:set LINE_CHANNEL_SECRET=<Channel Secret>
$ heroku config:set LINE_CHANNEL_SECRET=<アクセストークン>
- リプライイベントの時にも、userId, groupId, roomIdのjsonが含まれているので、メッセージの転送先に合わせて控えておいてください。
p event['source']
で取得できます。
メッセージを送信する
メッセージのプッシュにかなり時間がかかってしまいました。SDKを使ってもうまくメッセージが送信されませんでしたので、直接APIを叩いてプッシュすることにしました。
LINEのAPIリファレンスを参考にして、Rubyに書き変えてリクエストを投げました。
以下のように入力すると指定したユーザIDに "Hello, world" とメッセージがプッシュされたので、これを元にしてRubyで書き変えることにしました
curl -v -X POST https://api.line.me/v2/bot/message/push \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {channel access token}' \
-d '{
"to": "ユーザID",
"messages":[
{
"type":"text",
"text":"Hello, world"
}
]
}'
以下がRubyに変換したコードです
require 'line/bot'
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://api.line.me/v2/bot/message/push")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer アクセストークン"
request.body = JSON.dump({
"to" => "ユーザIDもしくはグループID",
"messages" => [
{
"type" => "text",
"text" => "Hello, world"
}
]
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
これで、プッシュメッセージを送ることができます。
ここまででプッシュメッセージを送れていれば、config.ruは必要ないので、削除して良いです。
Discordbotの作成
Discordのbotには コマンド + message を送ると、LINEに message を送るプログラムを書きます。
- Discord Developerにアクセスし、botを作成する
- OAuth2で「bot」を選択すると下にURLが出るので、コピペしてサーバにbotを追加
コード
今回書いたコードを大まかに分けて説明します
bot = Discordrb::Commands::CommandBot.new token: 'token', client_id: 'ClientId', prefix: "!"
bot.command :line do |event|
bot_message = event.message.content
bot_message.slice!(0,6)
event.respond "#{bot_message}"
end
- コマンドを使えるbotを生成( Discordrb::Bot.new token: 'token'でも可能)
- bot.commandでコマンドを作成
- event.message.contentは「!line 」も含んでしまいますので、sliceで最初から6文字目までをカット
- event.respondはなくてもよいが、ただの動作確認です。(オウム返し)
def push_line(message)
uri = URI.parse("https://api.line.me/v2/bot/message/push")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer AccessToken"
request.body = JSON.dump({
"to" => "userIdもしくはgroupId",
"messages" => [
{
"type" => "text",
"text" => message
}
]
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
end
push_lineでは「!line」と入力したらコマンド以降のメッセージをLINEに送信します。一回、shellでpostして成功したものをそのままRubyに変換しました。
最後にProcfileを以下の通りに変更
bundle exec ruby app.rb
- 「!line + message」を入力すると「message」がLINEに送信されていれば完成です。
最後にデプロイしてあげれば、いつでもDiscordとLINEにメッセージを共有することができます。成功すると、以下のような動作になります。
最終的なコード
source "https://rubygems.org"
gem 'sinatra'
gem 'line-bot-api'
gem 'discordrb'
require 'line/bot'
require 'discordrb'
require 'net/http'
require 'uri'
require 'json'
bot = Discordrb::Commands::CommandBot.new token: 'token', client_id: 'ClientId', prefix: "!"
def client
@client ||= Line::Bot::Client.new { |config|
config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
}
end
bot.command :line do |event|
bot_message = event.message.content
bot_message.slice!(0,6)
event.respond "#{bot_message}"
push_line(bot_message)
end
def push_line(message)
uri = URI.parse("https://api.line.me/v2/bot/message/push")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Bearer AccessToken"
request.body = JSON.dump({
"to" => "userIdもしくはgroupId",
"messages" => [
{
"type" => "text",
"text" => message
}
]
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
end
bot.run
bundle exec ruby app.rb
おわりに
今回はDiscordにコマンド+メッセージを送ると、LINEにメッセージを転送するbotたちを作りました。Rubyで書いたが、ドキュメントやリファレンスを見ると、Pythonやjavascriptの方がわかりやすいなと感じました。(Rubyが初めてでPuthonとjavascriptは書いたことがあるというのもありますが)
無駄な部分がいくつか残ってますが、当初の目的である「DiscordとLINEにメッセージを送りたい」というのは達成できました。discordbotのコマンドは結構簡単に作れたので、これからも機能を追加していこうと思います。
あと、bot名は適当です
2019.5.16追記
肝心の誰が発信したかが不明だったので、以下のコードに編集
def add_message(str1, str2)
return str1 + str2
end
post(add_message(event.user.name, bot_message))