Dawid Wysokiński
3fcf38f5c7
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #30
515 lines
14 KiB
Go
515 lines
14 KiB
Go
package discord
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/domain"
|
|
"github.com/bwmarrin/discordgo"
|
|
)
|
|
|
|
type groupCommand struct {
|
|
groupSvc GroupService
|
|
choiceSvc ChoiceService
|
|
}
|
|
|
|
func (c *groupCommand) name() string {
|
|
return "group"
|
|
}
|
|
|
|
func (c *groupCommand) register(s *discordgo.Session) error {
|
|
if err := c.create(s); err != nil {
|
|
return err
|
|
}
|
|
|
|
s.AddHandler(c.handle)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *groupCommand) create(s *discordgo.Session) error {
|
|
versionChoices, err := c.getVersionChoices()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var perm int64 = discordgo.PermissionAdministrator
|
|
dm := false
|
|
|
|
_, err = s.ApplicationCommandCreate(s.State.User.ID, "", &discordgo.ApplicationCommand{
|
|
Name: c.name(),
|
|
Description: "Manages groups on this server",
|
|
DefaultMemberPermissions: &perm,
|
|
DMPermission: &dm,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "create",
|
|
Description: "Creates a new monitor group",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "version",
|
|
Description: "e.g. www.tribalwars.net, www.plemiona.pl",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Choices: versionChoices,
|
|
Required: true,
|
|
},
|
|
{
|
|
Name: "server",
|
|
Description: "Tribal Wars server (e.g. en115, pl170)",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
{
|
|
Name: "channel-gains",
|
|
Description: "Specifies on which channel notifications of gained villages will appear",
|
|
Type: discordgo.ApplicationCommandOptionChannel,
|
|
ChannelTypes: []discordgo.ChannelType{
|
|
discordgo.ChannelTypeGuildText,
|
|
},
|
|
Required: false,
|
|
},
|
|
{
|
|
Name: "channel-losses",
|
|
Description: "Specifies on which channel notifications of lost villages will appear",
|
|
Type: discordgo.ApplicationCommandOptionChannel,
|
|
ChannelTypes: []discordgo.ChannelType{
|
|
discordgo.ChannelTypeGuildText,
|
|
},
|
|
Required: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "list",
|
|
Description: "Lists all created groups",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
},
|
|
{
|
|
Name: "set",
|
|
Description: "Sets various properties in a group configuration",
|
|
Type: discordgo.ApplicationCommandOptionSubCommandGroup,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "channel-gains",
|
|
Description: "Specifies on which channel notifications of gained villages will appear",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "group",
|
|
Description: "Group ID",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
{
|
|
Name: "channel",
|
|
Description: "Channel",
|
|
Type: discordgo.ApplicationCommandOptionChannel,
|
|
ChannelTypes: []discordgo.ChannelType{
|
|
discordgo.ChannelTypeGuildText,
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "channel-losses",
|
|
Description: "Specifies on which channel notifications of lost villages will appear",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "group",
|
|
Description: "Group ID",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
{
|
|
Name: "channel",
|
|
Description: "Channel ID",
|
|
Type: discordgo.ApplicationCommandOptionChannel,
|
|
ChannelTypes: []discordgo.ChannelType{
|
|
discordgo.ChannelTypeGuildText,
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "unset",
|
|
Description: "Unsets various properties in a group configuration",
|
|
Type: discordgo.ApplicationCommandOptionSubCommandGroup,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "channel-gains",
|
|
Description: "Disables notifications of gained villages",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "group",
|
|
Description: "Group ID",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "channel-losses",
|
|
Description: "Disables notifications of lost villages",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "group",
|
|
Description: "Group ID",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "delete",
|
|
Description: "Deletes a group",
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Name: "group",
|
|
Description: "Group ID",
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("s.ApplicationCommandCreate: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *groupCommand) getVersionChoices() ([]*discordgo.ApplicationCommandOptionChoice, error) {
|
|
choices, err := c.choiceSvc.Versions(context.Background())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ChoiceService.Versions: %w", err)
|
|
}
|
|
|
|
dcChoices := make([]*discordgo.ApplicationCommandOptionChoice, 0, len(choices))
|
|
for _, v := range choices {
|
|
dcChoices = append(dcChoices, &discordgo.ApplicationCommandOptionChoice{
|
|
Name: v.Name,
|
|
Value: v.Value,
|
|
})
|
|
}
|
|
|
|
return dcChoices, nil
|
|
}
|
|
|
|
func (c *groupCommand) handle(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
cmdData := i.ApplicationCommandData()
|
|
|
|
if cmdData.Name != c.name() {
|
|
return
|
|
}
|
|
|
|
switch cmdData.Options[0].Name {
|
|
case "create":
|
|
c.handleCreate(s, i)
|
|
return
|
|
case "list":
|
|
c.handleList(s, i)
|
|
return
|
|
case "set":
|
|
c.handleSet(s, i)
|
|
return
|
|
case "unset":
|
|
c.handleUnset(s, i)
|
|
return
|
|
case "delete":
|
|
c.handleDelete(s, i)
|
|
return
|
|
default:
|
|
}
|
|
}
|
|
|
|
func (c *groupCommand) handleCreate(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
version := ""
|
|
server := ""
|
|
channelGains := ""
|
|
channelLosses := ""
|
|
for _, opt := range i.ApplicationCommandData().Options[0].Options {
|
|
if opt == nil {
|
|
continue
|
|
}
|
|
switch opt.Name {
|
|
case "version":
|
|
version = opt.StringValue()
|
|
case "server":
|
|
server = opt.StringValue()
|
|
case "channel-gains":
|
|
channelGains = opt.ChannelValue(s).ID
|
|
case "channel-losses":
|
|
channelLosses = opt.ChannelValue(s).ID
|
|
}
|
|
}
|
|
|
|
params, err := domain.NewCreateGroupParams(
|
|
i.GuildID,
|
|
version,
|
|
server,
|
|
channelGains,
|
|
channelLosses,
|
|
)
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
group, err := c.groupSvc.Create(ctx, params)
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully created (ID=" + group.ID + ")",
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleList(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
groups, err := c.groupSvc.List(ctx, domain.ListGroupsParams{
|
|
ServerIDs: []string{i.GuildID},
|
|
})
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Embeds: []*discordgo.MessageEmbed{
|
|
{
|
|
Type: discordgo.EmbedTypeRich,
|
|
Title: "Group list",
|
|
Description: buildGroupListDescription(groups),
|
|
Timestamp: formatTimestamp(time.Now()),
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleSet(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
switch i.ApplicationCommandData().Options[0].Options[0].Name {
|
|
case "channel-gains":
|
|
c.handleSetChannelGains(s, i)
|
|
return
|
|
case "channel-losses":
|
|
c.handleSetChannelLosses(s, i)
|
|
return
|
|
default:
|
|
}
|
|
}
|
|
|
|
func (c *groupCommand) handleSetChannelGains(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
group := ""
|
|
channel := ""
|
|
for _, opt := range i.ApplicationCommandData().Options[0].Options[0].Options {
|
|
if opt == nil {
|
|
continue
|
|
}
|
|
switch opt.Name {
|
|
case "group":
|
|
group = opt.StringValue()
|
|
case "channel":
|
|
channel = opt.ChannelValue(s).ID
|
|
}
|
|
}
|
|
|
|
_, err := c.groupSvc.SetChannelGains(ctx, group, i.GuildID, channel)
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully updated",
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleSetChannelLosses(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
group := ""
|
|
channel := ""
|
|
for _, opt := range i.ApplicationCommandData().Options[0].Options[0].Options {
|
|
if opt == nil {
|
|
continue
|
|
}
|
|
switch opt.Name {
|
|
case "group":
|
|
group = opt.StringValue()
|
|
case "channel":
|
|
channel = opt.ChannelValue(s).ID
|
|
}
|
|
}
|
|
|
|
_, err := c.groupSvc.SetChannelLosses(ctx, group, i.GuildID, channel)
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully updated",
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleUnset(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
switch i.ApplicationCommandData().Options[0].Options[0].Name {
|
|
case "channel-gains":
|
|
c.handleUnsetChannelGains(s, i)
|
|
return
|
|
case "channel-losses":
|
|
c.handleUnsetChannelLosses(s, i)
|
|
return
|
|
default:
|
|
}
|
|
}
|
|
|
|
func (c *groupCommand) handleUnsetChannelGains(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
group := i.ApplicationCommandData().Options[0].Options[0].Options[0].StringValue()
|
|
_, err := c.groupSvc.SetChannelGains(ctx, group, i.GuildID, "")
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully updated",
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleUnsetChannelLosses(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
group := i.ApplicationCommandData().Options[0].Options[0].Options[0].StringValue()
|
|
_, err := c.groupSvc.SetChannelLosses(ctx, group, i.GuildID, "")
|
|
if err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully updated",
|
|
},
|
|
})
|
|
}
|
|
|
|
func (c *groupCommand) handleDelete(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
ctx := context.Background()
|
|
|
|
group := i.ApplicationCommandData().Options[0].Options[0].StringValue()
|
|
if err := c.groupSvc.Delete(ctx, group, i.GuildID); err != nil {
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: messageFromError(err),
|
|
},
|
|
})
|
|
return
|
|
}
|
|
|
|
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
Data: &discordgo.InteractionResponseData{
|
|
Content: "group has been successfully deleted",
|
|
},
|
|
})
|
|
}
|
|
|
|
func buildGroupListDescription(groups []domain.Group) string {
|
|
description := "**ID** - **Server** - **Channel gains** - **Channel losses**"
|
|
for i, g := range groups {
|
|
channelGains := "Not set"
|
|
if g.ChannelGains != "" {
|
|
channelGains = "<#" + g.ChannelGains + ">"
|
|
}
|
|
channelLosses := "Not set"
|
|
if g.ChannelLosses != "" {
|
|
channelLosses = "<#" + g.ChannelLosses + ">"
|
|
}
|
|
description += fmt.Sprintf(
|
|
"\n%d. %s - %s - %s - %s",
|
|
i+1,
|
|
g.ID,
|
|
g.ServerKey,
|
|
channelGains,
|
|
channelLosses,
|
|
)
|
|
}
|
|
return description
|
|
}
|