package mail import ( "context" "encoding/json" "errors" "github.com/jackc/pgx/v5" "github.com/ultisuite/ulti-backend/internal/mail/webhooks" ) func (s *Service) UpdateWebhook(ctx context.Context, externalID, webhookID string, req *updateWebhookRequest, method string, maxRetries int) error { headersJSON, _ := json.Marshal(req.Headers) tx, err := s.db.Begin(ctx) if err != nil { return err } defer tx.Rollback(ctx) var version int eventTypesJSON, err := marshalWebhookEventTypes(req.EventTypes) if err != nil { return err } mailScopeJSON, err := marshalWebhookMailScope(req.MailScope) if err != nil { return err } driveScopeJSON, err := marshalWebhookDriveScope(req.DriveScope) if err != nil { return err } contactsScopeJSON, err := marshalWebhookContactsScope(req.ContactsScope) if err != nil { return err } agendaScopeJSON, err := marshalWebhookAgendaScope(req.AgendaScope) if err != nil { return err } err = tx.QueryRow(ctx, ` UPDATE webhook_templates SET name = $1, url = $2, method = $3, headers = $4, body_template = $5, signing_secret = $6, max_retries = $7, event_types = $8, mail_scope = $9, drive_scope = $10, contacts_scope = $11, agenda_scope = $12, version = version + 1, updated_at = NOW() WHERE id = $13 AND user_id = (SELECT id FROM users WHERE external_id = $14) RETURNING version `, req.Name, req.URL, method, headersJSON, req.BodyTemplate, req.SigningSecret, maxRetries, eventTypesJSON, mailScopeJSON, driveScopeJSON, contactsScopeJSON, agendaScopeJSON, webhookID, externalID).Scan(&version) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return ErrNotFound } return err } if _, err := tx.Exec(ctx, ` INSERT INTO webhook_template_versions (template_id, version, method, headers, body_template) VALUES ($1, $2, $3, $4, $5) `, webhookID, version, method, headersJSON, req.BodyTemplate); err != nil { return err } return tx.Commit(ctx) } func (s *Service) PreviewWebhookTemplate(_ context.Context, _ string, req *previewWebhookRequest) (map[string]any, error) { msgCtx := &webhooks.MessageContext{ SenderName: req.Message.SenderName, SenderEmail: req.Message.SenderEmail, Subject: req.Message.Subject, BodyText: req.Message.BodyText, BodyHTML: req.Message.BodyHTML, Date: req.Message.Date, Recipients: req.Message.Recipients, HasAttachment: req.Message.HasAttachment, MessageID: req.Message.MessageID, } return map[string]any{ "payload": webhooks.RenderBodyTemplate(req.BodyTemplate, msgCtx), }, nil }