Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
feat: add commands for paintball registeration and display
Browse files Browse the repository at this point in the history
  • Loading branch information
yechentide committed Oct 16, 2023
1 parent f8b87af commit eadbfc0
Show file tree
Hide file tree
Showing 12 changed files with 590 additions and 0 deletions.
61 changes: 61 additions & 0 deletions bot/bot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package bot

import (
"fmt"
"log/slog"
"os"
"os/signal"
"syscall"

"github.com/bwmarrin/discordgo"
"github.com/yechentide/mhnow-bot/config"
)

func Run() {
slog.Info("Botを起動しています ...")
discord, err := discordgo.New(config.GetBotToken())
if err != nil {
slog.Error("Botの初期化に失敗しました", "error", err)
os.Exit(1)
}

discord.AddHandler(onMessageCreate)
discord.AddHandler(onMessageUpdate)
discord.AddHandler(onMessageDelete)

discord.AddHandler(onMessageReactionAdd)
discord.AddHandler(onMessageReactionRemove)
discord.AddHandler(onMessageReactionRemoveAll)

discord.AddHandler(onInteractionCreated)

err = discord.Open()
if err != nil {
slog.Error("Botのログインに失敗しました", "error", err)
os.Exit(1)
}

defer func() {
discord.Close()
fmt.Println("")
slog.Info("Botを終了しました")
}()

for _, guild := range discord.State.Guilds {
RegisterCommands(discord, guild.ID)
}

slog.Info("========== ========== ========== Monster Hunter Now - Discord Bot ========== ========== ==========")
stopBot := make(chan os.Signal, 1)
signal.Notify(stopBot, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, syscall.SIGTERM)
<-stopBot
}

/*
GuildMemberAdd
GuildMemberUpdate
GuildMemberRemove
GuildEmojisUpdate
UserUpdate
MessageDeleteBulk
*/
37 changes: 37 additions & 0 deletions bot/handle-Interaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package bot

import (
"fmt"
"log/slog"

"github.com/bwmarrin/discordgo"
cmds "github.com/yechentide/mhnow-bot/commands"
)

func onInteractionCreated(s *discordgo.Session, i *discordgo.InteractionCreate) {
switch i.Type {
case discordgo.InteractionApplicationCommand:
slog.Debug("Interaction Created", "Command", i)
commandHandler(s, i)
case discordgo.InteractionMessageComponent:
slog.Debug("Interaction Created", "MessageComponent", i)
case discordgo.InteractionModalSubmit:
slog.Debug("Interaction Created", "ModalSubmit", i)
default:
slog.Debug("Interaction Created", i.Type, i)
}
}

func commandHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
hunterName := i.Member.Nick
if len(hunterName) == 0 {
hunterName = i.Member.User.Username
}
slog.Info(fmt.Sprintf("%s がコマンド %s を実行しました", hunterName, i.ApplicationCommandData().Name))
switch i.ApplicationCommandData().Name {
case "paint":
cmds.PaintHandler(s, i)
case "paint-list":
cmds.PaintListHandler(s, i)
}
}
81 changes: 81 additions & 0 deletions bot/handle-message-reaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package bot

import (
"fmt"
"log/slog"

"github.com/bwmarrin/discordgo"
)

/*
MessageReactionAdd
MessageReactionRemove
MessageReactionRemoveAll
*/

func onMessageReactionAdd(s *discordgo.Session, r *discordgo.MessageReactionAdd) {
snowflake := r.Emoji.Name + ":" + r.Emoji.ID
if r.GuildID == "" {
slog.Debug(fmt.Sprintf(
"Direct reaction added: Channel=%s, Guild=%s, MessageID=%s, Emoji=%s",
r.ChannelID,
r.GuildID,
r.MessageID,
snowflake,
))
} else {
slog.Debug(fmt.Sprintf(
"Guild reaction added: Channel=%s, Guild=%s, Author=%s(%s)_%-20s, MessageID=%s, Emoji=%s",
r.ChannelID,
r.GuildID,
r.Member.User.Username,
r.Member.Nick,
r.Member.User.ID,
r.MessageID,
snowflake,
))
}
}

func onMessageReactionRemove(s *discordgo.Session, r *discordgo.MessageReactionRemove) {
snowflake := r.Emoji.Name + ":" + r.Emoji.ID
if r.GuildID == "" {
slog.Debug(fmt.Sprintf(
"Direct reaction removed: Channel=%s, Guild=%s, User=%s, MessageID=%s, Emoji=%s",
r.ChannelID,
r.GuildID,
r.UserID,
r.MessageID,
snowflake,
))
} else {
slog.Debug(fmt.Sprintf(
"Guild reaction removed: Channel=%s, Guild=%s, User=%s, MessageID=%s, Emoji=%s",
r.ChannelID,
r.GuildID,
r.UserID,
r.MessageID,
snowflake,
))
}
}

func onMessageReactionRemoveAll(s *discordgo.Session, r *discordgo.MessageReactionRemoveAll) {
if r.GuildID == "" {
slog.Debug(fmt.Sprintf(
"All direct reaction removed: Channel=%s, Guild=%s, User=%s, MessageID=%s",
r.ChannelID,
r.GuildID,
r.UserID,
r.MessageID,
))
} else {
slog.Debug(fmt.Sprintf(
"All guild reaction removed: Channel=%s, Guild=%s, User=%s, MessageID=%s",
r.ChannelID,
r.GuildID,
r.UserID,
r.MessageID,
))
}
}
69 changes: 69 additions & 0 deletions bot/handle-message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package bot

