diff --git a/api-jellyseerr.go b/api-jellyseerr.go index 3a5da5c..897e9b1 100644 --- a/api-jellyseerr.go +++ b/api-jellyseerr.go @@ -6,6 +6,7 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/hrfee/jfa-go/common" "github.com/hrfee/jfa-go/jellyseerr" lm "github.com/hrfee/jfa-go/logmessages" ) @@ -124,29 +125,62 @@ func (js *JellyseerrWrapper) ImportUser(jellyfinID string, req newUserDTO, profi return } -func (js *JellyseerrWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) { +func (js *JellyseerrWrapper) SetContactMethods(jellyfinID string, email *string, discord *DiscordUser, telegram *TelegramUser, contactPrefs *common.ContactPreferences) (err error) { _, err = js.MustGetUser(jellyfinID) if err != nil { return } - contactMethods := map[jellyseerr.NotificationsField]any{} - if emailEnabled { - err = js.ModifyMainUserSettings(jellyfinID, jellyseerr.MainUserSettings{Email: req.Email}) - if err != nil { - // FIXME: This is a little ugly, considering all other errors are unformatted - err = fmt.Errorf(lm.FailedSetEmailAddress, lm.Jellyseerr, jellyfinID, err) - return - } else { - contactMethods[jellyseerr.FieldEmailEnabled] = req.EmailContact + if contactPrefs == nil { + contactPrefs = &common.ContactPreferences{ + Email: nil, + Discord: nil, + Telegram: nil, + Matrix: nil, } } - if discordEnabled && discord != nil { - contactMethods[jellyseerr.FieldDiscord] = discord.ID - contactMethods[jellyseerr.FieldDiscordEnabled] = req.DiscordContact + contactMethods := map[jellyseerr.NotificationsField]any{} + if emailEnabled { + if contactPrefs.Email != nil { + contactMethods[jellyseerr.FieldEmailEnabled] = *(contactPrefs.Email) + } else if email != nil && *email != "" { + contactMethods[jellyseerr.FieldEmailEnabled] = true + } + if email != nil { + err = js.ModifyMainUserSettings(jellyfinID, jellyseerr.MainUserSettings{Email: *email}) + if err != nil { + // FIXME: This is a little ugly, considering all other errors are unformatted + err = fmt.Errorf(lm.FailedSetEmailAddress, lm.Jellyseerr, jellyfinID, err) + return + } + } } - if telegramEnabled && telegram != nil { - contactMethods[jellyseerr.FieldTelegram] = telegram.ChatID - contactMethods[jellyseerr.FieldTelegramEnabled] = req.TelegramContact + if discordEnabled { + if contactPrefs.Discord != nil { + contactMethods[jellyseerr.FieldDiscordEnabled] = *(contactPrefs.Discord) + } else if discord != nil && discord.ID != "" { + contactMethods[jellyseerr.FieldDiscordEnabled] = true + } + if discord != nil { + contactMethods[jellyseerr.FieldDiscord] = discord.ID + // Whether this is still necessary or not, i don't know. + if discord.ID == "" { + contactMethods[jellyseerr.FieldDiscord] = jellyseerr.BogusIdentifier + } + } + } + if telegramEnabled { + if contactPrefs.Telegram != nil { + contactMethods[jellyseerr.FieldTelegramEnabled] = *(contactPrefs.Telegram) + } else if telegram != nil && telegram.ChatID != 0 { + contactMethods[jellyseerr.FieldTelegramEnabled] = true + } + if telegram != nil { + contactMethods[jellyseerr.FieldTelegram] = telegram.ChatID + // Whether this is still necessary or not, i don't know. + if telegram.ChatID == 0 { + contactMethods[jellyseerr.FieldTelegram] = jellyseerr.BogusIdentifier + } + } } if len(contactMethods) > 0 { err = js.ModifyNotifications(jellyfinID, contactMethods) diff --git a/api-messages.go b/api-messages.go index ddebd92..0abc4e6 100644 --- a/api-messages.go +++ b/api-messages.go @@ -4,7 +4,7 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/hrfee/jfa-go/jellyseerr" + "github.com/hrfee/jfa-go/common" lm "github.com/hrfee/jfa-go/logmessages" "github.com/lithammer/shortuuid/v3" "gopkg.in/ini.v1" @@ -263,21 +263,21 @@ func (app *appContext) TelegramAddUser(gc *gin.Context) { } app.storage.SetTelegramKey(req.ID, tgUser) - if err := app.js.ModifyNotifications(gc.GetString("jfId"), map[jellyseerr.NotificationsField]any{ - jellyseerr.FieldTelegram: tgUser.ChatID, - jellyseerr.FieldTelegramEnabled: tgUser.Contact, - }); err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(req.ID, nil, nil, &tgUser, &common.ContactPreferences{ + Telegram: &tgUser.Contact, + }); err != nil { + app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) + } } - linkExistingOmbiDiscordTelegram(app) app.InvalidateWebUserCache() respondBool(200, true, gc) } // @Summary Sets whether to notify a user through telegram/discord/matrix/email or not. // @Produce json -// @Param SetContactMethodsDTO body SetContactMethodsDTO true "User's Jellyfin ID and whether or not to notify then through Telegram." +// @Param SetContactPreferencesDTO body SetContactPreferencesDTO true "User's Jellyfin ID and whether or not to notify then through Telegram." // @Success 200 {object} boolResponse // @Success 400 {object} boolResponse // @Success 500 {object} boolResponse @@ -285,24 +285,24 @@ func (app *appContext) TelegramAddUser(gc *gin.Context) { // @Security Bearer // @tags Other func (app *appContext) SetContactMethods(gc *gin.Context) { - var req SetContactMethodsDTO + var req SetContactPreferencesDTO gc.BindJSON(&req) if req.ID == "" { respondBool(400, false, gc) return } - app.setContactMethods(req, gc) + app.setContactPreferences(req, gc) } -func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Context) { - jsPrefs := map[jellyseerr.NotificationsField]any{} +func (app *appContext) setContactPreferences(req SetContactPreferencesDTO, gc *gin.Context) { + contactPrefs := common.ContactPreferences{} if tgUser, ok := app.storage.GetTelegramKey(req.ID); ok { change := tgUser.Contact != req.Telegram tgUser.Contact = req.Telegram app.storage.SetTelegramKey(req.ID, tgUser) if change { app.debug.Printf(lm.SetContactPrefForService, lm.Telegram, tgUser.Username, req.Telegram) - jsPrefs[jellyseerr.FieldTelegramEnabled] = req.Telegram + contactPrefs.Telegram = &req.Telegram } } if dcUser, ok := app.storage.GetDiscordKey(req.ID); ok { @@ -311,7 +311,7 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.storage.SetDiscordKey(req.ID, dcUser) if change { app.debug.Printf(lm.SetContactPrefForService, lm.Discord, dcUser.Username, req.Discord) - jsPrefs[jellyseerr.FieldDiscordEnabled] = req.Discord + contactPrefs.Discord = &req.Discord } } if mxUser, ok := app.storage.GetMatrixKey(req.ID); ok { @@ -320,6 +320,7 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.storage.SetMatrixKey(req.ID, mxUser) if change { app.debug.Printf(lm.SetContactPrefForService, lm.Matrix, mxUser.UserID, req.Matrix) + contactPrefs.Matrix = &req.Matrix } } if email, ok := app.storage.GetEmailsKey(req.ID); ok { @@ -328,13 +329,13 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.storage.SetEmailsKey(req.ID, email) if change { app.debug.Printf(lm.SetContactPrefForService, lm.Email, email.Addr, req.Email) - jsPrefs[jellyseerr.FieldEmailEnabled] = req.Email + contactPrefs.Email = &req.Email } } - if app.config.Section("jellyseerr").Key("enabled").MustBool(false) { - err := app.js.ModifyNotifications(req.ID, jsPrefs) - if err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) + + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(req.ID, nil, nil, nil, &contactPrefs); err != nil { + app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) } } app.InvalidateWebUserCache() @@ -621,11 +622,12 @@ func (app *appContext) DiscordConnect(gc *gin.Context) { app.storage.SetDiscordKey(req.JellyfinID, user) - if err := app.js.ModifyNotifications(req.JellyfinID, map[jellyseerr.NotificationsField]any{ - jellyseerr.FieldDiscord: req.DiscordID, - jellyseerr.FieldDiscordEnabled: true, - }); err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(req.JellyfinID, nil, &user, nil, &common.ContactPreferences{ + Discord: &user.Contact, + }); err != nil { + app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) + } } app.storage.SetActivityKey(shortuuid.New(), Activity{ @@ -659,12 +661,14 @@ func (app *appContext) UnlinkDiscord(gc *gin.Context) { } */ app.storage.DeleteDiscordKey(req.ID) - // FIXME: Use thirdPartyServices for this - if err := app.js.ModifyNotifications(req.ID, map[jellyseerr.NotificationsField]any{ - jellyseerr.FieldDiscord: jellyseerr.BogusIdentifier, - jellyseerr.FieldDiscordEnabled: false, - }); err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) + contact := false + + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(req.ID, nil, EmptyDiscordUser(), nil, &common.ContactPreferences{ + Discord: &contact, + }); err != nil { + app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) + } } app.storage.SetActivityKey(shortuuid.New(), Activity{ @@ -697,12 +701,14 @@ func (app *appContext) UnlinkTelegram(gc *gin.Context) { } */ app.storage.DeleteTelegramKey(req.ID) - // FIXME: Use thirdPartyServices for this - if err := app.js.ModifyNotifications(req.ID, map[jellyseerr.NotificationsField]any{ - jellyseerr.FieldTelegram: jellyseerr.BogusIdentifier, - jellyseerr.FieldTelegramEnabled: false, - }); err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) + contact := false + + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(req.ID, nil, nil, EmptyTelegramUser(), &common.ContactPreferences{ + Telegram: &contact, + }); err != nil { + app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) + } } app.storage.SetActivityKey(shortuuid.New(), Activity{ diff --git a/api-ombi.go b/api-ombi.go index 4f5a2d1..76b3828 100644 --- a/api-ombi.go +++ b/api-ombi.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/hrfee/jfa-go/common" lm "github.com/hrfee/jfa-go/logmessages" - "github.com/hrfee/jfa-go/ombi" + ombiLib "github.com/hrfee/jfa-go/ombi" "github.com/hrfee/mediabrowser" ) @@ -147,7 +147,8 @@ func (app *appContext) DeleteOmbiProfile(gc *gin.Context) { } type OmbiWrapper struct { - *ombi.Ombi + OmbiUserByJfID func(jfID string) (map[string]interface{}, error) + *ombiLib.Ombi } func (ombi *OmbiWrapper) applyProfile(user map[string]interface{}, profile map[string]interface{}) (err error) { @@ -189,23 +190,69 @@ func (ombi *OmbiWrapper) ImportUser(jellyfinID string, req newUserDTO, profile P return } -func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) { - var ombiUser map[string]interface{} - ombiUser, err = ombi.getUser(req.Username, req.Email) +func (ombi *OmbiWrapper) SetContactMethods(jellyfinID string, email *string, discord *DiscordUser, telegram *TelegramUser, contactPrefs *common.ContactPreferences) (err error) { + ombiUser, err := ombi.OmbiUserByJfID(jellyfinID) if err != nil { return } - if discordEnabled || telegramEnabled { - dID := "" - tUser := "" + if contactPrefs == nil { + contactPrefs = &common.ContactPreferences{ + Email: nil, + Discord: nil, + Telegram: nil, + Matrix: nil, + } + } + if emailEnabled && email != nil { + ombiUser["emailAddress"] = *email + err = ombi.ModifyUser(ombiUser) + if err != nil { + // FIXME: This is a little ugly, considering all other errors are unformatted + err = fmt.Errorf(lm.FailedSetEmailAddress, lm.Ombi, jellyfinID, err) + return + } + } + + data := make([]ombiLib.NotificationPref, 0, 2) + if discordEnabled { + pref := ombiLib.NotificationPref{ + Agent: ombiLib.NotifAgentDiscord, + UserID: ombiUser["id"].(string), + } + valid := false + if contactPrefs.Discord != nil { + pref.Enabled = *(contactPrefs.Discord) + valid = true + } else if discord != nil && discord.ID != "" { + pref.Enabled = true + valid = true + } if discord != nil { - dID = discord.ID + pref.Value = discord.ID + valid = true + } + if valid { + data = append(data, pref) + } + } + if telegramEnabled && telegram != nil { + pref := ombiLib.NotificationPref{ + Agent: ombiLib.NotifAgentTelegram, + UserID: ombiUser["id"].(string), + } + if contactPrefs.Telegram != nil { + pref.Enabled = *(contactPrefs.Telegram) + } else if telegram != nil && telegram.Username != "" { + pref.Enabled = true } if telegram != nil { - tUser = telegram.Username + pref.Value = telegram.Username } + data = append(data, pref) + } + if len(data) > 0 { var resp string - resp, err = ombi.SetNotificationPrefs(ombiUser, dID, tUser) + resp, err = ombi.SetNotificationPrefs(ombiUser, data) if err != nil { if resp != "" { err = fmt.Errorf("%v, %s", err, resp) diff --git a/api-userpage.go b/api-userpage.go index 10da341..f25dd8a 100644 --- a/api-userpage.go +++ b/api-userpage.go @@ -107,7 +107,7 @@ func (app *appContext) MyDetails(gc *gin.Context) { // @Summary Sets whether to notify yourself through telegram/discord/matrix/email or not. // @Produce json -// @Param SetContactMethodsDTO body SetContactMethodsDTO true "User's Jellyfin ID and whether or not to notify then through Telegram." +// @Param SetContactPreferencesDTO body SetContactPreferencesDTO true "User's Jellyfin ID and whether or not to notify then through Telegram." // @Success 200 {object} boolResponse // @Success 400 {object} boolResponse // @Success 500 {object} boolResponse @@ -115,14 +115,14 @@ func (app *appContext) MyDetails(gc *gin.Context) { // @Security Bearer // @tags User Page func (app *appContext) SetMyContactMethods(gc *gin.Context) { - var req SetContactMethodsDTO + var req SetContactPreferencesDTO gc.BindJSON(&req) req.ID = gc.GetString("jfId") if req.ID == "" { respondBool(400, false, gc) return } - app.setContactMethods(req, gc) + app.setContactPreferences(req, gc) } // @Summary Logout by deleting refresh token from cookies. diff --git a/api-users.go b/api-users.go index aac73e8..ee57606 100644 --- a/api-users.go +++ b/api-users.go @@ -10,7 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" - "github.com/hrfee/jfa-go/jellyseerr" + "github.com/hrfee/jfa-go/common" lm "github.com/hrfee/jfa-go/logmessages" "github.com/hrfee/mediabrowser" "github.com/lithammer/shortuuid/v3" @@ -54,12 +54,13 @@ func (app *appContext) NewUserFromAdmin(gc *gin.Context) { nu.Log() } + var emailStore *EmailAddress = nil if emailEnabled && req.Email != "" { - emailStore := EmailAddress{ + emailStore = &EmailAddress{ Addr: req.Email, Contact: true, } - app.storage.SetEmailsKey(nu.User.ID, emailStore) + app.storage.SetEmailsKey(nu.User.ID, *emailStore) } for _, tps := range app.thirdPartyServices { @@ -67,7 +68,12 @@ func (app *appContext) NewUserFromAdmin(gc *gin.Context) { continue } // We only have email - err := tps.AddContactMethods(nu.User.ID, req, nil, nil) + if emailStore == nil { + continue + } + err := tps.SetContactMethods(nu.User.ID, &req.Email, nil, nil, &common.ContactPreferences{ + Email: &(emailStore.Contact), + }) if err != nil { app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) } @@ -279,12 +285,14 @@ func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey referralsEnabled := profile != nil && profile.ReferralTemplateKey != "" && app.config.Section("user_page").Key("enabled").MustBool(false) && app.config.Section("user_page").Key("referrals").MustBool(false) + contactPrefs := common.ContactPreferences{} if (emailEnabled && req.Email != "") || invite.UserLabel != "" || referralsEnabled { emailStore := EmailAddress{ Addr: req.Email, Contact: (req.Email != ""), Label: invite.UserLabel, } + contactPrefs.Email = &(emailStore.Contact) if profile != nil { profile.ReferralTemplateKey = profile.ReferralTemplateKey } @@ -345,18 +353,22 @@ func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey var discordUser *DiscordUser = nil var telegramUser *TelegramUser = nil + // FIXME: Make sure its okay to, then change this check to len(app.tps) != 0 && (for loop of tps.Enabled ) if app.ombi.Enabled(app, profile) || app.js.Enabled(app, profile) { // FIXME: figure these out in a nicer way? this relies on the current ordering, // which may not be fixed. if discordEnabled { if req.completeContactMethods[0].User != nil { discordUser = req.completeContactMethods[0].User.(*DiscordUser) + contactPrefs.Discord = &discordUser.Contact } if telegramEnabled && req.completeContactMethods[1].User != nil { telegramUser = req.completeContactMethods[1].User.(*TelegramUser) + contactPrefs.Telegram = &telegramUser.Contact } } else if telegramEnabled && req.completeContactMethods[0].User != nil { telegramUser = req.completeContactMethods[0].User.(*TelegramUser) + contactPrefs.Telegram = &telegramUser.Contact } } @@ -365,7 +377,7 @@ func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey continue } // User already created, now we can link contact methods - err := tps.AddContactMethods(nu.User.ID, req.newUserDTO, discordUser, telegramUser) + err := tps.SetContactMethods(nu.User.ID, &(req.Email), discordUser, telegramUser, &contactPrefs) if err != nil { app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) } @@ -1119,39 +1131,21 @@ func (app *appContext) ModifyLabels(gc *gin.Context) { } func (app *appContext) modifyEmail(jfID string, addr string) { - contactPrefChanged := false emailStore, ok := app.storage.GetEmailsKey(jfID) // Auto enable contact by email for newly added addresses if !ok || emailStore.Addr == "" { emailStore = EmailAddress{ Contact: true, } - contactPrefChanged = true } emailStore.Addr = addr app.storage.SetEmailsKey(jfID, emailStore) - if app.config.Section("ombi").Key("enabled").MustBool(false) { - ombiUser, err := app.getOmbiUser(jfID) - if err == nil { - ombiUser["emailAddress"] = addr - err = app.ombi.ModifyUser(ombiUser) - if err != nil { - app.err.Printf(lm.FailedSetEmailAddress, lm.Ombi, jfID, err) - } - } - } - if app.config.Section("jellyseerr").Key("enabled").MustBool(false) { - err := app.js.ModifyMainUserSettings(jfID, jellyseerr.MainUserSettings{Email: addr}) - if err != nil { - app.err.Printf(lm.FailedSetEmailAddress, lm.Jellyseerr, jfID, err) - } else if contactPrefChanged { - contactMethods := map[jellyseerr.NotificationsField]any{ - jellyseerr.FieldEmailEnabled: true, - } - err := app.js.ModifyNotifications(jfID, contactMethods) - if err != nil { - app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err) - } + + for _, tps := range app.thirdPartyServices { + if err := tps.SetContactMethods(jfID, &addr, nil, nil, &common.ContactPreferences{ + Email: &(emailStore.Contact), + }); err != nil { + app.err.Printf(lm.FailedSetEmailAddress, tps.Name(), jfID, err) } } app.InvalidateWebUserCache() diff --git a/common/common.go b/common/common.go index a56e1ff..c361aa7 100644 --- a/common/common.go +++ b/common/common.go @@ -16,6 +16,16 @@ import ( lm "github.com/hrfee/jfa-go/logmessages" ) +const ( + BogusIdentifier = "123412341234123456" +) + +// ContactPreferences holds whether or not a user should be contacted through each of the available +// methods. If nil, leave setting alone. +type ContactPreferences struct { + Email, Discord, Telegram, Matrix *bool +} + // TimeoutHandler recovers from an http timeout or panic. type TimeoutHandler func() diff --git a/discord.go b/discord.go index 02180be..a2512cb 100644 --- a/discord.go +++ b/discord.go @@ -32,6 +32,17 @@ type DiscordDaemon struct { retryOpts *common.MustAuthenticateOptions } +func EmptyDiscordUser() *DiscordUser { + return &DiscordUser{ + ID: "", + Username: "", + Discriminator: "", + Lang: "", + Contact: false, + JellyfinID: "", + } +} + func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) { token := app.config.Section("discord").Key("token").String() if token == "" { diff --git a/main.go b/main.go index 8f15939..a5d8dff 100644 --- a/main.go +++ b/main.go @@ -369,7 +369,9 @@ func start(asDaemon, firstCall bool) { // NOTE: As of writing this, the order in app.thirdPartyServices doesn't matter, // but in future it might (like app.contactMethods does), so append to the end! if app.config.Section("ombi").Key("enabled").MustBool(false) { - app.ombi = &OmbiWrapper{} + app.ombi = &OmbiWrapper{ + OmbiUserByJfID: app.getOmbiUser, + } app.debug.Printf(lm.UsingOmbi) ombiServer := app.config.Section("ombi").Key("server").String() app.ombi.Ombi = ombi.NewOmbi( diff --git a/matrix.go b/matrix.go index ec6d16a..f6b191d 100644 --- a/matrix.go +++ b/matrix.go @@ -64,6 +64,16 @@ var matrixFilter = mautrix.Filter{ }, } +func EmptyMatrixUser() *MatrixUser { + return &MatrixUser{ + RoomID: "", + UserID: "", + Lang: "", + Contact: false, + JellyfinID: "", + } +} + func (d *MatrixDaemon) renderUserID(uid id.UserID) id.UserID { if uid[0] != '@' { uid = "@" + uid diff --git a/migrations.go b/migrations.go index 254dbdf..9ffef37 100644 --- a/migrations.go +++ b/migrations.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" + "github.com/hrfee/jfa-go/ombi" "gopkg.in/ini.v1" ) @@ -191,7 +192,10 @@ func linkExistingOmbiDiscordTelegram(app *appContext) error { app.debug.Printf("Failed to get Ombi user with Discord/Telegram \"%s\"/\"%s\": %v", ids[0], ids[1], err) continue } - _, err = app.ombi.SetNotificationPrefs(ombiUser, ids[0], ids[1]) + _, err = app.ombi.SetNotificationPrefs(ombiUser, []ombi.NotificationPref{ + {ombi.NotifAgentDiscord, ombiUser["id"].(string), ids[0], true}, + {ombi.NotifAgentTelegram, ombiUser["id"].(string), ids[1], true}, + }) if err != nil { app.debug.Printf("Failed to set prefs for Ombi user \"%s\": %v", ombiUser["userName"].(string), err) continue diff --git a/models.go b/models.go index d8467e8..30b1ca8 100644 --- a/models.go +++ b/models.go @@ -278,7 +278,7 @@ type telegramSetDTO struct { ID string `json:"id"` // Jellyfin ID of user. } -type SetContactMethodsDTO struct { +type SetContactPreferencesDTO struct { ID string `json:"id"` Email bool `json:"email"` Discord bool `json:"discord"` diff --git a/ombi/ombi.go b/ombi/ombi.go index 4bd9c04..2edc906 100644 --- a/ombi/ombi.go +++ b/ombi/ombi.go @@ -246,16 +246,8 @@ type NotificationPref struct { Enabled bool `json:"enabled"` } -func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, telegramUser string) (result string, err error) { - id := user["id"].(string) +func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, data []NotificationPref) (result string, err error) { url := fmt.Sprintf("%s/api/v1/Identity/NotificationPreferences", ombi.server) - data := []NotificationPref{} - if discordID != "" { - data = append(data, NotificationPref{NotifAgentDiscord, id, discordID, true}) - } - if telegramUser != "" { - data = append(data, NotificationPref{NotifAgentTelegram, id, telegramUser, true}) - } var code int result, code, err = ombi.send("POST", url, data, true, map[string]string{"UserName": user["userName"].(string)}) err = co.GenericErr(code, err) diff --git a/storage.go b/storage.go index 5bc46f2..58932da 100644 --- a/storage.go +++ b/storage.go @@ -625,7 +625,11 @@ type ThirdPartyService interface { common.ConfigurableTransport // ok implies user imported, err can be any issue that occurs during ImportUser(jellyfinID string, req newUserDTO, profile Profile) (err error, ok bool) - AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) + // SetContactMethods allows setting any combination of contact method address/username/id and contact preference. To leave fields alone, pass nil pointers, to set them to a blank value, use "" or Empty(Discord|Telegram|Matrix)User(). Ignores the "Contact" field in some xyzUser structs. + SetContactMethods(jellyfinID string, email *string, discord *DiscordUser, telegram *TelegramUser, contactPrefs *common.ContactPreferences) (err error) + // Enabled returns whether this service is enabled in the given profile. + // Not for checking if the service is enabled in general! + // If it wasn't, it wouldn't be in app.thirdPartyServices. Enabled(app *appContext, profile *Profile) bool Name() string } diff --git a/telegram.go b/telegram.go index c7cf5fb..384efc6 100644 --- a/telegram.go +++ b/telegram.go @@ -28,6 +28,16 @@ func (tv TelegramVerifiedToken) ToUser() *TelegramUser { } } +func EmptyTelegramUser() *TelegramUser { + return &TelegramUser{ + JellyfinID: "", + ChatID: 0, + Username: "", + Lang: "", + Contact: false, + } +} + func (t *TelegramVerifiedToken) Name() string { return t.Username } func (t *TelegramVerifiedToken) SetMethodID(id any) { t.ChatID = id.(int64) } func (t *TelegramVerifiedToken) MethodID() any { return t.ChatID }