10.2 Event-Driven Architectures
Multi-stage pipelines process data sequentially. But how does data enter the pipeline? Often through events—external occurrences that trigger automation. This section shows you how to build event-driven architectures where external events automatically start your workflows.
What Is Event-Driven Architecture?
Traditional vs Event-Driven
Traditional approach (manual trigger):
You manually add row
↓
Pipeline processes data
↓
Results produced
↓
You review and take actionEvent-driven approach (automatic trigger):
External event happens
↓
System automatically creates row
↓
Pipeline processes automatically
↓
Results appear without your involvementKey difference: Automation starts without human intervention
Real-World Analogy: Security System
Traditional security:
- You check cameras every hour
- You decide if something is wrong
- You call police if needed
Event-driven security (alarm system):
- Motion sensor detects movement (event)
- Alarm triggers automatically (event handler)
- System calls police automatically (event response)
- You get notified after action taken
Benefits: Instant response, 24/7 monitoring, no manual checking
In Taibles
Event-driven architecture means:
- Event source: External system (email, webhook, schedule, file upload)
- Event handler: Trigger listens for events
- Event processing: Trigger creates row with event data
- Automation pipeline: Columns process the new row
- Event response: Actions based on event (email reply, API call, notification)
Example flow:
Customer emails support@company.com (EVENT)
↓
Email trigger detects email (HANDLER)
↓
Creates support ticket row (PROCESSING)
↓
Auto-classification, assignment, response (PIPELINE)
↓
Reply sent to customer (RESPONSE)Result: Complete support automation without manual intervention
Core Concepts
Concept 1: Events Are External Occurrences
What qualifies as an event?
✅ Yes (external events):
- Email received
- Webhook called by external service
- Scheduled time reached (cron)
- File uploaded
- Form submitted
- API called by third party
❌ No (internal state changes):
- Column calculates value
- Row updated manually
- Dependency completes
Key: Events originate outside your taible
Concept 2: Event Handlers (Triggers)
Triggers are event handlers that:
- Listen for specific events
- Capture event data
- Create rows automatically
Types available (70+ integrations):
- Email Triggers: IMAP, Gmail, Outlook
- Webhook Trigger: HTTP calls from external services
- Scheduled Trigger: Runs on schedule (cron)
- Form Triggers: Google Forms, Typeform, Jotform
- Service-Specific Triggers: Shopify, Stripe, HubSpot, Salesforce, and 60+ more
Each trigger type creates rows automatically when event occurs
Concept 3: Event Data Capture
When event occurs, trigger captures:
Email event captures:
- From address
- Subject line
- Body content
- Attachments
- Timestamp
- Thread ID (for replies)
Webhook event captures:
- HTTP headers
- Request body (JSON/form data)
- Query parameters
- Source IP
- Timestamp
Scheduled event captures:
- Execution time
- Schedule definition
- Iteration count
All captured data → Stored in columns → Available to pipeline
Concept 4: Event Processing Pipeline
After row created, standard pipeline executes:
Trigger creates row
↓
Dependent columns execute
↓
Dependencies → Conditions → Processing
↓
Results producedSame principles as multi-stage pipelines (Section 10.1)
Difference: Pipeline triggered by event (not manual row creation)
Concept 5: Event Responses
Pipeline can respond to events:
- Send email reply
- Call webhook (notify external system)
- Update database
- Create rows in other taibles
- Trigger other automations
Creates feedback loop: Event → Process → Respond → (possibly trigger new event)
Example Architecture: Customer Support Automation
Let's build a complete event-driven support system.
Business Scenario
Challenge: Support inbox overwhelmed with emails
Goal: Automate ticket creation, classification, assignment, and response drafting
Event flow:
- Customer sends email to support@company.com
- Email triggers ticket creation
- System classifies issue
- System assigns to agent
- System drafts response
- Agent reviews and approves
- Response sent to customer
- Customer replies (new event)
- System updates ticket
- Agent notified
Result: 80% faster ticket handling, zero manual ticket creation
Implementation: Support Ticket System
Architecture Overview
Taible: Support Tickets
Trigger: IMAP (monitors support@company.com)
Event: Email received
Pipeline Stages:
- Data extraction (from email)
- Classification (LLM categorizes issue)
- Priority determination (LLM assesses urgency)
- Assignment (route to appropriate agent)
- Response generation (LLM drafts reply)
- Manual approval (agent reviews)
- Response sending (SMTP)
Step 1: Create Support Tickets Taible
Create new taible:
Click "Create Taible" button
Name: "Support Tickets"
Description: "Event-driven support ticket management"
Click "Create"
Step 2: Add IMAP Trigger
Set up email monitoring:
- Click "Add Trigger" button in taible toolbar
Add Trigger
IMAP Email
EmailMonitor any IMAP email inbox for new messages
Gmail
EmailConnect to Gmail and receive new emails
Tip: In this example, we'll select the IMAP trigger to monitor our support email inbox. This allows us to automatically create a new row whenever an email arrives.
- Select "IMAP" trigger type from the categorized list
Configure IMAP Trigger
Connection Details
Monitoring Settings
Row Creation Behavior
Configure trigger:
Connection details:
- Server:
imap.gmail.com(or your email provider) - Port:
993 - Email:
support@company.com - Password: (app password)
- Use SSL: Yes
Monitoring:
- Folder: INBOX
- Check interval: Every 1 minute
- Mark as read: Yes
Row creation:
- Create row: On new email
- Thread handling: Update existing row if same thread
- Server:
Save trigger configuration
Result: Trigger monitors inbox, creates row for each new email
Step 3: Create Data Extraction Columns
Columns to add:
| Column Name | Type | Purpose |
|---|---|---|
email_data | Trigger Output | Raw email data from IMAP |
sender | Custom Code | Extract sender email |
subject | Custom Code | Extract subject |
body | Custom Code | Extract body text |
thread_id | Custom Code | Extract thread identifier |
Column: sender
sender
Custom CodeExtract sender email and name from email data
Run Mode "Once": This column will execute once when its dependencies (email_data) have values. It won't recalculate unless you manually trigger it.
Configuration:
- Type: Custom Code
- Dependencies:
email_data - Run mode: Once
Code (extracts sender information):
def emailData = data['']['']['email_data']
if (!emailData) return null
// Extract sender
def from = emailData.from
def senderEmail = from instanceof String ? from : from?.address ?: 'unknown'
// Parse name if available
def senderName = from?.name ?: senderEmail.split('@')[0]
return [
email: senderEmail,
name: senderName,
display: "${senderName} <${senderEmail}>"
]Column: subject
Configuration:
- Type: Custom Code
- Dependencies:
email_data - Run mode: Once
Code (extracts subject line):
def emailData = data['']['']['email_data']
return emailData?.subject ?: 'No Subject'Column: body
Configuration:
- Type: Custom Code
- Dependencies:
email_data - Run mode: Once
Code (extracts and cleans email body):
def emailData = data['']['']['email_data']
def body = emailData?.textBody ?: emailData?.htmlBody ?: ''
// Clean HTML if needed
if (body.contains('<html')) {
// Basic HTML stripping
body = body.replaceAll(/<[^>]+>/, '')
}
return bodyStep 4: Create Classification Columns
Columns for AI classification:
| Column Name | Type | Dependencies | Purpose |
|---|---|---|---|
category | LLM | subject, body | Classify issue type |
priority | LLM | subject, body, category | Determine urgency |
sentiment | LLM | body | Analyze customer emotion |
Column: category
Configuration:
- Type: LLM (GPT-4 or similar)
- Dependencies:
subject,body - Run mode: Once
Prompt (classifies support issue):
Classify this support email into ONE of these categories:
- Technical Issue
- Billing Question
- Feature Request
- General Inquiry
- Complaint
Subject: [Subject Line]
Body: [Email Body]
Return ONLY the category name, nothing else.💡 How Prompts Work
You don't need to write code to insert the data—just reference the column names in your prompt, and the system handles the rest.
Column: priority
Configuration:
- Type: LLM
- Dependencies:
subject,body,category - Run mode: Once
Prompt (determines urgency):
Determine the priority level for this support ticket:
Subject: [Subject Line]
Body: [Email Body]
Category: [Category]
Priority levels:
- URGENT: System down, critical issue, angry customer
- HIGH: Important problem affecting work
- MEDIUM: Standard request or question
- LOW: General inquiry, feature request
Return ONLY the priority level (URGENT, HIGH, MEDIUM, or LOW).Step 5: Create Assignment Logic
Column: assigned_agent
Configuration:
- Type: Custom Code
- Dependencies:
category,priority - Run mode: Once
Code (assigns to appropriate team):
def category = data['']['']['category']
def priority = data['']['']['priority']
def assignment = [:]
// Assign based on category
switch (category) {
case 'Technical Issue':
assignment.agent = 'Tech Support Team'
assignment.team = 'Technical'
break
case 'Billing Question':
assignment.agent = 'Billing Team'
assignment.team = 'Finance'
break
case 'Feature Request':
assignment.agent = 'Product Team'
assignment.team = 'Product'
break
default:
assignment.agent = 'General Support'
assignment.team = 'Support'
}
// Escalate if urgent
if (priority == 'URGENT') {
assignment.escalated = true
assignment.agent = 'Senior ' + assignment.agent
}
assignment.assigned_at = new Date().toString()
return assignment💡 Smart Routing
The beauty of event-driven architecture: All this happens within seconds of the email arriving, with zero manual work.
Step 6: Create Response Generation
Column: response_draft
Configuration:
- Type: LLM
- Dependencies:
sender,subject,body,category,priority - Run mode: Once
Prompt (generates professional response):
Generate a professional support email response for this ticket:
From: [Sender Name and Email]
Subject: [Subject Line]
Body: [Email Body]
Category: [Issue Category]
Priority: [Priority Level]
Write a helpful, empathetic response that:
1. Acknowledges their issue
2. Provides relevant information or next steps
3. Sets expectations for resolution time
4. Maintains professional but friendly tone
5. Includes appropriate sign-off
Response:Step 7: Create Manual Approval & Send
Column: response_approved
Configuration:
- Type: Toggle (Boolean)
- Manual entry: Yes
Purpose: Agent reviews draft, clicks toggle to approve
Agent Review Step
⏸ Awaiting approval. Toggle to send the response.
Column: response_sent
Configuration:
- Type: SMTP (Send Email)
- Dependencies:
response_draft,response_approved - Condition: Only run when response_approved is checked
- Run mode: Once
SMTP Configuration:
- To: [Sender Email]
- From: support@company.com
- Subject: Re: [Original Subject]
- Body: [Response Draft]
- In-Reply-To: [Thread ID] (maintains thread)
SMTP Column Configuration
Send EmailHow Email Sending Works:
- The system automatically inserts data from other columns (like sender email, original subject, response draft)
- You write placeholders like [Sender Email] in the configuration
- When the column executes, it replaces placeholders with actual values
- The Thread ID ensures the reply appears in the same conversation
Condition: This column only runs when "response_approved" is checked (true).
Step 8: Add Status Tracking
Column: status
Configuration:
- Type: Custom Code
- Dependencies:
response_sent,response_approved - Run mode: Always
Code (tracks ticket status):
def responseSent = data['']['']['response_sent']
def approved = data['']['']['response_approved']
if (responseSent) {
return 'RESPONDED'
} else if (approved) {
return 'APPROVED_PENDING_SEND'
} else {
return 'AWAITING_REVIEW'
}Ticket Status Indicators
The status column automatically updates based on the workflow state:
Automatic Status Tracking: The status column uses "Run Mode: Always" so it updates every time its dependencies change. This gives you real-time visibility into each ticket's progress through the workflow.
Complete Event Flow
Flow 1: New Ticket Creation
Event: Customer emails support@company.com
Complete Automation Flow: Email to Response
Email Arrives
0-60 secIMAP trigger detects new email in support@company.com inbox
Subject: Unable to login to account
Row Created
InstantNew row automatically added to Support Tickets taible with email data
Data Extraction
~1 secColumns parse email data: sender, subject, body, thread_id
AI Classification
~5 secLLM analyzes email and determines category, priority, sentiment
Auto-Assignment
InstantTicket routed to appropriate team based on category and priority
Response Generation
~8 secLLM drafts professional, empathetic response tailored to the issue
Ready for Review
Awaiting AgentAgent receives notification, reviews draft, makes edits if needed, approves
Email Sent
CompleteResponse automatically sent when agent toggles approval
Total Automation Time: ~15 seconds
From email arrival to response ready for approval, the entire pipeline executes in under 15 seconds. Agent only reviews final draft—no data entry, categorization, or assignment needed.
Automated steps:
- IMAP trigger detects email (within 1 minute)
- Creates new row in Support Tickets taible
email_datacolumn populated with email content- Stage 1 (Extraction): Sender, subject, body extracted
- Stage 2 (Classification): LLM classifies category, priority, sentiment
- Stage 3 (Assignment): Auto-assigned to appropriate agent
- Stage 4 (Response): LLM generates response draft
- Stage 5 (Approval): Status shows "Awaiting Review"
Agent action:
- Notification received (via dashboard or email)
- Reviews ticket in taible
- Reads customer email and response draft
- Edits draft if needed (directly in the column)
- Clicks approval toggle
Automated completion: 6. response_sent column executes (sends email) 7. status updates to "Responded"
Total time: 1-2 minutes from email received to response ready for approval
Flow 2: Customer Reply (Thread Continuation)
Event: Customer replies to support email
Automated steps:
- IMAP trigger detects reply
- Matches thread ID to existing ticket
- Updates existing row (doesn't create new)
- Updates
email_datawith new message - Could trigger additional columns:
- Extract new message text
- Append to message history
- Analyze sentiment change
- Re-prioritize if needed
- Notify assigned agent
Key feature: Thread continuity maintained automatically
💡 Conversation Continuity
This means your entire conversation history stays in one place, making it easy for agents to understand the full context.
Sub-Taible for Message History
Purpose
Track all messages in a ticket (initial email + all replies)
Setup
Create sub-taible:
In Support Tickets taible, click column header "+"
Select "Sub-Taible" column type
Configure:
- Column name:
messages - Display label: "Message History"
- Sub-taible name: "Ticket Messages"
- Column name:
Add columns to sub-taible:
message_body(Text)sender(Text) - "customer" or "agent"timestamp(Text)sentiment(LLM) - Analyze message sentiment
Add Messages Automatically
Column in parent (Support Tickets): log_new_message
Configuration:
- Type: Add Row (to sub-taible)
- Dependencies:
email_data,sender,body - Run mode: Always
Configuration:
- Target taible: Ticket Messages (sub-taible)
- Mappings:
message_body→ [Email Body]sender→ "customer"timestamp→ [Current Time]
Result: Each email automatically logged as message in sub-taible
Event-Driven Patterns
Pattern 1: Reactive Processing
Trigger: External event starts process
Example: Email → Ticket → Classification → Response
Use when: Responding to external stimuli
Pattern 1: Reactive Processing
Best for: Customer communication, support systems, form submissions—any scenario where you need to respond immediately to external input.
Pattern 2: Scheduled Processing
Trigger: Time-based event starts process
Example: Every night at midnight → Generate daily report
Use when: Regular batch operations
Pattern 2: Scheduled Processing
Common Schedules
- • Daily reports (midnight)
- • Weekly summaries (Monday 9 AM)
- • Monthly invoices (1st of month)
- • Hourly status checks
Best for: Reports, backups, cleanup tasks, batch processing—anything that needs to run regularly on a predictable schedule.
Pattern 3: Webhook Integration
Trigger: External service calls webhook → Creates row
Example: Stripe payment → Payment record → Invoice sent
Use when: Integrating with SaaS platforms
Pattern 3: Webhook Integration
Example: Stripe Payment Webhook
{ "event": "payment.succeeded", "amount": 9900, "customer": "cus_123" }
Popular Webhook Integrations
Best for: Integrating with SaaS platforms and external services. Webhooks enable real-time two-way communication between systems.
Pattern 4: Chained Events
One event triggers another:
Event 1: Email received
↓
Response sent
↓ (triggers Event 2)
Customer reply received
↓
Update ticket
↓ (triggers Event 3)
Escalation needed
↓
Notification sentUse when: Complex multi-step workflows
Pattern 5: Event Aggregation
Multiple events combine:
Order placed (webhook) ─┐
Payment received (webhook) ─┤→ Complete order → Ship
Inventory checked (cron) ─┘Use when: Need confirmation from multiple sources
Pattern 5: Event Aggregation
Multiple independent events must all occur before action is taken. Think of it like a checklist—only when all boxes are checked does the system proceed.
Implementation Approach
order_received, payment_confirmed, inventory_availableCommon Use Cases
Best for: Scenarios requiring multiple confirmations before proceeding. Prevents premature action and ensures all prerequisites are met.
Benefits of Event-Driven Architecture
Benefit 1: Real-Time Response
Traditional: Check inbox manually every hour
- 1-hour response time
- Emails pile up
- Overwhelmed during peak times
Event-driven: Instant processing
- 1-minute response time (trigger check interval)
- Each email processed immediately
- Consistent performance
Result: 60× faster response
Benefit 2: Zero Manual Data Entry
Traditional:
- Read email
- Copy details to ticket system
- Classify manually
- Assign manually
- Draft response
Event-driven:
- All automatic
- Zero manual entry
- Consistent data capture
Result: 90% time savings on data entry
Benefit 3: 24/7 Operation
Traditional: Only during business hours
Event-driven: Always on
- Weekend emails processed
- Night-time events handled
- Global time zones covered
Result: Continuous operation
Benefit 4: Scalability
Traditional: 1 person handles ~50 tickets/day
Event-driven: System handles 1,000+ events/day
- Auto-classification: ∞ tickets
- Auto-assignment: ∞ tickets
- Response drafting: ∞ tickets
- Human only for approval
Result: 20× scaling without hiring
Traditional vs Event-Driven: Side-by-Side Comparison
Traditional Manual Process
Event-Driven Automation
Real-World Impact
Implementation Checklist
Planning Phase
Planning Phase Checklist
Implementation Phase
Implementation Phase Checklist
Pro Tip: Test with real events during development. Send a test email or trigger a webhook to see your pipeline in action before going live.
Common Patterns Comparison
| Pattern | Trigger Type | Use Case | Example |
|---|---|---|---|
Email Automation | IMAP | Customer communication | Support tickets, inquiries |
API Integration | Webhook | External service events | Stripe payments, Shopify orders |
Scheduled Tasks | Cron | Regular operations | Daily reports, cleanup jobs |
File Processing | File Upload | Batch data import | CSV processing, image uploads |
Real-Time Sync | Webhook+IMAP | Two-way integration | CRM sync, chat apps |
Troubleshooting Event-Driven Systems
Issue 1: Events Not Creating Rows
Issue: Events Not Creating Rows
If your trigger isn't creating rows when events occur, check these common causes:
Issue 2: Duplicate Rows Created
Issue: Duplicate Rows Created
If the same event is creating multiple rows, configure deduplication:
If same ID received → Update existing row
If new ID → Create new row
Issue 3: Processing Delays
Issue: Processing Delays
If events are slow to process, investigate these areas:
- Run slow columns in parallel (avoid unnecessary dependencies)
- Use faster models for classification (GPT-3.5 vs GPT-4)
- Cache results for repeated lookups
Issue 4: Missing Event Data
Issue: Missing Event Data
If columns aren't extracting data correctly from events:
email_data) to see what data was actually captured: // Safe navigation with ?
def sender = emailData?.from?.address ?: 'unknown'
def subject = emailData?.subject ?: 'No Subject'
// Returns null instead of error if field missing
Summary: Event-Driven Architectures
You now understand event-driven architectures:
✅ Core concepts:
- Events trigger automation externally
- Triggers listen and create rows
- Pipelines process event data
- Responses complete the loop
✅ Complete example: Customer support automation
- IMAP trigger monitors inbox
- Auto-classification and assignment
- Response generation and approval
- Thread continuity maintained
✅ Event patterns:
- Reactive (respond to events)
- Scheduled (time-based)
- Webhook (API integration)
- Chained (event triggers event)
- Aggregated (multiple sources)
✅ Benefits:
- Real-time response (60× faster)
- Zero manual data entry (90% time savings)
- 24/7 operation
- Scalability (20× capacity)
✅ Implementation: Checklist for planning and building
Next Steps
Now that you understand event-driven architectures, Section 10.3 will cover:
- Data aggregation patterns
- Roll-up from child to parent
- Cross-row calculations
- Time-series analysis
Let's master data aggregation!