A trigger is the foundation of workflow automation in the Thena platform. It consists of two key components: an event and filters. While events represent what happened, triggers allow you to specify exactly when a workflow should execute based on those events.

Understanding triggers

Core concept

A trigger is a combination of an event and optional filters. Events tell us what happened (e.g., “ticket created”), while filters let us specify precise conditions about when we care about that event (e.g., “only when the ticket priority is high”).

Event types

System events

• Ticket events: Created, updated, status changed
• User events: Created, updated, permissions changed
• Team events: Created, members changed
• Account events: Created, updated, status changed

Integration events

• Slack events: Message sent, channel created
• Email events: Received, sent, bounced
• Custom app events: Any app-specific events
• Scheduled events: Time-based triggers

Event anatomy

An event in the Thena Platform consists of several key components that define its structure and behavior.

Key components

Core properties

uid: Unique identifier for the event
eventName: Human-readable name
eventType: Machine-readable type (e.g., ticket:updated)
source: Origin of the event
description: Human-readable description

Schema structure

message: Core event data including actor and payload
messageAttributes: Context and metadata about the event
required fields: Mandatory data points
properties: Data type definitions and validations

Event data structure

Events follow a consistent structure that enables:

  • Rich context through nested properties
  • Type safety with JSON schema validation
  • Clear audit trail with actor and timestamp information
  • Flexible data access through dot notation in filters

Here’s a comprehensive example of a ticket update event:

{
  "uid": "D0DN56NJ10C3RJJG1TGR3D86HM0S8",
  "description": "This event is triggered when a ticket is updated",
  "eventName": "Ticket updated",
  "source": "platform_app",
  "eventType": "ticket:updated",
  "schema": {
    "type": "object",
    "required": ["message", "messageAttributes"],
    "properties": {
      "message": {
        "type": "object",
        "required": ["actor", "orgId", "eventId", "payload", "eventType", "timestamp"],
        "properties": {
          "actor": {
            "type": "object",
            "required": ["email", "id", "type"],
            "properties": {
              "id": { "type": "string" },
              "type": { "type": "string" },
              "email": { "type": "string" }
            }
          },
          "payload": {
            "type": "object",
            "required": ["previousTicket", "ticket"],
            "properties": {
              "ticket": {
                "type": "object",
                "required": ["id", "title", "teamId"],
                "properties": {
                  "id": { "type": "string" },
                  "title": { "type": "string" },
                  "teamId": { "type": "string" }
                  // ... additional ticket properties
                }
              },
              "previousTicket": {
                "type": "object",
                "required": ["id", "title", "teamId"]
                // ... same structure as ticket
              }
            }
          }
        }
      },
      "messageAttributes": {
        "type": "object",
        "required": [
          "event_name",
          "event_id",
          "event_timestamp",
          "context_user_id",
          "context_user_type",
          "context_organization_id"
        ]
        // ... attribute properties
      }
    }
  },
  "metadata": {
    "entityType": "Ticket",
    "pathToTeamId": "context.event.message.payload.ticket.teamId",
    "pathToAnnotate": "context.event.message.payload.ticket",
    "requiredFields": {
      "ticketId": "{{context.event.message.payload.ticket.id}}"
    }
  }
}

Trigger components

Event definition

NameTypeOptionsComments
Event NamestringRequired, Format: app:eventUnique event identifier
Event SchemaobjectRequiredJSON Schema of event data
Event DataobjectRequiredActual event payload
SourcestringRequiredEvent origin identifier
TimestampdatetimeRequiredEvent occurrence time

Filter operators

Filters in triggers allow you to specify precise conditions for when a workflow should execute. The platform supports a comprehensive set of operators:

Comparison operators

OperatorDescriptionExample
~eqEquals{"priority": {"~eq": "high"}}
~neqNot equals{"status": {"~neq": "closed"}}
~gtGreater than{"value": {"~gt": 100}}
~gteGreater than or equal{"age": {"~gte": 18}}
~ltLess than{"count": {"~lt": 5}}
~lteLess than or equal{"score": {"~lte": 10}}

Collection operators

OperatorDescriptionExample
~inIn array{"status": {"~in": ["open", "pending"]}}
~ninNot in array{"type": {"~nin": ["internal", "test"]}}

String operators

