Building an AI Telegram Agent with ZEP Memory in n8n
Persistent context, conversational memory, and graph search — step by step
Author: n8npro.work
Reference workflow: ZEP Memory Telegram Agent (JSON provided)
Overview
This guide shows how to build a memory-aware Telegram agent in n8n that uses:
ZEP Memory for long-term conversational memory and knowledge graph search
OpenRouter (GPT-4.1 mini) as the chat model
Optional Postgres memory for a hybrid memory architecture
Compared to a basic chatbot, this agent remembers past conversations, retrieves relevant facts from ZEP’s graph, and responds with context continuity.
Architecture at a Glance
Input layer: Telegram triggers receive messages from users and hand them to the AI pipeline.
Memory layer: ZEP APIs fetch recent messages and graph edges; replies are written back to ZEP. Optional Postgres memory adds a local short-term window.
Cognition layer: LangChain Agents in n8n call GPT-4.1 mini (via OpenRouter) to generate responses using context from memory and graph.
Prerequisites
n8n instance with HTTP access for Telegram webhooks
Telegram Bot token from BotFather
ZEP account and API key
OpenRouter account and API key
Optional: Postgres database and credentials
Importing the Workflow
In n8n, go to Workflows → Import from File.
Paste or upload your JSON workflow.
Save the workflow. Do not activate yet.
Credentials to Create in n8n
Create these credentials in Settings → Credentials:
Telegram API
Token: your BotFather token
ZEP API
Base URL:
https://api.getzep.com/api/v2Header:
Authorization: Api-Key <YOUR_ZEP_KEY>
OpenRouter API
Base URL:
https://openrouter.ai/api/v1Header:
Authorization: Bearer <YOUR_OPENROUTER_KEY>
Postgres (optional)
Host, port, database, user, password, SSL as required
After creating, open the workflow and assign these credentials to the corresponding nodes.
Node Map and Purpose
| Node | Purpose |
|---|---|
| Telegram Trigger, Telegram Trigger1, Telegram Trigger2 | Receive Telegram messages for different branches |
| AI Agent, AI Agent 2, AI Agent 3 | LangChain Agents that produce answers using GPT-4.1 mini |
| GPT 4.1 mini, GPT 4.1 mini1, GPT 4.1 mini2 | OpenRouter chat model providers wired into each agent |
| Context Window | HTTP GET to ZEP sessions to fetch recent messages (context) |
| User Graph, User Graph1 | HTTP POST to ZEP graph search to fetch relevant facts/edges |
| Code, Code1, Code2 | Parse ZEP responses into arrays of facts and conversation pairs |
| Merge | Combine context and graph outputs before responding |
| Add Memory, Add Memory1 | HTTP POST to ZEP sessions to write user/assistant message pairs |
| Zep | n8n ZEP memory node for agent memory |
| Simple Memory | n8n buffer window memory for quick local context |
| Postgres Chat Memory | Optional persistent short-term memory in Postgres |
| Send a text message, Send a text message1, Send a text message2 | Telegram sender nodes to deliver answers back to users |
| Sticky Note, Sticky Note1, Sticky Note2, Sticky Note3, Sticky Note4 | Documentation and layout notes inside the canvas |
Step-by-Step Setup
1) Configure Telegram
Create a bot with BotFather and copy the token.
In n8n, add the Telegram credential and select it in:
Telegram Trigger
Send a text message
Send a text message1
Send a text message2
Open the Telegram Trigger node and copy the webhook URL n8n shows when you click “Listen for test event” (or activate the workflow so n8n registers the webhook).
Send a test message to your bot and confirm the trigger receives it.
Tip: If your n8n is behind a firewall or not public, expose it via a secure tunnel or reverse proxy with HTTPS.
2) Configure ZEP Memory
Get your ZEP API key from your ZEP dashboard.
Create a ZEP API credential in n8n and assign it to:
Context Window
User Graph / User Graph1
Add Memory / Add Memory1
In the Context Window node, confirm the URL pattern:
GET https://api.getzep.com/api/v2/sessions/{{ $json.message.chat.id }}/messages?limit=10In User Graph nodes, confirm the request body includes:
user_idqueryset from the user message textscope: "edges"an appropriate
limitandmin_relevance
Note: Replace any hardcoded user_id with your own strategy. You can map user_id to Telegram chat id or your internal user id.
3) Configure OpenRouter (GPT-4.1 mini)
Create the OpenRouter credential with your API key.
Assign the credential to GPT 4.1 mini, GPT 4.1 mini1, and GPT 4.1 mini2.
Confirm your AI Agent nodes reference the correct language model nodes in their
ai_languageModelconnections.
4) Optional: Postgres Hybrid Memory
Create a Postgres credential in n8n.
Assign it to the Postgres Chat Memory node.
Set
sessionKeyto a stable identifier such as{{$('Telegram Trigger').item.json.message.chat.id}}.Use this node to maintain a short sliding window locally while ZEP stores long-term memory and graph data.
5) Validate the Code Nodes
The Code and Code2 nodes extract facts from ZEP’s graph search response. The Code1 node formats recent message pairs into readable lines such as:
Human: …
AI: …
Confirm:
item.json.datais valid JSONThe structure matches ZEP’s response for
edgesandmessagesYou return a single item containing
factsandconversationsarrays that downstream agents can use
6) Connect and Merge Context
The Merge node combines:
Parsed facts from the graph
Parsed conversation pairs from the context window
This merged object feeds AI Agent 2 (and AI Agent 3 in the hybrid branch), whose systemMessage templates reference:
{{ $json.facts.join("\n") }}{{ $json.conversations.join("\n\n") }}
Adjust the template to your tone of voice or brand style.
7) Persist Memory After Each Reply
Both Add Memory nodes write a pair of messages to ZEP:
role_type: user, content: user text
role_type: assistant, content: model output
Sanitize outputs as in the example (strip newlines and quotes) to avoid escaping issues.
8) Activate and Test
Activate the workflow.
Send messages to your Telegram bot.
Observe the execution in n8n. You should see:
Context Window returning recent messages
User Graph returning relevant edges/facts
AI Agent generating responses conditioned on both
Add Memory posting the new exchange to ZEP
Usage Tips
Keep
limitconservative in Context Window to control latency and tokens.Tune
min_relevancefor graph search to balance recall vs precision.Use different
systemMessagetemplates per agent for specialization, for example:Agent 1: fast general Q&A
Agent 2: context-heavy answers using facts and conversations
Agent 3: hybrid branch with Postgres memory
Troubleshooting
Telegram trigger not firing
Ensure n8n is reachable over HTTPS and webhook is registered.
Re-save the workflow or use “Listen for test event”.
ZEP 401/403 errors
Recheck API key and Authorization header format.
Confirm the base path is correct.
Empty facts or conversations
Check the Code nodes’ JSON parsing.
Log
item.jsonwithconsole.login the Code node to verify structure.
Model errors or empty outputs
Confirm OpenRouter key, model availability, and account limits.
Reduce prompt size or context length.
Security and Production Notes
Store API keys in n8n credentials, never in plain text.
Rate-limit Telegram to avoid spam and manage costs.
Add guardrails in system prompts for privacy and inappropriate content.
Consider user consent and retention policies for memory storage.
Example Prompts to Try
What did I ask you last time about invoices?
Summarize the last three things we discussed.
What are the key facts about my project based on our past chats?
Continue our discussion from yesterday about the product launch plan.
This workflow turns a standard Telegram bot into a context-aware AI agent powered by ZEP Memory. With graph search, recent context windows, and optional Postgres hybrid memory, your assistant can recall, reason, and evolve across sessions. Connect your credentials, import the JSON, and start conversing with an agent that genuinely remembers.
{
"name": "ZEP Memory",
"nodes": [
{
"parameters": {
"promptType": "define",
"text": "={{ $json.message.text }}",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [220, -560],
"id": "541507eb-abde-478e-9960-567439f41475",
"name": "AI Agent"
},
{
"parameters": {
"updates": ["message"],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [0, -560],
"id": "210ce106-4b4e-40e6-9aff-abd151a33dd6",
"name": "Telegram Trigger",
"credentials": {
"telegramApi": {
"id": "9jQWan3cOz3tE62s",
"name": "Telegram account 2"
}
}
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "={{ $json.output }}",
"additionalFields": { "appendAttribution": false }
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [580, -560],
"id": "03069cee-447d-41d3-95b1-d98f0445ad3c",
"name": "Send a text message",
"credentials": {
"telegramApi": {
"id": "9jQWan3cOz3tE62s",
"name": "Telegram account 2"
}
}
},
{
"parameters": {
"url": "=https://api.getzep.com/api/v2/sessions/{{ $json.message.chat.id }}/messages",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendQuery": true,
"queryParameters": {
"parameters": [{ "name": "limit", "value": "10" }]
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [160, -80],
"id": "6e2c0c5e-304d-45b2-b946-83855db03a57",
"name": "Context Window"
},
{
"parameters": {
"method": "POST",
"url": "https://api.getzep.com/api/v2/graph/search",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"user_id\": \"zep_c6b8b1f0...\",\"query\": \"{{ $json.message.text }}\",\"scope\": \"edges\",\"limit\": 3,\"search_filters\": {\"min_relevance\": 0.7}}"
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [160, 80],
"id": "4508f733-d001-499b-8828-11a191282a1b",
"name": "User Graph"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('Telegram Trigger1').item.json.message.text }}",
"options": {
"systemMessage": "=You are a helpful assistant.\\nHere is additional information about Nate:\\n{{ $json.facts.join('\\n') }}\\n5 most recent interactions:\\n{{ $json.conversations.join('\\n\\n')}}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [620, 0],
"id": "4ce5948e-9f07-4ff4-82bc-f0a722ce7f51",
"name": "AI Agent 2"
},
{
"parameters": {
"method": "POST",
"url": "=https://api.getzep.com/api/v2/sessions/{{ $('Telegram Trigger1').item.json.message.chat.id }}/memory",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zepApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"user_id\": \"zep_c6b8b1f0...\",\"session_id\": \"{{ $('Telegram Trigger1').item.json.message.chat.id }}\",\"messages\": [{\"role_type\": \"user\",\"content\": \"{{ $('Telegram Trigger1').item.json.message.text }}\"},{\"role_type\": \"assistant\",\"content\": \"{{ $json.output }}\"}]}"
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [940, 0],
"id": "6aa1334a-b036-4c8f-943b-1bdb8293e5ec",
"name": "Add Memory"
}
]
}