import (
"fmt"
"log/slog"

"github.com/bwmarrin/discordgo"
)

/*
MessageCreate
MessageUpdate
MessageDelete
*/

func isBotMentionedInMessage(s *discordgo.Session, mentions []*discordgo.User) bool {
for _, mention := range mentions {
if mention.ID == s.State.User.ID {
return true
}
}
return false
}

func onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.GuildID == "" {
onDirectMessageCreated(s, m)
} else if isBotMentionedInMessage(s, m.Mentions) {
onGuildMessageCreated(s, m)
}
}

func onMessageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) {
if !isBotMentionedInMessage(s, m.Mentions) {
return
}
slog.Info(fmt.Sprintf(
"Message updated: Channel=%s, Guild=%s, Author=%s_%-20s\n%s",
m.ChannelID,
m.GuildID,
m.Author.Username,
m.Author.ID,
m.Content,
))
}

func onMessageDelete(s *discordgo.Session, m *discordgo.MessageDelete) {}

func onGuildMessageCreated(s *discordgo.Session, m *discordgo.MessageCreate) {
slog.Info(fmt.Sprintf(
"Guild message created: Channel=%s, Guild=%s, Author=%s(%s)_%-20s\n%s",
m.ChannelID,
m.GuildID,
m.Author.Username,
m.Member.Nick,
m.Author.ID,
m.Content,
))
}

func onDirectMessageCreated(s *discordgo.Session, m *discordgo.MessageCreate) {
slog.Info(fmt.Sprintf(
"Direct message created: Channel=%s, Author=%s_%-20s\n%s",
m.ChannelID,
m.Author.Username,
m.Author.ID,
m.Content,
))
}
41 changes: 41 additions & 0 deletions bot/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package bot

import (
"fmt"

"github.com/bwmarrin/discordgo"
)

func SendMessage(s *discordgo.Session, channelID string, msg string) {
_, err := s.ChannelMessageSend(channelID, msg)
fmt.Println(">>> " + msg)
if err != nil {
fmt.Println("Error sending message: ", err)
}
}

func SendReply(s *discordgo.Session, channelID string, reference *discordgo.MessageReference, msg string) {
_, err := s.ChannelMessageSendReply(channelID, msg, reference)
if err != nil {
fmt.Println("Error sending message: ", err)
}
}

func SendEmbedMessage(s *discordgo.Session, channelID, title, desc string, color int) {
embed := &discordgo.MessageEmbed{
Title: title,
Description: desc,
Color: color,
}
_, err := s.ChannelMessageSendEmbed(channelID, embed)
if err != nil {
fmt.Println("Error sending embed message: ", err)
}
}

func SendReaction(s *discordgo.Session, channelID, messageID, reaction string) {
err := s.MessageReactionAdd(channelID, messageID, reaction)
if err != nil {
fmt.Println("Error add a reaction: ", err)
}
}
26 changes: 26 additions & 0 deletions bot/register-cmds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package bot

import (
"fmt"
"log/slog"

"github.com/bwmarrin/discordgo"
cmds "github.com/yechentide/mhnow-bot/commands"
)

func RegisterCommands(s *discordgo.Session, guildId string) {
registerMessage := fmt.Sprintf("Registering commands for guild %s ...", guildId)
slog.Info(registerMessage)

paintListCmd := cmds.PaintListCommand()
paintCmd, err := cmds.PaintCommand()
if err != nil {
panic(err)
}
_, err = s.ApplicationCommandBulkOverwrite(s.State.User.ID, guildId, []*discordgo.ApplicationCommand{
paintListCmd, paintCmd,
})
if err != nil {
panic(err)
}
}
17 changes: 17 additions & 0 deletions commands/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package commands

import (
"github.com/bwmarrin/discordgo"
)

func sendInteractionRespondMessage(s *discordgo.Session, i *discordgo.InteractionCreate, message string) {
s.InteractionRespond(
i.Interaction,
&discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: message,
},
},
)
}
56 changes: 56 additions & 0 deletions commands/paint-list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package commands

import (
"fmt"

"github.com/bwmarrin/discordgo"
"github.com/yechentide/mhnow-bot/dao"
"github.com/yechentide/mhnow-bot/utils"
)

func PaintListCommand() *discordgo.ApplicationCommand {
return &discordgo.ApplicationCommand{
Type: 1,
Name: "paint-list",
Description: "消滅していないモンスターの一覧を表示します",
}
}

func PaintListHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
query := dao.New(dao.GetDb())
monsters, err := query.FindHuntableMontersWithGuild(dao.GetCtx())
if err != nil {
sendInteractionRespondMessage(s, i, "データの取得に失敗しました")
return
}

msg := ""
if len(monsters) == 0 {
msg = "消滅していないモンスターの一覧はありません"
sendInteractionRespondMessage(s, i, msg)
return
}

emojiMap := utils.GenerateGuildEmojiMap(s, i.GuildID)
for _, monster := range monsters {
monsterName := monster.MonsterJpName
snowflake, ok := (*emojiMap)[monster.MonsterID]
if ok {
monsterName = snowflake
}
jstTime := monster.DisappearAt.Format("01/02_15:04")
location := monster.Location.String
if location == "" {
location = "???"
}
msg += fmt.Sprintf(
"## %s(R%d) *%s*まで\n> %sが%sで発見した\n",
monsterName,
monster.Rank,
jstTime,
monster.HunterName,
location,
)
}
sendInteractionRespondMessage(s, i, msg)
}
Loading

0 comments on commit eadbfc0

Please sign in to comment.