🤖
【Go】Discordのbotにボタンをつける方法(ERROR: UNION_TYPE_CHOICESでハマった話)
discordのbotで、ボタンを付けるのにかなり苦戦したので、記録として残しておきます。
より良い方法があれば、コメントで教えていただけると嬉しいです。
使用するライブラリ
結論
最初に動いたコードを載せておきます。
btn
という文字列を入力すると
- タイトル
- 本文
- ボタン
を返してくれるbotです。
※ボタンは押しても何も起こりません。
package main
import (
"fmt"
"github.com/bwmarrin/discordgo"
"github.com/joho/godotenv"
"log"
"os"
"os/signal"
"syscall"
)
func main() {
if err := godotenv.Load(".env"); err != nil {
log.Fatal(fmt.Sprintf(".envを読み込めません: %v", err))
}
var Token = "Bot " + os.Getenv("APP_BOT_TOKEN")
session, err := discordgo.New(Token)
session.Token = Token
if err != nil {
log.Fatalln(err)
}
//イベントハンドラを追加
session.AddHandler(Handler)
if err = session.Open(); err != nil {
log.Fatalln(err)
}
defer func() {
if err = session.Close(); err != nil {
log.Fatalln(err)
}
return
}()
stopBot := make(chan os.Signal, 1)
signal.Notify(stopBot, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-stopBot
return
}
func Handler(s *discordgo.Session, m *discordgo.MessageCreate) {
const CMD = "btn"
if m.Content != CMD {
return
}
// ボタン付きのメッセージを送信
{
btn := discordgo.Button{
Label: "ラベル",
Style: discordgo.PrimaryButton,
CustomID: "abcd",
}
actions := discordgo.ActionsRow{
Components: []discordgo.MessageComponent{btn},
}
embed := &discordgo.MessageEmbed{
Title: "タイトル",
Description: "本文",
}
data := &discordgo.MessageSend{
Components: []discordgo.MessageComponent{actions},
Embed: embed,
}
_, err := s.ChannelMessageSendComplex(m.ChannelID, data)
if err != nil {
log.Fatalln(err)
}
}
}
どこでハマったか?
ハマった原因としては、data
のComponents
スライスに直接btn
を入れており、actions
を噛ませることをしていなかったからです。
// ここです
actions := discordgo.ActionsRow{
Components: []discordgo.MessageComponent{btn},
}
これをしないと、以下のようなエラーが発生し、typeが1以外はNGだと怒られます。
型としてはButton型を直接MessageComponent型のスライスに入れることは可能ですが、actions
を噛ませることが重要です。
2022/10/07 01:03:30 HTTP 400 Bad Request, {"code": 50035, "errors": {"components": {"0": {"_errors": [{"code": "UNION_TYPE_CHOICES", "message": "Value of field \"type\" must be one of (1,)."}]}}}, "message": "Invalid Form Body"}
(追記)ボタンクリックで返信を表示
ボタンがクリックされたら、クリックした人しか見られないメッセージを送信するコードを書きましたので、追記します。
session.AddHandler(InteractionHandler)
のような感じで、ハンドラを追加して使用します。
func InteractionHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
if i.MessageComponentData().CustomID == "abcd" {
resp := &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Flags: discordgo.MessageFlagsEphemeral,
Content: "レスポンスです",
},
}
if err := s.InteractionRespond(i.Interaction, resp); err != nil {
log.Fatalln(err)
}
}
}
以上
Discussion