mirror of
https://github.com/lone-cloud/prism
synced 2026-06-03 08:43:10 -07:00
122 lines
3.2 KiB
Go
122 lines
3.2 KiB
Go
package signal
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"prism/service/config"
|
|
"prism/service/delivery"
|
|
"prism/service/subscription"
|
|
"prism/service/util"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
type Integration struct {
|
|
cfg *config.Config
|
|
client *Client
|
|
Handlers *Handlers
|
|
Sender *Sender
|
|
Groups *GroupCache
|
|
store *subscription.Store
|
|
logger *slog.Logger
|
|
tmpl *util.TemplateRenderer
|
|
}
|
|
|
|
func NewIntegration(cfg *config.Config, store *subscription.Store, logger *slog.Logger, tmpl *util.TemplateRenderer) *Integration {
|
|
client := NewClient()
|
|
groups, err := NewGroupCache(store.DB)
|
|
if err != nil {
|
|
logger.Error("Failed to initialize Signal group cache", "error", err)
|
|
}
|
|
var sender *Sender
|
|
if client != nil {
|
|
sender = NewSender(client, groups, logger)
|
|
}
|
|
return &Integration{
|
|
cfg: cfg,
|
|
client: client,
|
|
Sender: sender,
|
|
Groups: groups,
|
|
store: store,
|
|
logger: logger,
|
|
tmpl: tmpl,
|
|
}
|
|
}
|
|
|
|
func (s *Integration) RegisterRoutes(router *chi.Mux, auth func(http.Handler) http.Handler, logger *slog.Logger) {
|
|
s.Handlers = RegisterRoutes(router, s.cfg, auth, s.tmpl, logger, s.client)
|
|
}
|
|
|
|
func (s *Integration) Start(ctx context.Context, logger *slog.Logger) {
|
|
if s.Handlers != nil && s.Handlers.Client != nil {
|
|
client := s.Handlers.Client
|
|
account, _ := client.GetLinkedAccount()
|
|
if account != nil {
|
|
logger.Debug("Signal enabled", "status", "linked", "number", FormatPhoneNumber(account.Number))
|
|
} else {
|
|
logger.Debug("Signal enabled", "status", "unlinked", "action", "visit admin UI to link")
|
|
}
|
|
} else {
|
|
logger.Debug("Signal disabled", "reason", "signal-cli not found in PATH")
|
|
}
|
|
}
|
|
|
|
func (s *Integration) IsEnabled() bool {
|
|
return s.Handlers != nil && s.Handlers.Client != nil
|
|
}
|
|
|
|
func (s *Integration) Health() (bool, string) {
|
|
if s.Handlers == nil || s.Handlers.Client == nil {
|
|
return false, ""
|
|
}
|
|
account, _ := s.Handlers.Client.GetLinkedAccount()
|
|
if account == nil {
|
|
return false, ""
|
|
}
|
|
return true, account.Number
|
|
}
|
|
|
|
func (s *Integration) AutoSubscribe(appName string, store *subscription.Store, publisher *delivery.Publisher) error {
|
|
if s.Sender == nil {
|
|
return fmt.Errorf("signal-cli not available")
|
|
}
|
|
linked, err := s.Sender.IsLinked()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to check Signal link status: %w", err)
|
|
}
|
|
if !linked {
|
|
return fmt.Errorf("no linked Signal account")
|
|
}
|
|
if !publisher.HasChannel(subscription.ChannelSignal) {
|
|
publisher.RegisterSender(subscription.ChannelSignal, s.Sender)
|
|
}
|
|
|
|
var signalSub *subscription.SignalSubscription
|
|
if cachedGroup, err := s.Groups.Get(appName); err != nil {
|
|
s.logger.Warn("Failed to check for cached Signal group", "error", err)
|
|
} else if cachedGroup != nil {
|
|
s.logger.Debug("Reusing cached Signal group", "app", appName)
|
|
signalSub = cachedGroup
|
|
}
|
|
|
|
if signalSub == nil {
|
|
if signalSub, err = s.Sender.CreateDefaultSignalSubscription(appName); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
subID, err := store.AddSubscription(subscription.Subscription{
|
|
AppName: appName,
|
|
Channel: subscription.ChannelSignal,
|
|
Signal: signalSub,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.logger.Info("Auto-configured Signal subscription", "app", appName, "subscriptionID", subID)
|
|
return nil
|
|
}
|