diff --git a/api-invites.go b/api-invites.go index 66e97fb..51e2236 100644 --- a/api-invites.go +++ b/api-invites.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "strconv" "strings" @@ -195,43 +196,47 @@ func (app *appContext) GenerateInvite(gc *gin.Context) { invite.UserMinutes = req.UserMinutes } invite.ValidTill = validTill - if req.SendTo != "" && app.config.Section("invite_emails").Key("enabled").MustBool(false) { - addressValid := false - discord := "" - if discordEnabled && (!strings.Contains(req.SendTo, "@") || strings.HasPrefix(req.SendTo, "@")) { - users := app.discord.GetUsers(req.SendTo) - if len(users) == 0 { - invite.SendTo = fmt.Sprintf(lm.FailedSendToTooltipNoUser, req.SendTo) - } else if len(users) > 1 { - invite.SendTo = fmt.Sprintf(lm.FailedSendToTooltipMultiUser, req.SendTo) - } else { - invite.SendTo = req.SendTo - addressValid = true - discord = users[0].User.ID - } - } else if emailEnabled { - addressValid = true - invite.SendTo = req.SendTo - } - if addressValid { - msg, err := app.email.constructInvite(invite.Code, invite, app, false) - if err != nil { - // Slight misuse of the template - invite.SendTo = fmt.Sprintf(lm.FailedConstructInviteMessage, req.SendTo, err) - - app.err.Printf(lm.FailedConstructInviteMessage, invite.Code, err) - } else { - var err error - if discord != "" { - err = app.discord.SendDM(msg, discord) + if req.SendTo != "" { + if !(app.config.Section("invite_emails").Key("enabled").MustBool(false)) { + app.err.Printf(lm.FailedSendInviteMessage, invite.Code, req.SendTo, errors.New(lm.InviteMessagesDisabled)) + } else { + addressValid := false + discord := "" + if discordEnabled && (!strings.Contains(req.SendTo, "@") || strings.HasPrefix(req.SendTo, "@")) { + users := app.discord.GetUsers(req.SendTo) + if len(users) == 0 { + invite.SendTo = fmt.Sprintf(lm.FailedSendToTooltipNoUser, req.SendTo) + } else if len(users) > 1 { + invite.SendTo = fmt.Sprintf(lm.FailedSendToTooltipMultiUser, req.SendTo) } else { - err = app.email.send(msg, req.SendTo) + invite.SendTo = req.SendTo + addressValid = true + discord = users[0].User.ID } + } else if emailEnabled { + addressValid = true + invite.SendTo = req.SendTo + } + if addressValid { + msg, err := app.email.constructInvite(invite.Code, invite, app, false) if err != nil { - invite.SendTo = fmt.Sprintf(lm.FailedSendInviteMessage, invite.Code, req.SendTo, err) - app.err.Println(invite.SendTo) + // Slight misuse of the template + invite.SendTo = fmt.Sprintf(lm.FailedConstructInviteMessage, req.SendTo, err) + + app.err.Printf(lm.FailedConstructInviteMessage, invite.Code, err) } else { - app.info.Printf(lm.SentInviteMessage, invite.Code, req.SendTo) + var err error + if discord != "" { + err = app.discord.SendDM(msg, discord) + } else { + err = app.email.send(msg, req.SendTo) + } + if err != nil { + invite.SendTo = fmt.Sprintf(lm.FailedSendInviteMessage, invite.Code, req.SendTo, err) + app.err.Println(invite.SendTo) + } else { + app.info.Printf(lm.SentInviteMessage, invite.Code, req.SendTo) + } } } } diff --git a/config/config-base.yaml b/config/config-base.yaml index d7f7f1d..2084ec6 100644 --- a/config/config-base.yaml +++ b/config/config-base.yaml @@ -1138,7 +1138,7 @@ sections: type: note depends_true: link_reset required: false - description: Set the "External jfa-go URL" in General so that links to jfa-go can be made. + description: Set the "External jfa-go URL" value in General so that links to jfa-go can be made. - setting: language name: Default reset link language requires_restart: true @@ -1167,9 +1167,9 @@ sections: description: Subject of password reset emails. - section: invite_emails meta: - name: Invite emails + name: Invite Messages description: Settings for sending invites directly to users. - depends_true: email|method + depends_true: messages|enabled settings: - setting: enabled name: Enabled diff --git a/discord.go b/discord.go index df34929..af0d52e 100644 --- a/discord.go +++ b/discord.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "net/http" "strings" @@ -605,6 +606,21 @@ func (d *DiscordDaemon) cmdInvite(s *dg.Session, i *dg.InteractionCreate, lang s requester := 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] = requester recipient := i.ApplicationCommandData().Options[0].UserValue(s) + + // We don't reveal much in the message response itself so we can re-use this easily. + sendResponse := func(langKey string) { + err := s.InteractionRespond(i.Interaction, &dg.InteractionResponse{ + Type: dg.InteractionResponseChannelMessageWithSource, + Data: &dg.InteractionResponseData{ + Content: d.app.storage.lang.Telegram[lang].Strings.get(langKey), + Flags: 64, // Ephemeral + }, + }) + if err != nil { + d.app.err.Printf(lm.FailedReply, lm.Discord, requester.ID, err) + } + } + // d.app.debug.Println(invuser) //label := i.ApplicationCommandData().Options[2].StringValue() //profile := i.ApplicationCommandData().Options[3].StringValue() @@ -615,13 +631,7 @@ func (d *DiscordDaemon) cmdInvite(s *dg.Session, i *dg.InteractionCreate, lang s // We want the same criteria for running this command as accessing the admin page (i.e. an "admin" of some sort) if !(d.app.canAccessAdminPageByID(requester.JellyfinID)) { d.app.err.Printf(lm.FailedGenerateInvite, fmt.Sprintf(lm.NonAdminUser, requester.JellyfinID)) - s.InteractionRespond(i.Interaction, &dg.InteractionResponse{ - Type: dg.InteractionResponseChannelMessageWithSource, - Data: &dg.InteractionResponseData{ - Content: d.app.storage.lang.Telegram[lang].Strings.get("noPermission"), - Flags: 64, // Ephemeral - }, - }) + sendResponse("noPermission") return } @@ -663,54 +673,43 @@ func (d *DiscordDaemon) cmdInvite(s *dg.Session, i *dg.InteractionCreate, lang s } } - if recipient != nil && d.app.config.Section("invite_emails").Key("enabled").MustBool(false) { - invname, err := d.bot.GuildMember(d.guildID, recipient.ID) + if recipient != nil { + err = nil + + var invname *dg.Member = nil + invname, err = d.bot.GuildMember(d.guildID, recipient.ID) invite.SendTo = invname.User.Username - msg, err := d.app.email.constructInvite(invite.Code, invite, d.app, false) - if err != nil { - invite.SendTo = fmt.Sprintf(lm.FailedConstructInviteMessage, invite.Code, err) - d.app.err.Println(invite.SendTo) - err := s.InteractionRespond(i.Interaction, &dg.InteractionResponse{ - Type: dg.InteractionResponseChannelMessageWithSource, - Data: &dg.InteractionResponseData{ - Content: d.app.storage.lang.Telegram[lang].Strings.get("sentInviteFailure"), - Flags: 64, // Ephemeral - }, - }) + + if err == nil && !(d.app.config.Section("invite_emails").Key("enabled").MustBool(false)) { + err = errors.New(lm.InviteMessagesDisabled) + } + + var msg *Message + if err == nil { + msg, err = d.app.email.constructInvite(invite.Code, invite, d.app, false) if err != nil { - d.app.err.Printf(lm.FailedReply, lm.Discord, requester.ID, err) - } - } else { - var err error - err = d.app.discord.SendDM(msg, recipient.ID) - if err != nil { - invite.SendTo = fmt.Sprintf(lm.FailedSendInviteMessage, invite.Code, RenderDiscordUsername(recipient), err) + // Print extra message, ideally we'd just print this, or get rid of it though. + invite.SendTo = fmt.Sprintf(lm.FailedConstructInviteMessage, invite.Code, err) d.app.err.Println(invite.SendTo) - err := s.InteractionRespond(i.Interaction, &dg.InteractionResponse{ - Type: dg.InteractionResponseChannelMessageWithSource, - Data: &dg.InteractionResponseData{ - Content: d.app.storage.lang.Telegram[lang].Strings.get("sentInviteFailure"), - Flags: 64, // Ephemeral - }, - }) - if err != nil { - d.app.err.Printf(lm.FailedReply, lm.Discord, requester.ID, err) - } - } else { - d.app.info.Printf(lm.SentInviteMessage, invite.Code, RenderDiscordUsername(recipient)) - err := s.InteractionRespond(i.Interaction, &dg.InteractionResponse{ - Type: dg.InteractionResponseChannelMessageWithSource, - Data: &dg.InteractionResponseData{ - Content: d.app.storage.lang.Telegram[lang].Strings.get("sentInvite"), - Flags: 64, // Ephemeral - }, - }) - if err != nil { - d.app.err.Printf(lm.FailedReply, lm.Discord, requester.ID, err) - } } } + + if err == nil { + err = d.app.discord.SendDM(msg, recipient.ID) + } + + if err == nil { + d.app.info.Printf(lm.SentInviteMessage, invite.Code, RenderDiscordUsername(recipient)) + sendResponse("sentInvite") + } + + if err != nil { + invite.SendTo = fmt.Sprintf(lm.FailedSendInviteMessage, invite.Code, RenderDiscordUsername(recipient), err) + d.app.err.Println(invite.SendTo) + sendResponse("sentInviteFailure") + } } + //if profile != "" { d.app.storage.SetInvitesKey(invite.Code, invite) } diff --git a/logmessages/logmessages.go b/logmessages/logmessages.go index 5e4c333..160dabe 100644 --- a/logmessages/logmessages.go +++ b/logmessages/logmessages.go @@ -355,6 +355,7 @@ const ( FailedConstructInviteMessage = "Failed to construct invite message for \"%s\": %v" FailedSendInviteMessage = "Failed to send invite message for \"%s\" to \"%s\": %v" SentInviteMessage = "Sent invite message for \"%s\" to \"%s\"" + InviteMessagesDisabled = "invite messages are disabled, check settings" FailedConstructConfirmationEmail = "Failed to construct confirmation email for \"%s\": %v" FailedSendConfirmationEmail = "Failed to send confirmation email for \"%s\" to \"%s\": %v"