mirror of
https://github.com/lone-cloud/prism
synced 2026-06-03 08:43:10 -07:00
168 lines
4.6 KiB
Go
168 lines
4.6 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"prism/service/notification"
|
|
"prism/service/util"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
type subscriptionFormData struct {
|
|
Channel string
|
|
GroupID string
|
|
ChatID string
|
|
}
|
|
|
|
func (s *Server) handleCreateSubscription(w http.ResponseWriter, r *http.Request) {
|
|
appName := chi.URLParam(r, "appName")
|
|
if appName == "" {
|
|
http.Error(w, "Missing app parameter", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := r.ParseForm(); err != nil {
|
|
util.JSONError(w, "Invalid form data", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
form := subscriptionFormData{
|
|
Channel: r.FormValue("channel"),
|
|
GroupID: r.FormValue("group_id"),
|
|
ChatID: r.FormValue("chat_id"),
|
|
}
|
|
|
|
channel := notification.Channel(form.Channel)
|
|
if !s.dispatcher.IsValidChannel(channel) {
|
|
util.SetToast(w, fmt.Sprintf("Invalid or unavailable channel: %s", form.Channel), "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
|
|
app, err := s.store.GetApp(appName)
|
|
if err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to load app subscriptions", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
if app != nil {
|
|
for _, existingSub := range app.Subscriptions {
|
|
if existingSub.Channel == channel {
|
|
util.SetToast(w, fmt.Sprintf("%s already enabled", channel.Label()), "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
subID, err := notification.GenerateSubscriptionID()
|
|
if err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to generate subscription ID", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
sub := notification.Subscription{
|
|
ID: subID,
|
|
AppName: appName,
|
|
Channel: channel,
|
|
}
|
|
|
|
switch channel {
|
|
case notification.ChannelSignal:
|
|
if s.integrations.Signal == nil || !s.integrations.Signal.IsEnabled() {
|
|
util.SetToast(w, "Signal not configured", "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
client := s.integrations.Signal.GetHandlers().GetClient()
|
|
account, err := client.GetLinkedAccount()
|
|
if err != nil || account == nil {
|
|
util.SetToast(w, "Signal not linked - configure in Integrations below", "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
|
|
if form.GroupID != "" {
|
|
sub.Signal = ¬ification.SignalSubscription{
|
|
GroupID: form.GroupID,
|
|
Account: account.Number,
|
|
}
|
|
} else {
|
|
cachedGroup, err := s.store.GetSignalGroup(appName)
|
|
if err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to check for cached Signal group", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
if cachedGroup != nil && cachedGroup.Account == account.Number {
|
|
sub.Signal = cachedGroup
|
|
} else {
|
|
signalSub, err := s.integrations.Signal.GetSender().CreateDefaultSignalSubscription(appName)
|
|
if err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to create Signal subscription", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
sub.Signal = signalSub
|
|
}
|
|
}
|
|
|
|
case notification.ChannelTelegram:
|
|
if s.integrations.Telegram == nil || !s.integrations.Telegram.IsEnabled() {
|
|
util.SetToast(w, "Telegram not configured", "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
chatID := s.integrations.Telegram.GetHandlers().GetChatID()
|
|
if chatID == 0 {
|
|
util.SetToast(w, "Telegram not linked - configure in Integrations below", "error")
|
|
s.handleFragmentApps(w, r)
|
|
return
|
|
}
|
|
if form.ChatID != "" {
|
|
chatID = 0
|
|
fmt.Sscanf(form.ChatID, "%d", &chatID)
|
|
}
|
|
sub.Telegram = ¬ification.TelegramSubscription{
|
|
ChatID: fmt.Sprintf("%d", chatID),
|
|
}
|
|
|
|
default:
|
|
util.JSONError(w, "Unsupported channel for manual subscription", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := s.store.AddSubscription(sub); err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to create subscription", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
util.SetToast(w, fmt.Sprintf("%s enabled", channel.Label()), "success")
|
|
s.handleFragmentApps(w, r)
|
|
}
|
|
|
|
func (s *Server) handleDeleteSubscription(w http.ResponseWriter, r *http.Request) {
|
|
subscriptionID := chi.URLParam(r, "subscriptionId")
|
|
if subscriptionID == "" {
|
|
http.Error(w, "Missing subscription ID", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
sub, err := s.store.GetSubscription(subscriptionID)
|
|
if err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to get subscription", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
if err := s.store.DeleteSubscription(subscriptionID); err != nil {
|
|
util.LogAndError(w, s.logger, "Failed to delete subscription", http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
message := fmt.Sprintf("%s disabled", sub.Channel.Label())
|
|
if sub.Channel == notification.ChannelWebPush {
|
|
message = fmt.Sprintf("%s deleted", sub.Channel.Label())
|
|
}
|
|
util.SetToast(w, message, "success")
|
|
s.handleFragmentApps(w, r)
|
|
}
|