ultisuite-backend/internal/mail/rules/simulate.go
R3D347HR4Y cd0a80f5e8 huhu
2026-05-25 13:52:27 +02:00

72 lines
2.2 KiB
Go

package rules
import (
"context"
"fmt"
"github.com/ultisuite/ulti-backend/internal/mail/webhooks"
)
type SimulatedActionResult struct {
ActionResult
SimulatedPayload string `json:"simulated_payload,omitempty"`
}
type SimulationResult struct {
Matched bool `json:"matched"`
Actions []SimulatedActionResult `json:"actions,omitempty"`
}
func (e *Engine) SimulateRule(ctx context.Context, conditions []Condition, actions []Action, msg *Message) SimulationResult {
if !matchesAll(conditions, msg) {
return SimulationResult{Matched: false}
}
return SimulationResult{
Matched: true,
Actions: e.simulateActions(ctx, actions, msg),
}
}
func (e *Engine) simulateActions(ctx context.Context, actions []Action, msg *Message) []SimulatedActionResult {
results := make([]SimulatedActionResult, 0, len(actions))
for _, action := range actions {
results = append(results, e.simulateAction(ctx, action, msg))
}
return results
}
func (e *Engine) simulateAction(ctx context.Context, action Action, msg *Message) SimulatedActionResult {
switch action.Type {
case "label", "move", "archive", "delete", "mark_read", "remove_label", "mark_important", "mark_spam", "star", "notify", "reply", "send_mail", "forward":
return SimulatedActionResult{
ActionResult: ActionResult{Type: action.Type, Value: action.Value, OK: true},
}
case "webhook":
if e.db == nil {
return SimulatedActionResult{
ActionResult: actionResultFrom(action, fmt.Errorf("webhook simulation unavailable")),
}
}
var bodyTemplate string
err := e.db.QueryRow(ctx, `
SELECT body_template
FROM webhook_templates
WHERE id = $1 AND is_active = true
`, action.Value).Scan(&bodyTemplate)
if err != nil {
return SimulatedActionResult{
ActionResult: actionResultFrom(action, fmt.Errorf("query template: %w", err)),
}
}
payload := webhooks.RenderBodyTemplate(bodyTemplate, messageToWebhookContext(msg))
return SimulatedActionResult{
ActionResult: ActionResult{Type: action.Type, Value: action.Value, OK: true},
SimulatedPayload: payload,
}
default:
return SimulatedActionResult{
ActionResult: actionResultFrom(action, fmt.Errorf("unknown action type: %s", action.Type)),
}
}
}