OperatorDescriptionExample
~regexMatches regex{"email": {"~regex": ".*@company\\.com"}}
~nregexDoes not match regex{"url": {"~nregex": ".*\\.test\\.com"}}
~startsStarts with{"name": {"~starts": "Test"}}
~nstartsDoes not start with{"ref": {"~nstarts": "DRAFT"}}
~endsEnds with{"email": {"~ends": "@thena.ai"}}
~nendsDoes not end with{"path": {"~nends": ".tmp"}}
~containsContains{"description": {"~contains": "urgent"}}
~ncontainsDoes not contain{"title": {"~ncontains": "test"}}

Special operators

OperatorDescriptionExample
~isnullIs null{"assignee": {"~isnull": true}}
~isemptyIs empty{"tags": {"~isempty": true}}

Logical operators

OperatorDescriptionExample
~andAll conditions must match{"~and": [{"status": {"~eq": "open"}}, {"priority": {"~eq": "high"}}]}
~orAny condition must match{"~or": [{"type": {"~eq": "bug"}}, {"priority": {"~eq": "high"}}]}

Filter operators can be combined to create complex conditions. The platform evaluates them in a deterministic order, with logical operators (~and, ~or) being evaluated last.

Example trigger

{
  "name": "Change status to Waiting on Customer when an agent replies",
  "triggerEvent": "ticket:comment:created",
  "filters": {
    "~and": [
      {
        "{{context.event.message.payload.comment.teamId}}": {
          "~eq": "T66CEQQJXZ"
        }
      },
      {
        "~and": [
          {
            "~and": [
              {
                "{{ context.event.message.payload.ticket.status.name }}": {
                  "~neq": "Waiting on customer"
                }
              },
              {
                "{{ context.event.message.payload.comment.customerContact }}": {
                  "~isEmpty": true
                }
              },
              {
                "{{ context.event.message.payload.comment.commentVisibility }}": {
                  "~eq": "public"
                }
              },
              {
                "{{ context.event.message.payload.comment.commentType }}": {
                  "~eq": "comment"
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

This example demonstrates:

  • Using context variables with dot notation to access nested properties
  • Combining multiple logical operators
  • Checking for specific team, status, and comment properties
  • Using various comparison and special operators

Platform events reference

Events are real-time notifications that your application can listen to when specific actions occur in the Thena platform. Each event contains metadata about when and where it was triggered, along with relevant payload data.

Event structure

All events in the Thena platform follow a consistent base structure:

{
  "event_id": "evt_123abc456def",
  "event_type": "ticket:created",
  "timestamp": "2025-01-26T12:34:56Z",
  "org_id": "org_789xyz",
  "team_id": "team_123abc",
  "actor": {
    "id": "usr_456def",
    "type": "user"
  },
  "payload": {
    // Event-specific data
  }
}

Available events

Organization events

  • org:created - When a new organization is created
  • org:updated - When organization details are updated
  • org:deleted - When an organization is deleted
  • org:settings:updated - When organization settings are modified

Team events

  • team:created - When a new team is created
  • team:updated - When team details are updated
  • team:deleted - When a team is deleted
  • team:member:added - When a member is added to a team
  • team:member:removed - When a member is removed from a team

User events

  • user:created - When a new user is created
  • user:updated - When user details are updated
  • user:deleted - When a user is deleted
  • user:status:changed - When a user’s status changes
  • user:role:changed - When a user’s role is modified
  • user:login - When a user logs in
  • user:logout - When a user logs out

Ticket events

  • ticket:created - When a new ticket is created
  • ticket:updated - When ticket details are updated
  • ticket:deleted - When a ticket is deleted
  • ticket:status:changed - When a ticket’s status changes
  • ticket:assigned - When a ticket is assigned
  • ticket:unassigned - When a ticket is unassigned
  • ticket:priority:changed - When a ticket’s priority changes
  • ticket:comment:added - When a comment is added to a ticket
  • ticket:comment:updated - When a comment is updated
  • ticket:comment:deleted - When a comment is deleted
  • ticket:reaction:added - When a reaction is added to a ticket
  • ticket:reaction:removed - When a reaction is removed from a ticket
  • ticket:comment:reaction:added - When a reaction is added to a comment
  • ticket:comment:reaction:removed - When a reaction is removed from a comment

Account events

  • account:created - When a new account is created
  • account:updated - When account details are updated
  • account:deleted - When an account is deleted
  • account:status:changed - When an account’s status changes

Customer events

  • customer:created - When a new customer is created
  • customer:updated - When customer details are updated
  • customer:deleted - When a customer is deleted
  • customer:merged - When customer records are merged

Custom field events

  • custom_field:created - When a new custom field is created
  • custom_field:updated - When a custom field is updated
  • custom_field:deleted - When a custom field is deleted
  • custom_field:value:changed - When a custom field value changes

Form events

  • form:created - When a new form is created
  • form:updated - When a form is updated
  • form:deleted - When a form is deleted
  • form:submission:created - When a form submission is received
  • form:submission:updated - When a form submission is updated

SLA events

  • sla:created - When a new SLA policy is created
  • sla:updated - When an SLA policy is updated
  • sla:deleted - When an SLA policy is deleted
  • sla:breach:warning - When an SLA is about to breach
  • sla:breach:occurred - When an SLA breach occurs

Workflow events

  • workflow:created - When a new workflow is created
  • workflow:updated - When a workflow is updated
  • workflow:deleted - When a workflow is deleted
  • workflow:executed - When a workflow starts execution
  • workflow:step:completed - When a workflow step is completed
  • workflow:completed - When a workflow execution completes

CSAT events

  • csat:survey:sent - When a CSAT survey is sent
  • csat:response:received - When a CSAT response is received
  • csat:feedback:updated - When CSAT feedback is updated

App events

  • app:installed - When an app is installed in a workspace
  • app:uninstalled - When an app is uninstalled from a workspace
  • app:reinstalled - When an app is reinstalled in a workspace
  • app:mentioned - When an app is mentioned in a conversation
  • app:settings:updated - When app settings are modified

Source integration events

Slack events
  • source:slack:message:received - When a message is received from Slack
  • source:slack:thread:created - When a new thread is created in Slack
  • source:slack:reaction:added - When a reaction is added in Slack
MS Teams events
  • source:msteams:message:received - When a message is received from MS Teams
  • source:msteams:thread:created - When a new thread is created in MS Teams
  • source:msteams:reaction:added - When a reaction is added in MS Teams
Email events
  • source:email:received - When an email is received
  • source:email:bounced - When an email bounces
  • source:email:replied - When an email is replied to
Widget events
  • source:widget:opened - When the widget is opened
  • source:widget:message:sent - When a message is sent via widget
  • source:widget:closed - When the widget is closed

Event delivery and retries

Events are delivered in real-time with automatic retries on failure:

  1. First attempt: Immediate delivery
  2. Second attempt: After 3 minutes
  3. Final attempt: After 5 minutes

Your webhook endpoint must respond within 3 seconds, or the request will time out and trigger the retry mechanism.

Design your event handlers to be idempotent as you may receive the same event multiple times during retries.

Best practices for event consumers

Handling events reliably

  • Implement idempotency checks: Store processed event IDs to avoid duplicate processing during retries
  • Use event timestamps: Process events in chronological order using the timestamp field
  • Validate event data: Always validate the event payload before processing to handle schema changes gracefully

Performance optimization

  • Process asynchronously: Handle events in background workers to avoid blocking your main application
  • Batch related operations: Group related database updates or API calls for better performance
  • Set reasonable timeouts: Acknowledge webhooks within 3 seconds and process heavy tasks asynchronously
  • Queue long-running tasks: If processing takes longer than 3 seconds, acknowledge the webhook and process in background

Error handling

  • Log processing errors: Include event ID and type in error logs for easier debugging
  • Implement dead letter queues: Store failed events separately for manual review
  • Monitor processing delays: Set up alerts for event processing backlogs

Security

  • Validate webhook signatures: Use the provided signature to verify event authenticity
  • Secure API keys: Store webhook secret keys in secure environment variables
  • Filter by event types: Subscribe only to events your application needs

Testing

  • Use the event simulator: Test your handlers with simulated events before going live
  • Verify retry handling: Test your idempotency logic with duplicate events
  • Monitor event processing: Track success rates and processing times in production

Remember to version your event handlers to handle potential schema changes in future platform updates.

Example event payloads