Skip to content

Rule Effects

Rule effects are the actions that rules execute in response to system events. A rule component returns one or more effects that instruct the system what operations to perform.

INFO

Current Effects: Available effects currently focus on actor commands and system operations. As new hook types are added (e.g., for files, registry), corresponding effects may be introduced.

WARNING

Effect Availability Varies by Hook: Not all effects work in all hooks. For example, validationError only works in Before hooks, while messageActor and scheduleJob typically work in After hooks. Always check the individual hook documentation in the Runtime Reference to see which effects are supported in each specific hook context.

Effect Categories

Actor Command Effects

Apply commands to specific actor types (current primary effect category):

orderCommand

Apply commands to orders:

filtrera
from {
  effect = 'orderCommand'
  type = 'createComputedOrderDiscount'
  componentId = 'free-shipping'
  description = 'Free Shipping'
  parameters = { threshold = '500' }
}

See Order Commands for available command types.

paymentCommand

Apply commands to payments:

filtrera
from {
  effect = 'paymentCommand'
  type = 'setDynamicFields'
  fields = {
    externalId = 'PAY-12345'
  }
}

See Payment Commands for available command types.

ticketCommand

Apply commands to tickets:

filtrera
from {
  effect = 'ticketCommand'
  type = 'assign'
  userId = 'user-123'
}

See Ticket Commands for available command types.

skuCommand

Apply commands to SKUs:

filtrera
from {
  effect = 'skuCommand'
  type = 'setDynamicFields'
  fields = {
    supplier = 'SUPPLIER-001'
  }
}

See Sku Commands for available command types.

assetCommand

Apply commands to assets:

filtrera
from [{
  effect = 'assetCommand'
  type = 'setDynamicFields'
  fields = {
    location = 'WAREHOUSE-A'
  }
}]

See Asset Commands for available command types.

System Operation Effects

messageActor

Send messages to other actors:

filtrera
from {
  effect = 'messageActor'
  actorType = 'order'
  actorId = '550e8400-e29b-41d4-a716-446655440000'
  messages = [{
    type = 'applyCommands'
    body = {
      commands = [{
        type = 'addTag'
        value = 'processed'
      }]
    }
  }]
}

Fields:

  • actorType - Type of actor (order, payment, ticket, sku, asset)
  • actorId - ID of the actor (or 'new' to create)
  • messages - Array of messages to send

scheduleJob

Schedule a job to run later:

filtrera
from {
  effect = 'scheduleJob'
  definition = 'process-order'
  at = datetime.now addHours 24
  parameters = {
    orderId = order.id
  }
}

Fields:

  • definition - Job definition/component ID
  • at - When to run (instant or nothing, defaults to immediate if omitted)
  • parameters - Parameters to pass (optional)

sendEmail

Queue an email for delivery:

filtrera
from {
  effect = 'sendEmail'
  to = input.order.invoiceAddress.email
  subject = 'Order Confirmation'
  body = {
    plainText = 'Thank you for your order!'
    html = '<h1>Thank you!</h1>'
  }
  category = 'order-confirmation'
  dynamic = { orderId = input.order.orderId :: text }
}

Fields:

  • to - Recipient email address (required)
  • subject - Email subject line (required)
  • body - Email body with plainText and/or html (at least one required)
  • cc - CC recipients array (optional)
  • bcc - BCC recipients array (optional)
  • from - Sender email address (optional, uses system default)
  • fromName - Sender display name (optional)
  • replyTo - Reply-to email address (optional)
  • category - Category for tracking (optional, defaults to 'rule')
  • dynamic - Custom metadata/tracking data (optional)

Custom Effect

custom

A pass-through effect that is not processed by the platform. Custom effects are designed for inter-rule communication via triggerHook. Hook listeners emit custom effects, and the calling rule collects them to decide what action to take.

filtrera
from {
  effect = 'custom'
  type = 'createReplacementOrder'
  productNumber = 'SKU-001'
  quantity = 1
}

Required Fields:

  • effect - Must be the literal 'custom'
  • type - A text identifier for the custom effect type

Additional fields are allowed — the record is open, so you can include any data the calling rule needs.

How it works:

  1. A parent rule calls triggerHook to trigger a secondary hook evaluation
  2. Hook listeners return effects — including custom effects
  3. The parent rule receives all effects as an iterator and decides what to do with them
filtrera
// Parent rule collects custom effects from hook listeners
let hookEffects = { orderId = order.id } triggerHook 'OnOrderValidated'

let replacements =
  hookEffects
  where e is { effect: 'custom', type: 'createReplacementOrder', productNumber: text, quantity: number }

// Parent decides how to handle them
from replacements select r => {
  effect = 'messageActor'
  actorType = 'order'
  actorId = 'new'
  messageType = 'create'
  body = { productNumber = r.productNumber, quantity = r.quantity }
}

TIP

Custom effects are silently ignored by the platform's effect processor. They only have meaning when collected by a calling rule via triggerHook.

Validation Effect

validationError

Prevent an operation and return an error:

filtrera
from {
  effect = 'validationError'
  code = 'INVALID_STATE'
  message = 'Operation not allowed in current state'
}

Fields:

  • code - Error code (string)
  • message - Error message (string)

Important: Only works in Before hooks. After hooks cannot prevent operations.

Effect Syntax

Single Effect

Return one effect:

filtrera
hook OnOrderCreated

from {
  effect = 'orderCommand'
  type = 'addTag'
  value = 'processed'
}

Multiple Effects

Return array of effects:

filtrera
hook OnOrderCreated

from [
  {
    effect = 'orderCommand'
    type = 'addTag'
    value = 'confirmed'
  },
  sendEmail {
    to = order.customer.email
    subject = 'Order Confirmed'
    body = { html = '<h1>Thank you!</h1>' }
    dynamic = {}
  }
]

No Effects

Return empty array when no effects needed:

filtrera
param input: OnOrderCreated

from input.order.total > 1000 match
  false |> []  // No effects
  true |> [{ effect = 'orderCommand', ... }]

Combining Effects

Rules can combine different effect types:

filtrera
param input: OnOrderCreated

from [
  // Add discount
  {
    effect = 'orderCommand'
    type = 'createComputedOrderDiscount'
    componentId = 'loyalty-discount'
    description = 'Loyalty Member Discount'
  },
  // Send email
  sendEmail {
    to = order.customer.email
    subject = 'Order Confirmed'
    body = { html = '<h1>Thank you!</h1>' }
    dynamic = { orderId = order.id }
  },
  // Schedule follow-up
  {
    effect = 'scheduleJob'
    definition = 'order-follow-up'
    at = datetime.now addDays 7
    parameters = { orderId = order.id }
  }
]

Common Patterns

Conditional Effects

Use pattern matching to conditionally execute effects:

filtrera
param input: OnOrderCreated

from order.total >= 500 match
  true |> {
    effect = 'orderCommand'
    type = 'addTag'
    value = 'high-value'
  }

Effect Based on Data

Build effects dynamically:

filtrera
param input: OnOrderCreated

let tags = input.order.total match
  when input.order.total >= 1000 |> ['high-value', 'priority']
  when input.order.total >= 500 |> ['high-value']
  |> []

from tags select tag => {
  effect = 'orderCommand'
  type = 'addTag'
  value = tag
}

Validation Errors

Prevent operations in before hooks:

filtrera
param input: OnOrderBeforeCreated

let errors = validateOrder(input.order)

from errors count > 0 match
  false |> []
  true |> errors select e => {
    effect = 'validationError'
    code = e.code
    message = e.message
  }

See Also

© 2024 Hantera AB. All rights reserved.