102 lines
2.9 KiB
Go
102 lines
2.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) (any, error) {
|
|
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,
|
|
Labels: req.Message.Labels,
|
|
}
|
|
|
|
engine := rules.NewEngine(s.db)
|
|
|
|
wf, conditions, actions, err := s.resolveSimulateRulePayload(ctx, externalID, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if wf != nil && len(wf.Nodes) > 0 {
|
|
var userID string
|
|
_ = s.db.QueryRow(ctx, `SELECT id FROM users WHERE external_id = $1`, externalID).Scan(&userID)
|
|
return engine.SimulateWorkflow(ctx, userID, wf, msg, &rules.EventContext{Type: rules.TriggerMessageReceived}), nil
|
|
}
|
|
|
|
return engine.SimulateRule(ctx, conditions, actions, msg), nil
|
|
}
|
|
|
|
func (s *Service) resolveSimulateRulePayload(ctx context.Context, externalID string, req *simulateRuleRequest) (*rules.Workflow, []rules.Condition, []rules.Action, error) {
|
|
if req.RuleID != "" {
|
|
var condJSON, actJSON, wfJSON []byte
|
|
err := s.db.QueryRow(ctx, `
|
|
SELECT conditions, actions, workflow
|
|
FROM mail_rules
|
|
WHERE id = $1 AND user_id = (SELECT id FROM users WHERE external_id = $2)
|
|
`, req.RuleID, externalID).Scan(&condJSON, &actJSON, &wfJSON)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, nil, nil, ErrNotFound
|
|
}
|
|
return nil, nil, nil, err
|
|
}
|
|
wf, err := rules.ParseWorkflow(wfJSON)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
if wf != nil && len(wf.Nodes) > 0 {
|
|
return wf, nil, nil, nil
|
|
}
|
|
conditions, actions, err := unmarshalRuleConditionsActions(condJSON, actJSON)
|
|
return nil, conditions, actions, err
|
|
}
|
|
|
|
if req.Rule.Workflow != nil {
|
|
wfJSON, err := json.Marshal(req.Rule.Workflow)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
wf, err := rules.ParseWorkflow(wfJSON)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
if wf != nil && len(wf.Nodes) > 0 {
|
|
return wf, nil, nil, nil
|
|
}
|
|
}
|
|
|
|
condJSON, err := json.Marshal(req.Rule.Conditions)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
actJSON, err := json.Marshal(req.Rule.Actions)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
conditions, actions, err := unmarshalRuleConditionsActions(condJSON, actJSON)
|
|
return nil, conditions, actions, err
|
|
}
|
|
|
|
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
|
|
}
|