diff --git a/discord.go b/discord.go index 8efd8fe..fd3de07 100644 --- a/discord.go +++ b/discord.go @@ -3,9 +3,11 @@ package main import ( "fmt" "strings" + "strconv" "time" dg "github.com/bwmarrin/discordgo" + "github.com/lithammer/shortuuid/v3" "github.com/timshannon/badgerhold/v4" ) @@ -50,6 +52,7 @@ func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) { dd.commandHandlers[app.config.Section("discord").Key("start_command").MustString("start")] = dd.cmdStart dd.commandHandlers["lang"] = dd.cmdLang dd.commandHandlers["pin"] = dd.cmdPIN + dd.commandHandlers["inv"] = dd.cmdInvite for _, user := range app.storage.GetDiscord() { dd.users[user.ID] = user } @@ -127,6 +130,7 @@ func (d *DiscordDaemon) run() { d.inviteChannelName = invChannel } } + err = d.bot.UpdateGameStatus(0, "/"+d.app.config.Section("discord").Key("start_command").MustString("start")) defer d.deregisterCommands() defer d.bot.Close() @@ -338,6 +342,36 @@ func (d *DiscordDaemon) registerCommands() { }, }, }, + { + Name: "inv", + Description: "Send an invite to a discord user (admin only).", + Options: []*dg.ApplicationCommandOption{ + { + Type: dg.ApplicationCommandOptionUser, + Name: "user", + Description: "User to Invite", + Required: true, + }, // running with just one option for now to mesh with what we've got, also may have the syntax wrong here + /*{ + Type: dg.ApplicationCommandOptionInteger, + Name: "expire after", + Description: "Time in minutes before expiration", + Required: false, + }, + { + Type: dg.ApplicationCommandOptionString, + Name: "label", + Description: "Label to apply to the user created with this invite", + Required: false, + }, + { + Type: dg.ApplicationCommandOptionString, + Name: "profile", + Description: "Profile to apply to the user created with this invite", + Required: false, + }, */ + }, + }, } commands[1].Options[0].Choices = make([]*dg.ApplicationCommandOptionChoice, len(d.app.storage.lang.Telegram)) i := 0 @@ -503,6 +537,86 @@ func (d *DiscordDaemon) cmdLang(s *dg.Session, i *dg.InteractionCreate, lang str } } +func (d *DiscordDaemon) cmdInvite(s *dg.Session, i *dg.InteractionCreate, lang string) { + channel, err := s.UserChannelCreate(i.Interaction.Member.User.ID) + requestor := d.MustGetUser(channel.ID, i.Interaction.Member.User.ID, i.Interaction.Member.User.Discriminator, i.Interaction.Member.User.Username) + d.users[i.Interaction.Member.User.ID] = requestor + invuser := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Value) + d.app.debug.Println(invuser) + //label := i.ApplicationCommandData().Options[2].StringValue() + //profile := i.ApplicationCommandData().Options[3].StringValue() + //mins, err := strconv.Atoi(i.ApplicationCommandData().Options[1].StringValue()) + expmin := 30 + //if mins > 0 { + // expmin = mins + //} + // Check whether requestor is linked to the admin account + requestoremail, ok := d.app.storage.GetEmailsKey(requestor.JellyfinID) + if !ok { + d.app.err.Printf("Failed to verify admin") + } + if !requestoremail.Admin { + d.app.err.Printf("User is not admin") + //add response message + return + } + // variation of app.GenerateInvite, some parts commented to potentially add back in later with the other command options + //d.app.debug.Println("Generating new invite with options: %s: %i: %s: %s", invuser, expmin, profile, label) + currentTime := time.Now() + validTill := currentTime.Add(time.Minute*time.Duration(expmin)) + // make sure code doesn't begin with number + inviteCode := shortuuid.New() + _, err = strconv.Atoi(string(inviteCode[0])) + for err == nil { + inviteCode = shortuuid.New() + _, err = strconv.Atoi(string(inviteCode[0])) + } + var invite Invite + //if label != "" { + // invite.Label = label + //} + invite.Created = currentTime + invite.RemainingUses = 1 + invite.UserExpiry = false + /*if invite.UserExpiry { + invite.UserMonths = req.UserMonths + invite.UserDays = req.UserDays + invite.UserHours = req.UserHours + invite.UserMinutes = req.UserMinutes + }*/ + invite.ValidTill = validTill + if invuser != "" && d.app.config.Section("invite_emails").Key("enabled").MustBool(false) { + d.app.debug.Printf("%s: Sending invite message", inviteCode) + invname, err := d.bot.GuildMember(d.guildID, invuser) + invite.SendTo = invname.User.Username + msg, err := d.app.email.constructInvite(inviteCode, invite, d.app, false) + if err != nil { + invite.SendTo = fmt.Sprintf("Failed to send to %s", invuser) + d.app.err.Printf("%s: Failed to construct invite message: %v", inviteCode, err) + //add response message + } else { + var err error + err = d.app.discord.SendDM(msg, invuser) + if err != nil { + invite.SendTo = fmt.Sprintf("Failed to send to %s", invuser) + d.app.err.Printf("%s: %s: %v", inviteCode, invite.SendTo, err) + //add response message + } else { + d.app.info.Printf("%s: Sent invite email to \"%s\"", inviteCode, invuser) + //add response message + } + } + } + //if profile != "" { + // if _, ok := d.app.storage.GetProfileKey(profile); ok { + // invite.Profile = profile + // } else { + // invite.Profile = "Default" + // } + //} + d.app.storage.SetInvitesKey(inviteCode, invite) +} + func (d *DiscordDaemon) messageHandler(s *dg.Session, m *dg.MessageCreate) { if m.GuildID != "" && d.channelName != "" { if d.channelID == "" {