Event-Driven Scripts
Event-driven scripts automatically execute when specific events occur in your Mirra account. Scripts subscribe to events from integrated services like Telegram, Gmail, Google Calendar, voice calls, and crypto transactions, with support for complex filtering conditions to control when execution occurs.
Syntax
Creating an Event Subscription
Basic Subscription
Filtered Subscription
Multiple Conditions
Description
Event-driven scripts enable reactive automation by executing scripts in response to real-time events from integrated services. When an event occurs, the Mirra platform checks all active subscriptions, evaluates filter conditions, and executes matching scripts with the event data.
All events follow a standardized structure defined in @mirra/shared-types/events, ensuring consistent access patterns across different event types. The structure uses clear nesting with integration-specific data in typed objects, eliminating vague field names and minimizing optional fields.
Event Flow
Event Subscriptions
Scripts create subscriptions to specific event types with optional filtering conditions. Each subscription specifies:
- Event type - The specific event to subscribe to (e.g.,
telegram.message) - Conditions - Optional filters using field paths, operators, and values
- Enabled status - Whether the subscription is currently active
Subscriptions are created via the SDK API:
Event Data Structure
All events extend BaseIntegrationEvent and include integration-specific fields:
Standardized Fields
Every event includes these standardized fields for consistent access:
id(string)Unique event identifier.
type(EventType)Event type identifier (e.g.,
'telegram.message','gmail.email_received').source(EventSource)Integration source (e.g.,
'telegram','google-gmail').timestamp(Date)When the event occurred in the Mirra system.
userId(string)User ID who owns this event. Always present.
content.text(string)Main text content. Works across all event types. Empty string if no text.
content.contentType(ContentType)Type of content:
'message','email','calendar_event','call','document', or'transcript'.content.timestamp(Date)When the content was created in the source system.
actor.id(string)ID of who created this event. Empty string for system-generated events.
actor.name(string)Display name of the actor. "System" for system-generated events.
actor.actorType(ActorType)Type of actor:
'user','bot','system','calendar', or'email'.context(ChannelContext | null)Where the event occurred. Null for system events without channel context.
Field Type Description context.channelIdstring Chat ID, thread ID, call ID, etc. context.channelNamestring Human-readable channel name context.channelTypeChannelType 'direct_message', 'group_chat', 'channel', 'email_thread', 'call' entity(EntityData)Graph entity data for memory and knowledge graph integration. Always present.
Integration-Specific Fields
Each event type includes additional fields specific to its integration:
- Telegram events -
telegramobject with chat ID, message ID, media info - Gmail events -
gmailobject with message ID, thread ID, subject, recipients - Calendar events -
calendarobject with event ID, times, attendees - Voice call events -
callobject with call ID, participants, duration - Crypto events -
cryptoobject with token address, chain, price
See the integration-specific documentation for complete field listings.
Accessing Event Data
Scripts receive events with both standardized and integration-specific fields:
Event Enrichment
Many events support automatic content enrichment through stream processing:
enrichment(EventEnrichment | null)Enrichment data added by stream processing. Null until processing completes.
Field Type Description enrichment.tickersTickerMention[] Detected stock/crypto ticker symbols enrichment.sentimentSentimentAnalysis | null Sentiment score (-1 to 1), label, confidence enrichment.companiesstring[] Detected company names enrichment.topicsstring[] Extracted topics enrichment.privacyobject Privacy controls (isPublic, anonymizationLevel, allowedAggregations) enrichment.streamobject Stream metadata (timestamps, partition, processingVersion)
Events that support enrichment:
telegram.messagetelegram.commandgmail.email_receivedgoogle-docs.document_updatedtranscript.chunk
Example:
Filtering Events
Event subscriptions support complex filtering with field-level conditions. Multiple conditions use AND logic by default.
Condition Operators
String Operators
| Operator | Description | Example |
|---|---|---|
equals | Exact match | {"field": "type", "operator": "equals", "value": "telegram.message"} |
not_equals | Not equal | {"field": "actor.name", "operator": "not_equals", "value": "Bot"} |
contains | Contains substring | {"field": "content.text", "operator": "contains", "value": "$"} |
not_contains | Doesn't contain | {"field": "content.text", "operator": "not_contains", "value": "spam"} |
starts_with | Starts with prefix | {"field": "content.text", "operator": "starts_with", "value": "/"} |
ends_with | Ends with suffix | {"field": "content.text", "operator": "ends_with", "value": "?"} |
Numeric Operators
| Operator | Description | Example |
|---|---|---|
greater_than | Greater than | {"field": "crypto.priceUsd", "operator": "greater_than", "value": 100} |
less_than | Less than | {"field": "call.durationSeconds", "operator": "less_than", "value": 300} |
greater_than_or_equal | Greater or equal | {"field": "enrichment.tickers.length", "operator": "greater_than_or_equal", "value": 1} |
less_than_or_equal | Less or equal | {"field": "call.durationSeconds", "operator": "less_than_or_equal", "value": 600} |
Existence Operators
| Operator | Description | Example |
|---|---|---|
exists | Field exists | {"field": "enrichment.tickers", "operator": "exists"} |
not_exists | Field doesn't exist | {"field": "error", "operator": "not_exists"} |
Array Operators
| Operator | Description | Example |
|---|---|---|
in | Value in array | {"field": "type", "operator": "in", "value": ["call.started", "call.ended"]} |
not_in | Value not in array | {"field": "status", "operator": "not_in", "value": ["error", "timeout"]} |
Logical Operators
| Operator | Description | Example |
|---|---|---|
and | All conditions must match | {"operator": "and", "conditions": [...]} |
or | Any condition must match | {"operator": "or", "conditions": [...]} |
Complex Filtering Examples
Multiple conditions (AND):
OR conditions:
Nested conditions:
Managing Subscriptions
List Subscriptions
Retrieve all subscriptions for a script:
Update Subscription
Modify an existing subscription:
Delete Subscription
Remove a subscription:
Available Event Types
Communication Events
- Telegram - Messages, commands, media
- Gmail - Emails received and sent
- Voice Calls - Calls, transcripts, summaries
Productivity Events
- Google Calendar - Events created, updated, deleted
- Google Docs - Document changes
- Google Drive - File updates
- Google Sheets - Spreadsheet changes
System Events
- Assignments - Scheduled executions, auto-pausing
- Activity Feed - Feed item creation
Financial Events
- Crypto - Price alerts, transactions, swaps
Execution Limits
Daily Limits
Scripts enforce daily execution limits configured in the script settings:
Once the limit is reached, the script stops executing until the next day (UTC midnight).
Cost Limits
Scripts also enforce per-execution cost limits:
Executions exceeding this cost fail with a cost limit error.
Best Practices
Be Specific with Filters
Use specific conditions to avoid unnecessary executions:
Handle Missing Fields
Always check for field existence before accessing:
Use Appropriate Execution Limits
Set limits based on expected event volume:
Test Before Enabling
Create subscriptions as disabled, test manually, then enable:
See Also
- Creating Scripts - Script structure and configuration
- Quickstart Guide - Create your first script
- Resources - Access external APIs from scripts
- SDK API Reference - Complete API documentation