#はじめに
GoでDiscordのbotを作ろうとしたところ、日本語の記事が一切見あたらなかったので申し訳程度のメモですが、記そうと思います。
- 送信されたメッセージに応じて処理を行う。
- 通話チャンネルに出入りする。
- 通話チャンネルで音声入力を監視する。
を実装したbotを作っていきます。
#注意 (2020/05/21)
この記事は投稿してから数年が経過してるので、ライブラリの更新状況によっては仕様が変わっている可能性があります。多分ある程度参考にはなると思うんですが、もしエラーが出たらライブラリのgodocとかをチェックしてみてくださいね!!!!!
#Go側の準備
ライブラリは https://github.com/bwmarrin/discordgo を使います。
go get github.com/bwmarrin/discordgo
をしておいてください。
#Discord側の準備
1.まずDiscord-My Appsにアクセスして、NewAppボタンをクリック。
2.続いて、アプリケーションの名前(アイコン、アプリケーションの説明)を入力してCreateAppをクリック。
(ここでいうアプリケーションの名前がBotの名前になります)
3.Create a Bot UserをクリックしたのちYes, do itをクリックしてボットユーザーを作成!
4.するとbotの詳細画面がでるので、
- APP DETAILS以下の__ClientID__
- APP BOT USERの_click to reveal_をクリックして表示される__Token__
を控えておきましょう。その後save changesで設定を保存しましょう
https://discordapp.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot&permissions=0
に、YOUR_CLIENT_ID
を手順4で控えたClient IDに置き換えてアクセスしましょう。
(上の画像なら342494499286679553と置き換える)
botを追加したいサーバーを選択して認証をクリック。
これでbotがサーバーに追加されました。
これで準備は整いました
#プログラム
以下プログラム本文です。
- YOUR_TOKEN
- YOUR_CLIENT_ID
- VOICE_CHANNEL_ID
を各々の値に変更して使用してください
package main
import (
"fmt"
"time"
"github.com/bwmarrin/discordgo"
"log"
"strings"
)
var(
Token = "Bot YOUR_TOKEN" //"Bot"という接頭辞がないと401 unauthorizedエラーが起きます
BotName = "<@YOUR_CLIENT_ID>"
stopBot = make(chan bool)
vcsession *discordgo.VoiceConnection
HelloWorld = "!helloworld"
ChannelVoiceJoin = "!vcjoin"
ChannelVoiceLeave = "!vcleave"
)
func main() {
//Discordのセッションを作成
discord, err := discordgo.New()
discord.Token = Token
if err != nil {
fmt.Println("Error logging in")
fmt.Println(err)
}
discord.AddHandler(onMessageCreate) //全てのWSAPIイベントが発生した時のイベントハンドラを追加
// websocketを開いてlistening開始
err = discord.Open()
if err != nil {
fmt.Println(err)
}
defer discord.Close()
fmt.Println("Listening...")
<-stopBot //プログラムが終了しないようロック
return
}
func onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if err != nil {
log.Println("Error getting channel: ", err)
return
}
fmt.Printf("%20s %20s %20s > %s\n", m.ChannelID, time.Now().Format(time.Stamp), m.Author.Username, m.Content)
switch {
case strings.HasPrefix(m.Content, fmt.Sprintf("%s %s", BotName, HelloWorld)): //Bot宛に!helloworld コマンドが実行された時
sendMessage(s, m.ChannelID, "Hello world!")
case strings.HasPrefix(m.Content, fmt.Sprintf("%s %s", BotName, ChannelVoiceJoin)):
//今いるサーバーのチャンネル情報の一覧を喋らせる処理を書いておきますね
//c, err := s.State.Channel(m.ChannelID) //チャンネル取得
//guildChannels, _ := s.GuildChannels(c.GuildID)
//var sendText string
//for _, a := range guildChannels{
//sendText += fmt.Sprintf("%vチャンネルの%v(IDは%v)\n", a.Type, a.Name, a.ID)
//}
//sendMessage(s, c, sendText) チャンネルの名前、ID、タイプ(通話orテキスト)をBOTが話す
//VOICE CHANNEL IDには、botを参加させたい通話チャンネルのIDを代入してください
//コメントアウトされた上記の処理を使うことでチャンネルIDを確認できます
vcsession, _ = s.ChannelVoiceJoin(c.GuildID, "VOICE_CHANNEL_ID", false, false)
vcsession.AddHandler(onVoiceReceived) //音声受信時のイベントハンドラ
case strings.HasPrefix(m.Content, fmt.Sprintf("%s %s", BotName, ChannelVoiceLeave)):
vcsession.Disconnect() //今いる通話チャンネルから抜ける
}
}
//メッセージを受信した時の、声の初めと終わりにPrintされるようだ
func onVoiceReceived(vc *discordgo.VoiceConnection, vs *discordgo.VoiceSpeakingUpdate) {
log.Print("しゃべったあああああ")
}
//メッセージを送信する関数
func sendMessage(s *discordgo.Session, channelID string, msg string) {
_, err := s.ChannelMessageSend(c.ID, msg)
log.Println(">>> " + msg)
if err != nil {
log.Println("Error sending message: ", err)
}
}
#まとめ
以上GoでDiscordのBotをつくるための手順でした。
あとはドキュメントを見ながらお好みに改造してください!
質問がございましたらコメントにて教えてください。
本記事はあくまでも現状GoでDiscordのBotをつくる日本語の記事がなかったため、至らない部分があることを十分承知した上で書かせていただいたものです。英語の資料やコードを読める方はそちらを読んでいただくほうが賢明かと思います。
何かコードに関して、追加情報等ございましたら、コメントにて教えていただけると大変助かります。
追記
このライブラリにはdiscordのグループがあります。https://discord.gg/0f1SbxBZjYoCtNPP (公用語は英語)
また、このライブラリの作者の方がdgvoiceというライブラリを作られていて、これを使うことでmp3ファイルの音源を通話チャンネルで流すことができます。