Skip to main content

Triggers

A trigger says “fire this function when this event happens on this sender.” Triggers are how you build event-driven automation without an AI agent — just raw events, your code reacts.
When a message.inbound event fires for sender snd_abc, the function runs.
If you only want a chatbot, you usually don’t need triggers — defineAgent already binds the agent to its sender. Use triggers when you want raw event delivery: custom logic before/after the agent, broadcasts, system events, or stand-alone automation without an LLM.

Event types

Run npx zavudev fn triggers events for the always-current list.

Adding triggers

Single event, single sender

Single event, all senders in the project

Multiple events × multiple senders (cartesian)

Mix specific + any

Duplicates are deduped silently.

Schedules (cron)

The cron event type runs the function on a schedule instead of a messaging event. Pass a standard 5-field expression (minute, hour, day-of-month, month, day-of-week), evaluated in UTC, minimum granularity one minute:
A schedule has no sender dimension, and one function can hold several cron triggers with different expressions. Each fire invokes the function with:
Pausing a cron trigger (fn triggers toggle --off) stops the schedule; re-enabling restarts it from now — missed ticks are not replayed.

Handling events in code

When a trigger fires, your function’s default handler (defineFunction) receives the event:
The event shape mirrors the webhook payload — same JSON, same fields. The difference: no HTTP receiver needed, no signature verification, no retries to manage. The dispatcher invokes your function directly with the event in the payload.

Pausing without removing

Toggle a trigger off without deleting:
Useful for temporary disabling without losing the trigger configuration.

Removing

When triggers + defineAgent coexist

If your function has BOTH:
  • defineAgent({...}) running on a sender, AND
  • An explicit trigger for message.inbound on the same sender
…then two things happen for every inbound message:
  1. The agent processes the message and replies via tools.
  2. Your defineFunction default handler also runs (the trigger fires it).
This is by design — you might want raw event access (for logging, custom analytics, escalation logic) on top of the agent. Just make sure your raw handler doesn’t also send a reply or you’ll double-message the customer. To avoid duplicate processing, gate your raw handler:

Native vs HTTP webhooks

Triggers are the native way to receive events. The old path — webhooks on senders — still works and is the right choice when your event receiver lives outside Zavu (an n8n flow, a Vercel function, an internal server). Inside Zavu Functions, prefer triggers:

Common patterns

Add a trigger on message.inbound and the agent on the same sender. Both run; the LLM responds, your code pages the team.

API equivalence