Triggers & Webhooks
What triggers are
Triggers let external events start AI Partner goals automatically. You configure a trigger once, and every time the event fires, AI Partner runs the associated goal — no prompt from you needed.
Three trigger types:
| Type | Fires when | Example |
|---|---|---|
| Email trigger | A new email arrives matching your filter | New email from investor → goal: "draft a reply in my voice" |
| Calendar trigger | A calendar event starts or is about to start | Meeting in 5 minutes → goal: "brief me on who's attending" |
| Webhook | An external service POSTs to your endpoint | GitHub issue created → goal: "triage and assign this issue" |
Email triggers
Setup
Go to sidebar → Integrations → Email Trigger, or configure in .env:
GMAIL_USER=your@gmail.com
GMAIL_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
EMAIL_TRIGGER_ENABLED=true
EMAIL_TRIGGER_POLL_INTERVAL_MINUTES=5
How to configure
Go to Settings → Triggers → + New Email Trigger:
Name: Investor email handler
Filter:
From: *@sequoia.com OR *@accel.com OR *@tiger.com
Subject contains: (any)
Has attachment: (any)
Goal template:
A new email arrived from {{sender}} with subject "{{subject}}".
Draft a professional reply in Alex's voice acknowledging their message
and moving toward next steps. Send the draft to my Telegram for approval.
Run mode: Goal
Filter syntax (Gmail query syntax — same as the Gmail search box):
from:boss@co.com— match a sender;from:*@sequoia.comfor a domainsubject:urgent— match subject keyword- `
What happens
New email arrives in Gmail
↓
EmailTriggerService polls Gmail every 5 minutes
↓
Email matches your filter? → yes
↓
Template substituted → goal created
↓
The goal engine runs the goal
↓
Result delivered to Telegram/chat
Template variables
{{sender}}— From address of the matching email{{subject}}— Email subject line{{snippet}}— Short preview of the email body (~100 chars){{attachments}}— Newline-separated workspace paths of downloaded files (only present whenfetchAttachments: true)
Fetching attachments
Set fetchAttachments: true when creating the trigger via the API to have AI Partner download email attachments into the tenant workspace before the goal runs:
{
"name": "Client statements",
"filter": "from:client@co.com has:attachment",
"fetchAttachments": true,
"mode": "goal",
"taskTemplate": "New bank statements received. Files:\n{{attachments}}\nRun month-end close for these statements."
}
Files are saved to uploads/email/<message_id>/ in the tenant workspace and their paths are injected into {{attachments}} (newline-separated) before the goal starts. This is the mechanism used by the bookkeeping service pilot to receive client CSV statements.
Calendar triggers
Setup
Requires Google Calendar connected:
GOOGLE_CALENDAR_ACCESS_TOKEN=your-token
CALENDAR_TRIGGER_ENABLED=true
How to configure
Go to Settings → Triggers → + New Calendar Trigger:
Name: Pre-meeting brief
Trigger: 15 minutes before any event with "meeting" or "call" in the title
Goal template:
I have a meeting starting in 15 minutes: "{{event_title}}" with {{attendees}}.
Briefly research each attendee (LinkedIn, recent news).
Summarize what I should know before the call. Send to my Telegram.
Run mode: Goal
Template variables:
{{event_title}}— calendar event title{{attendees}}— list of attendee email addresses{{location}}— meeting URL or room{{start_time}}— event start time{{description}}— event description
Timing options:
- Fire at event start
- Fire N minutes before
- Fire N minutes after event ends (for follow-up goals)
Webhooks
Webhooks let any external service trigger an AI Partner goal by sending an HTTP POST request to your webhook URL.
Creating a webhook
Go to Settings → Triggers → + New Webhook:
Name: GitHub new issue
Endpoint path: /api/triggers/webhook/github-issue (auto-generated)
Secret token: (auto-generated, copy this to GitHub)
Goal template:
A new GitHub issue was created:
Title: {{payload.issue.title}}
Body: {{payload.issue.body}}
Author: {{payload.issue.user.login}}
Repo: {{payload.repository.full_name}}
Triage this issue: assign a priority label (P0/P1/P2/P3),
assign to the right team (@backend or @frontend), and add a comment
acknowledging the reporter.
Run mode: Goal
Your webhook URL:
https://your-domain.com/api/triggers/webhook/github-issue
Set this in GitHub → repo → Settings → Webhooks → Payload URL.
Security: the secret token is used to validate the X-Hub-Signature-256 header. Requests without a valid signature are rejected.
Template variables
The entire webhook payload is available as {{payload.*}}. Use dot notation to access nested fields:
{{payload.issue.title}}
{{payload.pull_request.html_url}}
{{payload.pusher.name}}
{{payload.commits.0.message}}
Run history
Every webhook trigger logs:
- When it fired
- The raw payload received
- The goal that was started
- The goal's result
Go to Settings → Triggers → [webhook name] → Run History to see the log.
Managing triggers
| Action | How |
|---|---|
| Enable / Disable | Toggle in the triggers list |
| Test manually | Click Test — runs the goal with dummy/last payload |
| View run history | Click the trigger → History tab |
| Edit template | Click the pencil icon |
| Delete | Click the trash icon — removes future runs (history is kept) |
Trigger vs. Task Scheduler vs. Heartbeat
| Trigger | Task Scheduler | Heartbeat | |
|---|---|---|---|
| Fires when | External event (email, calendar, HTTP) | Fixed cron schedule | Intelligent tick based on context |
| Initiated by | External system | Clock | AI Partner itself |
| Goal defined | Per-trigger template | Per-task message | LLM-decided each tick |
| Best for | Reactive automation | Predictable recurring jobs | Proactive intelligence |
Use all three together for full automation coverage:
- Triggers for reacting to the outside world
- Task Scheduler for predictable recurring jobs
- Heartbeat for intelligent gap-filling
Example: full email automation pipeline
1. Email trigger: new email from client
↓
Goal: classify intent + draft reply
↓
AUTHORITY.md: reply_email + counterparty:client → draft_and_ask
↓
Telegram: approval request sent
↓
You tap "Approve"
↓
Email sent; counterparty record updated
2. Calendar trigger: 15 min before client meeting
↓
Goal: brief me on this client
↓
Pulls CounterpartyStore record (last contact, open commitments)
↓
Searches episodic memory for prior meeting transcripts
↓
Sends 2-paragraph brief to Telegram
3. Calendar trigger: 5 min after meeting ends
↓
Goal: send follow-up email
↓
Loads transcript from workspace/meetings/
↓
Drafts follow-up with action items
↓
Telegram approval → send