- Added a new endpoint for simulating rules based on sample messages, allowing users to test rule conditions and actions. - Enhanced webhook management with versioning, preview capabilities, and improved validation for webhook requests. - Updated service interfaces to support new functionalities, including max retries for webhooks and signing secrets. - Implemented observability metrics for webhook retries and dead-letter tracking, improving error handling and monitoring. - Enhanced unit tests to cover new simulation and webhook features, ensuring robust functionality and validation.
71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package mail
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/mail/rules"
|
|
)
|
|
|
|
func (s *Service) SimulateRule(ctx context.Context, externalID string, req *simulateRuleRequest) (rules.SimulationResult, error) {
|
|
conditions, actions, err := s.resolveSimulateRule(ctx, externalID, req)
|
|
if err != nil {
|
|
return rules.SimulationResult{}, err
|
|
}
|
|
|
|
msg := &rules.Message{
|
|
ID: "simulation",
|
|
From: req.Message.From,
|
|
To: req.Message.To,
|
|
Subject: req.Message.Subject,
|
|
BodyText: req.Message.BodyText,
|
|
HasAttachments: req.Message.HasAttachments,
|
|
}
|
|
|
|
engine := rules.NewEngine(s.db)
|
|
return engine.SimulateRule(ctx, conditions, actions, msg), nil
|
|
}
|
|
|
|
func (s *Service) resolveSimulateRule(ctx context.Context, externalID string, req *simulateRuleRequest) ([]rules.Condition, []rules.Action, error) {
|
|
if req.RuleID != "" {
|
|
var condJSON, actJSON []byte
|
|
err := s.db.QueryRow(ctx, `
|
|
SELECT conditions, actions
|
|
FROM mail_rules
|
|
WHERE id = $1 AND user_id = (SELECT id FROM users WHERE external_id = $2)
|
|
`, req.RuleID, externalID).Scan(&condJSON, &actJSON)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, nil, ErrNotFound
|
|
}
|
|
return nil, nil, err
|
|
}
|
|
return unmarshalRuleConditionsActions(condJSON, actJSON)
|
|
}
|
|
|
|
condJSON, err := json.Marshal(req.Rule.Conditions)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
actJSON, err := json.Marshal(req.Rule.Actions)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return unmarshalRuleConditionsActions(condJSON, actJSON)
|
|
}
|
|
|
|
func unmarshalRuleConditionsActions(condJSON, actJSON []byte) ([]rules.Condition, []rules.Action, error) {
|
|
var conditions []rules.Condition
|
|
var actions []rules.Action
|
|
if err := json.Unmarshal(condJSON, &conditions); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if err := json.Unmarshal(actJSON, &actions); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return conditions, actions, nil
|
|
}
|