mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
ThirdPartyServices: SetContactMethods for setting, enable/disable
replace AddContactMethods with a more generalised SetContactMethods, which can set (or leave alone) contact method addresses/names/ids and set (or leave alone) contact preferences. A little awkward to use, but works everywhere, and now a bunch of Jellyseerr integration features are present for Ombi (which they should've been anyway).
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/hrfee/jfa-go/common"
|
||||||
"github.com/hrfee/jfa-go/jellyseerr"
|
"github.com/hrfee/jfa-go/jellyseerr"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
)
|
)
|
||||||
@@ -124,29 +125,62 @@ func (js *JellyseerrWrapper) ImportUser(jellyfinID string, req newUserDTO, profi
|
|||||||
return
|
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)
|
_, err = js.MustGetUser(jellyfinID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
contactMethods := map[jellyseerr.NotificationsField]any{}
|
if contactPrefs == nil {
|
||||||
if emailEnabled {
|
contactPrefs = &common.ContactPreferences{
|
||||||
err = js.ModifyMainUserSettings(jellyfinID, jellyseerr.MainUserSettings{Email: req.Email})
|
Email: nil,
|
||||||
if err != nil {
|
Discord: nil,
|
||||||
// FIXME: This is a little ugly, considering all other errors are unformatted
|
Telegram: nil,
|
||||||
err = fmt.Errorf(lm.FailedSetEmailAddress, lm.Jellyseerr, jellyfinID, err)
|
Matrix: nil,
|
||||||
return
|
|
||||||
} else {
|
|
||||||
contactMethods[jellyseerr.FieldEmailEnabled] = req.EmailContact
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if discordEnabled && discord != nil {
|
contactMethods := map[jellyseerr.NotificationsField]any{}
|
||||||
contactMethods[jellyseerr.FieldDiscord] = discord.ID
|
if emailEnabled {
|
||||||
contactMethods[jellyseerr.FieldDiscordEnabled] = req.DiscordContact
|
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 {
|
if discordEnabled {
|
||||||
contactMethods[jellyseerr.FieldTelegram] = telegram.ChatID
|
if contactPrefs.Discord != nil {
|
||||||
contactMethods[jellyseerr.FieldTelegramEnabled] = req.TelegramContact
|
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 {
|
if len(contactMethods) > 0 {
|
||||||
err = js.ModifyNotifications(jellyfinID, contactMethods)
|
err = js.ModifyNotifications(jellyfinID, contactMethods)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/hrfee/jfa-go/jellyseerr"
|
"github.com/hrfee/jfa-go/common"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/lithammer/shortuuid/v3"
|
"github.com/lithammer/shortuuid/v3"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
@@ -263,21 +263,21 @@ func (app *appContext) TelegramAddUser(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
app.storage.SetTelegramKey(req.ID, tgUser)
|
app.storage.SetTelegramKey(req.ID, tgUser)
|
||||||
|
|
||||||
if err := app.js.ModifyNotifications(gc.GetString("jfId"), map[jellyseerr.NotificationsField]any{
|
for _, tps := range app.thirdPartyServices {
|
||||||
jellyseerr.FieldTelegram: tgUser.ChatID,
|
if err := tps.SetContactMethods(req.ID, nil, nil, &tgUser, &common.ContactPreferences{
|
||||||
jellyseerr.FieldTelegramEnabled: tgUser.Contact,
|
Telegram: &tgUser.Contact,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
linkExistingOmbiDiscordTelegram(app)
|
|
||||||
app.InvalidateWebUserCache()
|
app.InvalidateWebUserCache()
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Sets whether to notify a user through telegram/discord/matrix/email or not.
|
// @Summary Sets whether to notify a user through telegram/discord/matrix/email or not.
|
||||||
// @Produce json
|
// @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 200 {object} boolResponse
|
||||||
// @Success 400 {object} boolResponse
|
// @Success 400 {object} boolResponse
|
||||||
// @Success 500 {object} boolResponse
|
// @Success 500 {object} boolResponse
|
||||||
@@ -285,24 +285,24 @@ func (app *appContext) TelegramAddUser(gc *gin.Context) {
|
|||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) SetContactMethods(gc *gin.Context) {
|
func (app *appContext) SetContactMethods(gc *gin.Context) {
|
||||||
var req SetContactMethodsDTO
|
var req SetContactPreferencesDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
if req.ID == "" {
|
if req.ID == "" {
|
||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.setContactMethods(req, gc)
|
app.setContactPreferences(req, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Context) {
|
func (app *appContext) setContactPreferences(req SetContactPreferencesDTO, gc *gin.Context) {
|
||||||
jsPrefs := map[jellyseerr.NotificationsField]any{}
|
contactPrefs := common.ContactPreferences{}
|
||||||
if tgUser, ok := app.storage.GetTelegramKey(req.ID); ok {
|
if tgUser, ok := app.storage.GetTelegramKey(req.ID); ok {
|
||||||
change := tgUser.Contact != req.Telegram
|
change := tgUser.Contact != req.Telegram
|
||||||
tgUser.Contact = req.Telegram
|
tgUser.Contact = req.Telegram
|
||||||
app.storage.SetTelegramKey(req.ID, tgUser)
|
app.storage.SetTelegramKey(req.ID, tgUser)
|
||||||
if change {
|
if change {
|
||||||
app.debug.Printf(lm.SetContactPrefForService, lm.Telegram, tgUser.Username, req.Telegram)
|
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 {
|
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)
|
app.storage.SetDiscordKey(req.ID, dcUser)
|
||||||
if change {
|
if change {
|
||||||
app.debug.Printf(lm.SetContactPrefForService, lm.Discord, dcUser.Username, req.Discord)
|
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 {
|
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)
|
app.storage.SetMatrixKey(req.ID, mxUser)
|
||||||
if change {
|
if change {
|
||||||
app.debug.Printf(lm.SetContactPrefForService, lm.Matrix, mxUser.UserID, req.Matrix)
|
app.debug.Printf(lm.SetContactPrefForService, lm.Matrix, mxUser.UserID, req.Matrix)
|
||||||
|
contactPrefs.Matrix = &req.Matrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if email, ok := app.storage.GetEmailsKey(req.ID); ok {
|
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)
|
app.storage.SetEmailsKey(req.ID, email)
|
||||||
if change {
|
if change {
|
||||||
app.debug.Printf(lm.SetContactPrefForService, lm.Email, email.Addr, req.Email)
|
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)
|
for _, tps := range app.thirdPartyServices {
|
||||||
if err != nil {
|
if err := tps.SetContactMethods(req.ID, nil, nil, nil, &contactPrefs); err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.InvalidateWebUserCache()
|
app.InvalidateWebUserCache()
|
||||||
@@ -621,11 +622,12 @@ func (app *appContext) DiscordConnect(gc *gin.Context) {
|
|||||||
|
|
||||||
app.storage.SetDiscordKey(req.JellyfinID, user)
|
app.storage.SetDiscordKey(req.JellyfinID, user)
|
||||||
|
|
||||||
if err := app.js.ModifyNotifications(req.JellyfinID, map[jellyseerr.NotificationsField]any{
|
for _, tps := range app.thirdPartyServices {
|
||||||
jellyseerr.FieldDiscord: req.DiscordID,
|
if err := tps.SetContactMethods(req.JellyfinID, nil, &user, nil, &common.ContactPreferences{
|
||||||
jellyseerr.FieldDiscordEnabled: true,
|
Discord: &user.Contact,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
||||||
@@ -659,12 +661,14 @@ func (app *appContext) UnlinkDiscord(gc *gin.Context) {
|
|||||||
} */
|
} */
|
||||||
app.storage.DeleteDiscordKey(req.ID)
|
app.storage.DeleteDiscordKey(req.ID)
|
||||||
|
|
||||||
// FIXME: Use thirdPartyServices for this
|
contact := false
|
||||||
if err := app.js.ModifyNotifications(req.ID, map[jellyseerr.NotificationsField]any{
|
|
||||||
jellyseerr.FieldDiscord: jellyseerr.BogusIdentifier,
|
for _, tps := range app.thirdPartyServices {
|
||||||
jellyseerr.FieldDiscordEnabled: false,
|
if err := tps.SetContactMethods(req.ID, nil, EmptyDiscordUser(), nil, &common.ContactPreferences{
|
||||||
}); err != nil {
|
Discord: &contact,
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
}); err != nil {
|
||||||
|
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
||||||
@@ -697,12 +701,14 @@ func (app *appContext) UnlinkTelegram(gc *gin.Context) {
|
|||||||
} */
|
} */
|
||||||
app.storage.DeleteTelegramKey(req.ID)
|
app.storage.DeleteTelegramKey(req.ID)
|
||||||
|
|
||||||
// FIXME: Use thirdPartyServices for this
|
contact := false
|
||||||
if err := app.js.ModifyNotifications(req.ID, map[jellyseerr.NotificationsField]any{
|
|
||||||
jellyseerr.FieldTelegram: jellyseerr.BogusIdentifier,
|
for _, tps := range app.thirdPartyServices {
|
||||||
jellyseerr.FieldTelegramEnabled: false,
|
if err := tps.SetContactMethods(req.ID, nil, nil, EmptyTelegramUser(), &common.ContactPreferences{
|
||||||
}); err != nil {
|
Telegram: &contact,
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
}); err != nil {
|
||||||
|
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
||||||
|
|||||||
69
api-ombi.go
69
api-ombi.go
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/hrfee/jfa-go/common"
|
"github.com/hrfee/jfa-go/common"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/hrfee/jfa-go/ombi"
|
ombiLib "github.com/hrfee/jfa-go/ombi"
|
||||||
"github.com/hrfee/mediabrowser"
|
"github.com/hrfee/mediabrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -147,7 +147,8 @@ func (app *appContext) DeleteOmbiProfile(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OmbiWrapper struct {
|
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) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) {
|
func (ombi *OmbiWrapper) SetContactMethods(jellyfinID string, email *string, discord *DiscordUser, telegram *TelegramUser, contactPrefs *common.ContactPreferences) (err error) {
|
||||||
var ombiUser map[string]interface{}
|
ombiUser, err := ombi.OmbiUserByJfID(jellyfinID)
|
||||||
ombiUser, err = ombi.getUser(req.Username, req.Email)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if discordEnabled || telegramEnabled {
|
if contactPrefs == nil {
|
||||||
dID := ""
|
contactPrefs = &common.ContactPreferences{
|
||||||
tUser := ""
|
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 {
|
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 {
|
if telegram != nil {
|
||||||
tUser = telegram.Username
|
pref.Value = telegram.Username
|
||||||
}
|
}
|
||||||
|
data = append(data, pref)
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
var resp string
|
var resp string
|
||||||
resp, err = ombi.SetNotificationPrefs(ombiUser, dID, tUser)
|
resp, err = ombi.SetNotificationPrefs(ombiUser, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if resp != "" {
|
if resp != "" {
|
||||||
err = fmt.Errorf("%v, %s", err, resp)
|
err = fmt.Errorf("%v, %s", err, resp)
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func (app *appContext) MyDetails(gc *gin.Context) {
|
|||||||
|
|
||||||
// @Summary Sets whether to notify yourself through telegram/discord/matrix/email or not.
|
// @Summary Sets whether to notify yourself through telegram/discord/matrix/email or not.
|
||||||
// @Produce json
|
// @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 200 {object} boolResponse
|
||||||
// @Success 400 {object} boolResponse
|
// @Success 400 {object} boolResponse
|
||||||
// @Success 500 {object} boolResponse
|
// @Success 500 {object} boolResponse
|
||||||
@@ -115,14 +115,14 @@ func (app *appContext) MyDetails(gc *gin.Context) {
|
|||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
// @tags User Page
|
// @tags User Page
|
||||||
func (app *appContext) SetMyContactMethods(gc *gin.Context) {
|
func (app *appContext) SetMyContactMethods(gc *gin.Context) {
|
||||||
var req SetContactMethodsDTO
|
var req SetContactPreferencesDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
req.ID = gc.GetString("jfId")
|
req.ID = gc.GetString("jfId")
|
||||||
if req.ID == "" {
|
if req.ID == "" {
|
||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.setContactMethods(req, gc)
|
app.setContactPreferences(req, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Logout by deleting refresh token from cookies.
|
// @Summary Logout by deleting refresh token from cookies.
|
||||||
|
|||||||
52
api-users.go
52
api-users.go
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/hrfee/jfa-go/jellyseerr"
|
"github.com/hrfee/jfa-go/common"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/hrfee/mediabrowser"
|
"github.com/hrfee/mediabrowser"
|
||||||
"github.com/lithammer/shortuuid/v3"
|
"github.com/lithammer/shortuuid/v3"
|
||||||
@@ -54,12 +54,13 @@ func (app *appContext) NewUserFromAdmin(gc *gin.Context) {
|
|||||||
nu.Log()
|
nu.Log()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var emailStore *EmailAddress = nil
|
||||||
if emailEnabled && req.Email != "" {
|
if emailEnabled && req.Email != "" {
|
||||||
emailStore := EmailAddress{
|
emailStore = &EmailAddress{
|
||||||
Addr: req.Email,
|
Addr: req.Email,
|
||||||
Contact: true,
|
Contact: true,
|
||||||
}
|
}
|
||||||
app.storage.SetEmailsKey(nu.User.ID, emailStore)
|
app.storage.SetEmailsKey(nu.User.ID, *emailStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tps := range app.thirdPartyServices {
|
for _, tps := range app.thirdPartyServices {
|
||||||
@@ -67,7 +68,12 @@ func (app *appContext) NewUserFromAdmin(gc *gin.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// We only have email
|
// 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 {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
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)
|
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 {
|
if (emailEnabled && req.Email != "") || invite.UserLabel != "" || referralsEnabled {
|
||||||
emailStore := EmailAddress{
|
emailStore := EmailAddress{
|
||||||
Addr: req.Email,
|
Addr: req.Email,
|
||||||
Contact: (req.Email != ""),
|
Contact: (req.Email != ""),
|
||||||
Label: invite.UserLabel,
|
Label: invite.UserLabel,
|
||||||
}
|
}
|
||||||
|
contactPrefs.Email = &(emailStore.Contact)
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
profile.ReferralTemplateKey = profile.ReferralTemplateKey
|
profile.ReferralTemplateKey = profile.ReferralTemplateKey
|
||||||
}
|
}
|
||||||
@@ -345,18 +353,22 @@ func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey
|
|||||||
|
|
||||||
var discordUser *DiscordUser = nil
|
var discordUser *DiscordUser = nil
|
||||||
var telegramUser *TelegramUser = 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) {
|
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,
|
// FIXME: figure these out in a nicer way? this relies on the current ordering,
|
||||||
// which may not be fixed.
|
// which may not be fixed.
|
||||||
if discordEnabled {
|
if discordEnabled {
|
||||||
if req.completeContactMethods[0].User != nil {
|
if req.completeContactMethods[0].User != nil {
|
||||||
discordUser = req.completeContactMethods[0].User.(*DiscordUser)
|
discordUser = req.completeContactMethods[0].User.(*DiscordUser)
|
||||||
|
contactPrefs.Discord = &discordUser.Contact
|
||||||
}
|
}
|
||||||
if telegramEnabled && req.completeContactMethods[1].User != nil {
|
if telegramEnabled && req.completeContactMethods[1].User != nil {
|
||||||
telegramUser = req.completeContactMethods[1].User.(*TelegramUser)
|
telegramUser = req.completeContactMethods[1].User.(*TelegramUser)
|
||||||
|
contactPrefs.Telegram = &telegramUser.Contact
|
||||||
}
|
}
|
||||||
} else if telegramEnabled && req.completeContactMethods[0].User != nil {
|
} else if telegramEnabled && req.completeContactMethods[0].User != nil {
|
||||||
telegramUser = req.completeContactMethods[0].User.(*TelegramUser)
|
telegramUser = req.completeContactMethods[0].User.(*TelegramUser)
|
||||||
|
contactPrefs.Telegram = &telegramUser.Contact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +377,7 @@ func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// User already created, now we can link contact methods
|
// 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 {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err)
|
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) {
|
func (app *appContext) modifyEmail(jfID string, addr string) {
|
||||||
contactPrefChanged := false
|
|
||||||
emailStore, ok := app.storage.GetEmailsKey(jfID)
|
emailStore, ok := app.storage.GetEmailsKey(jfID)
|
||||||
// Auto enable contact by email for newly added addresses
|
// Auto enable contact by email for newly added addresses
|
||||||
if !ok || emailStore.Addr == "" {
|
if !ok || emailStore.Addr == "" {
|
||||||
emailStore = EmailAddress{
|
emailStore = EmailAddress{
|
||||||
Contact: true,
|
Contact: true,
|
||||||
}
|
}
|
||||||
contactPrefChanged = true
|
|
||||||
}
|
}
|
||||||
emailStore.Addr = addr
|
emailStore.Addr = addr
|
||||||
app.storage.SetEmailsKey(jfID, emailStore)
|
app.storage.SetEmailsKey(jfID, emailStore)
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
|
||||||
ombiUser, err := app.getOmbiUser(jfID)
|
for _, tps := range app.thirdPartyServices {
|
||||||
if err == nil {
|
if err := tps.SetContactMethods(jfID, &addr, nil, nil, &common.ContactPreferences{
|
||||||
ombiUser["emailAddress"] = addr
|
Email: &(emailStore.Contact),
|
||||||
err = app.ombi.ModifyUser(ombiUser)
|
}); err != nil {
|
||||||
if err != nil {
|
app.err.Printf(lm.FailedSetEmailAddress, tps.Name(), jfID, err)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.InvalidateWebUserCache()
|
app.InvalidateWebUserCache()
|
||||||
|
|||||||
@@ -16,6 +16,16 @@ import (
|
|||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
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.
|
// TimeoutHandler recovers from an http timeout or panic.
|
||||||
type TimeoutHandler func()
|
type TimeoutHandler func()
|
||||||
|
|
||||||
|
|||||||
11
discord.go
11
discord.go
@@ -32,6 +32,17 @@ type DiscordDaemon struct {
|
|||||||
retryOpts *common.MustAuthenticateOptions
|
retryOpts *common.MustAuthenticateOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EmptyDiscordUser() *DiscordUser {
|
||||||
|
return &DiscordUser{
|
||||||
|
ID: "",
|
||||||
|
Username: "",
|
||||||
|
Discriminator: "",
|
||||||
|
Lang: "",
|
||||||
|
Contact: false,
|
||||||
|
JellyfinID: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) {
|
func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) {
|
||||||
token := app.config.Section("discord").Key("token").String()
|
token := app.config.Section("discord").Key("token").String()
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
|||||||
4
main.go
4
main.go
@@ -369,7 +369,9 @@ func start(asDaemon, firstCall bool) {
|
|||||||
// NOTE: As of writing this, the order in app.thirdPartyServices doesn't matter,
|
// 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!
|
// but in future it might (like app.contactMethods does), so append to the end!
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||||
app.ombi = &OmbiWrapper{}
|
app.ombi = &OmbiWrapper{
|
||||||
|
OmbiUserByJfID: app.getOmbiUser,
|
||||||
|
}
|
||||||
app.debug.Printf(lm.UsingOmbi)
|
app.debug.Printf(lm.UsingOmbi)
|
||||||
ombiServer := app.config.Section("ombi").Key("server").String()
|
ombiServer := app.config.Section("ombi").Key("server").String()
|
||||||
app.ombi.Ombi = ombi.NewOmbi(
|
app.ombi.Ombi = ombi.NewOmbi(
|
||||||
|
|||||||
10
matrix.go
10
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 {
|
func (d *MatrixDaemon) renderUserID(uid id.UserID) id.UserID {
|
||||||
if uid[0] != '@' {
|
if uid[0] != '@' {
|
||||||
uid = "@" + uid
|
uid = "@" + uid
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hrfee/jfa-go/ombi"
|
||||||
"gopkg.in/ini.v1"
|
"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)
|
app.debug.Printf("Failed to get Ombi user with Discord/Telegram \"%s\"/\"%s\": %v", ids[0], ids[1], err)
|
||||||
continue
|
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 {
|
if err != nil {
|
||||||
app.debug.Printf("Failed to set prefs for Ombi user \"%s\": %v", ombiUser["userName"].(string), err)
|
app.debug.Printf("Failed to set prefs for Ombi user \"%s\": %v", ombiUser["userName"].(string), err)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ type telegramSetDTO struct {
|
|||||||
ID string `json:"id"` // Jellyfin ID of user.
|
ID string `json:"id"` // Jellyfin ID of user.
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetContactMethodsDTO struct {
|
type SetContactPreferencesDTO struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Email bool `json:"email"`
|
Email bool `json:"email"`
|
||||||
Discord bool `json:"discord"`
|
Discord bool `json:"discord"`
|
||||||
|
|||||||
10
ombi/ombi.go
10
ombi/ombi.go
@@ -246,16 +246,8 @@ type NotificationPref struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, telegramUser string) (result string, err error) {
|
func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, data []NotificationPref) (result string, err error) {
|
||||||
id := user["id"].(string)
|
|
||||||
url := fmt.Sprintf("%s/api/v1/Identity/NotificationPreferences", ombi.server)
|
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
|
var code int
|
||||||
result, code, err = ombi.send("POST", url, data, true, map[string]string{"UserName": user["userName"].(string)})
|
result, code, err = ombi.send("POST", url, data, true, map[string]string{"UserName": user["userName"].(string)})
|
||||||
err = co.GenericErr(code, err)
|
err = co.GenericErr(code, err)
|
||||||
|
|||||||
@@ -625,7 +625,11 @@ type ThirdPartyService interface {
|
|||||||
common.ConfigurableTransport
|
common.ConfigurableTransport
|
||||||
// ok implies user imported, err can be any issue that occurs during
|
// ok implies user imported, err can be any issue that occurs during
|
||||||
ImportUser(jellyfinID string, req newUserDTO, profile Profile) (err error, ok bool)
|
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
|
Enabled(app *appContext, profile *Profile) bool
|
||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|||||||
10
telegram.go
10
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) Name() string { return t.Username }
|
||||||
func (t *TelegramVerifiedToken) SetMethodID(id any) { t.ChatID = id.(int64) }
|
func (t *TelegramVerifiedToken) SetMethodID(id any) { t.ChatID = id.(int64) }
|
||||||
func (t *TelegramVerifiedToken) MethodID() any { return t.ChatID }
|
func (t *TelegramVerifiedToken) MethodID() any { return t.ChatID }
|
||||||
|
|||||||
Reference in New Issue
Block a user