package notification import ( "context" "github.com/zitadel/logging" "github.com/zitadel/zitadel/internal/notification/channels/smtp" "github.com/zitadel/zitadel/internal/notification/channels/twilio" "github.com/zitadel/zitadel/internal/notification/channels/webhook" "github.com/zitadel/zitadel/internal/notification/handlers" "github.com/zitadel/zitadel/internal/notification/senders" "github.com/zitadel/zitadel/internal/notification/types" "github.com/zitadel/zitadel/internal/telemetry/metrics" ) var _ types.ChannelChains = (*channels)(nil) type counters struct { success deliveryMetrics failed deliveryMetrics } type deliveryMetrics struct { email string sms string json string } type channels struct { q *handlers.NotificationQueries counters counters } func newChannels(q *handlers.NotificationQueries) *channels { c := &channels{ q: q, counters: counters{ success: deliveryMetrics{ email: "successful_deliveries_email", sms: "successful_deliveries_sms", json: "successful_deliveries_json", }, failed: deliveryMetrics{ email: "failed_deliveries_email", sms: "failed_deliveries_sms", json: "failed_deliveries_json", }, }, } registerCounter(c.counters.success.email, "Successfully delivered emails") registerCounter(c.counters.failed.email, "Failed email deliveries") registerCounter(c.counters.success.sms, "Successfully delivered SMS") registerCounter(c.counters.failed.sms, "Failed SMS deliveries") registerCounter(c.counters.success.json, "Successfully delivered JSON messages") registerCounter(c.counters.failed.json, "Failed JSON message deliveries") return c } func registerCounter(counter, desc string) { err := metrics.RegisterCounter(counter, desc) logging.WithFields("metric", counter).OnError(err).Panic("unable to register counter") } func (c *channels) Email(ctx context.Context) (*senders.Chain, *smtp.Config, error) { smtpCfg, err := c.q.GetSMTPConfig(ctx) if err != nil { return nil, nil, err } chain, err := senders.EmailChannels( ctx, smtpCfg, c.q.GetFileSystemProvider, c.q.GetLogProvider, c.counters.success.email, c.counters.failed.email, ) return chain, smtpCfg, err } func (c *channels) SMS(ctx context.Context) (*senders.Chain, *twilio.Config, error) { twilioCfg, err := c.q.GetTwilioConfig(ctx) if err != nil { return nil, nil, err } chain, err := senders.SMSChannels( ctx, twilioCfg, c.q.GetFileSystemProvider, c.q.GetLogProvider, c.counters.success.sms, c.counters.failed.sms, ) return chain, twilioCfg, err } func (c *channels) Webhook(ctx context.Context, cfg webhook.Config) (*senders.Chain, error) { return senders.WebhookChannels( ctx, cfg, c.q.GetFileSystemProvider, c.q.GetLogProvider, c.counters.success.json, c.counters.failed.json, ) }