206 lines
5.8 KiB
Go
206 lines
5.8 KiB
Go
package public
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"velox-bot/internal/db/services"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
)
|
|
|
|
var Config = &discordgo.ApplicationCommand{
|
|
Name: "config",
|
|
Description: "Server configuration",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: "addstreamer",
|
|
Description: "Add a Twitch streamer for live notifications",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Name: "username",
|
|
Description: "Twitch username (without https://)",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: "removestreamer",
|
|
Description: "Remove a Twitch streamer from live notifications",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Name: "username",
|
|
Description: "Twitch username to remove",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: "settwitchnotificationchannel",
|
|
Description: "Set the channel for Twitch live notifications",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionChannel,
|
|
Name: "channel",
|
|
Description: "Text channel for notifications",
|
|
Required: true,
|
|
ChannelTypes: []discordgo.ChannelType{discordgo.ChannelTypeGuildText, discordgo.ChannelTypeGuildNews},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
func ConfigHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
if i.GuildID == "" {
|
|
respondEphemeral(s, i, "This command can only be used in a server.")
|
|
return
|
|
}
|
|
if i.Member == nil || (i.Member.Permissions&discordgo.PermissionManageGuild) == 0 {
|
|
respondEphemeral(s, i, "You need the **Manage Server** permission to use this.")
|
|
return
|
|
}
|
|
if services.Global == nil || services.Global.Twitch == nil {
|
|
respondEphemeral(s, i, "Twitch configuration is not available.")
|
|
return
|
|
}
|
|
|
|
data := i.ApplicationCommandData()
|
|
if len(data.Options) == 0 {
|
|
respondEphemeral(s, i, "Missing subcommand.")
|
|
return
|
|
}
|
|
|
|
switch data.Options[0].Name {
|
|
case "addstreamer":
|
|
log.Printf("twitch: /config addstreamer invoked by %s in guild %s", i.Member.User.ID, i.GuildID)
|
|
handleAddStreamer(s, i)
|
|
case "removestreamer":
|
|
log.Printf("twitch: /config removestreamer invoked by %s in guild %s", i.Member.User.ID, i.GuildID)
|
|
handleRemoveStreamer(s, i)
|
|
case "settwitchnotificationchannel":
|
|
log.Printf("twitch: /config settwitchnotificationchannel invoked by %s in guild %s", i.Member.User.ID, i.GuildID)
|
|
handleSetChannel(s, i)
|
|
default:
|
|
respondEphemeral(s, i, "Unknown subcommand.")
|
|
}
|
|
}
|
|
|
|
func handleAddStreamer(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
|
if err != nil {
|
|
respondEphemeral(s, i, "Invalid guild ID.")
|
|
return
|
|
}
|
|
|
|
opt := i.ApplicationCommandData().Options[0]
|
|
var username string
|
|
for _, o := range opt.Options {
|
|
if o.Name == "username" {
|
|
username = strings.TrimSpace(o.StringValue())
|
|
}
|
|
}
|
|
username = strings.TrimPrefix(username, "https://www.twitch.tv/")
|
|
username = strings.TrimPrefix(username, "http://www.twitch.tv/")
|
|
username = strings.TrimPrefix(username, "twitch.tv/")
|
|
username = strings.TrimSpace(username)
|
|
|
|
if username == "" {
|
|
respondEphemeral(s, i, "Username cannot be empty.")
|
|
return
|
|
}
|
|
|
|
if err := services.Global.Twitch.UpsertStreamer(context.Background(), guildID, username); err != nil {
|
|
respondEphemeral(s, i, "Failed to add streamer.")
|
|
return
|
|
}
|
|
|
|
respondEphemeral(s, i, "Added `"+username+"` for Twitch live notifications.")
|
|
}
|
|
|
|
func handleRemoveStreamer(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
|
if err != nil {
|
|
respondEphemeral(s, i, "Invalid guild ID.")
|
|
return
|
|
}
|
|
|
|
opt := i.ApplicationCommandData().Options[0]
|
|
var username string
|
|
for _, o := range opt.Options {
|
|
if o.Name == "username" {
|
|
username = strings.TrimSpace(o.StringValue())
|
|
}
|
|
}
|
|
username = strings.TrimSpace(username)
|
|
if username == "" {
|
|
respondEphemeral(s, i, "Username cannot be empty.")
|
|
return
|
|
}
|
|
|
|
if err := services.Global.Twitch.RemoveStreamer(context.Background(), guildID, username); err != nil {
|
|
respondEphemeral(s, i, "Failed to remove streamer.")
|
|
return
|
|
}
|
|
|
|
respondEphemeral(s, i, "Removed `"+username+"` from Twitch live notifications.")
|
|
}
|
|
|
|
func handleSetChannel(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
guildID, err := strconv.ParseInt(i.GuildID, 10, 64)
|
|
if err != nil {
|
|
respondEphemeral(s, i, "Invalid guild ID.")
|
|
return
|
|
}
|
|
|
|
opt := i.ApplicationCommandData().Options[0]
|
|
var chOpt *discordgo.ApplicationCommandInteractionDataOption
|
|
for _, o := range opt.Options {
|
|
if o.Name == "channel" {
|
|
chOpt = o
|
|
break
|
|
}
|
|
}
|
|
if chOpt == nil {
|
|
respondEphemeral(s, i, "Missing channel option.")
|
|
return
|
|
}
|
|
|
|
ch := chOpt.ChannelValue(s)
|
|
if ch == nil {
|
|
respondEphemeral(s, i, "Invalid channel.")
|
|
return
|
|
}
|
|
|
|
chID, err := strconv.ParseInt(ch.ID, 10, 64)
|
|
if err != nil {
|
|
respondEphemeral(s, i, "Invalid channel ID.")
|
|
return
|
|
}
|
|
|
|
if err := services.Global.Twitch.SetNotificationChannel(context.Background(), guildID, chID); err != nil {
|
|
respondEphemeral(s, i, "Failed to set notification channel.")
|
|
return
|
|
}
|
|
|
|
respondEphemeral(s, i, "Twitch notifications will be sent to "+ch.Mention()+".")
|
|
}
|
|
|
|
func respondEphemeral(s *discordgo.Session, i *discordgo.InteractionCreate, msg string) {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: msg,
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
},
|
|
})
|
|
}
|
|
|