Skip to content
Expedify
Triggers — every way a workflow starts

Module · Someone contacted us

User Message trigger

Lesson 4 of 10 · 5 min

Everything so far has been started by your own data or your own clock. This is the first trigger where the workflow starts because a person did something — they typed a message and pressed send.

The User Message Trigger is the front door for web chat, and the foundation for every chat agent you will build later.

A worked example

A message in, a reply out

The simplest possible chat workflow.

Notice the alias. This node aliases to trigger, not usermessagetrigger_1 — so you read the message as {{trigger.message}}. Short, and not something you would have guessed from the type name.

What arrives

{{trigger.message}}

Holds
What they typed. The one you will use most.

{{trigger.matched}}

Holds
Whether a keyword filter matched.

{{trigger.chat_history}}

Holds
Earlier messages in this conversation, when memory is on.

{{trigger.chat_context}}

Holds
The wider conversation state.

{{trigger.attachments}}

Holds
Files they sent, with file_ids and file_urls beside it.

Filtering by keyword

The matching half of the node.

keywords

What it holds
Comma-separated keywords to match against

exact_match

What it holds
If true, entire message must match exactly (case-insensitive) Defaults to false.

wait_for_input

What it holds
Enable waiting for user input when node runs during workflow Defaults to false.

input_timeout

What it holds
Timeout for human input when used mid-workflow (seconds) Defaults to 10.

Leave keywords empty and every message starts the workflow, which is what a general assistant wants. Fill it in and only matching messages do — useful for a narrow workflow that should handle “refund” and leave everything else alone.

Keyword routing does not scale, and it is worth knowing that early. Real messages say “I want my money back”, not “refund”. A list of keywords is a reasonable filter for one narrow job and a poor substitute for understanding — which is what the AI Agent node exists for. Use keywords to scope a workflow, not to interpret a person.

Memory: the setting that makes it a conversation

The memory half — off by default, and usually what you want on.

enable_memory

What it holds
Enable chat history context retrieval Defaults to true.

memory_strategy

What it holds
Context selection strategy One of: recent_only · semantic_similar · conversation_aware · compressed Defaults to conversation_aware.

recent_messages_count

What it holds
Always include last N messages Defaults to 10.

max_context_messages

What it holds
Maximum number of messages to include Defaults to 50.

max_context_tokens

What it holds
Maximum tokens for context window Defaults to 4000.

Without memory, every message is a stranger. Someone asks “how much is the pro plan?”, then “and the annual price?” — and the second question arrives with no idea what “it” refers to. With memory on, the earlier turns come through in chat_history and the workflow can answer properly.

The three limits below it are a budget, not a preference. recent_messages_count and max_context_messages cap how much history travels; max_context_tokens caps its size. They matter because history goes into the prompt of whatever AI node comes next, and prompts are billed by size — an unbounded conversation gets slower and more expensive with every turn.

Waiting for a reply

wait_for_input lets the workflow pause on this node for the person's next message, with input_timeout deciding how long. That turns a one-shot reply into a back-and-forth — ask a question, wait, act on the answer.

Same idea, two nodes. This is the chat equivalent of the WhatsApp Question node, and a cousin of Human Approval: all three pause a run until a person responds. What differs is who is being asked and on which channel.

Try it

  1. Build the two-node workflow above: trigger, then a text response that quotes the message back.
  2. Open the chat and send two related messages with memory off — notice the second one has no context.
  3. Turn on enable_memory, set recent_messages_count to 5, and try the same pair again.
  4. Now add a keyword and confirm that non-matching messages do not start the workflow at all.

Next: the same idea on WhatsApp — where the conversation history comes with the trigger rather than being switched on.