Building an AI Telegram Agent with ZEP Memory in n8n

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

  1. Input layer: Telegram triggers receive messages from users and hand them to the AI pipeline.

  2. 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.

  3. 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

  1. In n8n, go to Workflows → Import from File.

  2. Paste or upload your JSON workflow.

  3. Save the workflow. Do not activate yet.


Credentials to Create in n8n

Create these credentials in Settings → Credentials:

  1. Telegram API

    • Token: your BotFather token

  2. ZEP API

    • Base URL: https://api.getzep.com/api/v2

    • Header: Authorization: Api-Key <YOUR_ZEP_KEY>

  3. OpenRouter API

    • Base URL: https://openrouter.ai/api/v1

    • Header: Authorization: Bearer <YOUR_OPENROUTER_KEY>

  4. 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

NodePurpose
Telegram Trigger, Telegram Trigger1, Telegram Trigger2Receive Telegram messages for different branches
AI Agent, AI Agent 2, AI Agent 3LangChain Agents that produce answers using GPT-4.1 mini
GPT 4.1 mini, GPT 4.1 mini1, GPT 4.1 mini2OpenRouter chat model providers wired into each agent
Context WindowHTTP GET to ZEP sessions to fetch recent messages (context)
User Graph, User Graph1HTTP POST to ZEP graph search to fetch relevant facts/edges
Code, Code1, Code2Parse ZEP responses into arrays of facts and conversation pairs
MergeCombine context and graph outputs before responding
Add Memory, Add Memory1HTTP POST to ZEP sessions to write user/assistant message pairs
Zepn8n ZEP memory node for agent memory
Simple Memoryn8n buffer window memory for quick local context
Postgres Chat MemoryOptional persistent short-term memory in Postgres
Send a text message, Send a text message1, Send a text message2Telegram sender nodes to deliver answers back to users
Sticky Note, Sticky Note1, Sticky Note2, Sticky Note3, Sticky Note4Documentation and layout notes inside the canvas

Step-by-Step Setup

1) Configure Telegram

  1. Create a bot with BotFather and copy the token.

  2. In n8n, add the Telegram credential and select it in:

    • Telegram Trigger

    • Send a text message

    • Send a text message1

    • Send a text message2

  3. 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).

  4. 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

  1. Get your ZEP API key from your ZEP dashboard.

  2. Create a ZEP API credential in n8n and assign it to:

    • Context Window

    • User Graph / User Graph1

    • Add Memory / Add Memory1

  3. In the Context Window node, confirm the URL pattern:
    GET https://api.getzep.com/api/v2/sessions/{{ $json.message.chat.id }}/messages?limit=10

  4. In User Graph nodes, confirm the request body includes:

    • user_id

    • query set from the user message text

    • scope: "edges"

    • an appropriate limit and min_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)

  1. Create the OpenRouter credential with your API key.

  2. Assign the credential to GPT 4.1 mini, GPT 4.1 mini1, and GPT 4.1 mini2.

  3. Confirm your AI Agent nodes reference the correct language model nodes in their ai_languageModel connections.

4) Optional: Postgres Hybrid Memory

  1. Create a Postgres credential in n8n.

  2. Assign it to the Postgres Chat Memory node.

  3. Set sessionKey to a stable identifier such as {{$('Telegram Trigger').item.json.message.chat.id}}.

  4. 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.data is valid JSON

  • The structure matches ZEP’s response for edges and messages

  • You return a single item containing facts and conversations arrays 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

  1. Activate the workflow.

  2. Send messages to your Telegram bot.

  3. 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 limit conservative in Context Window to control latency and tokens.

  • Tune min_relevance for graph search to balance recall vs precision.

  • Use different systemMessage templates 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.json with console.log in 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"
    }
  ]
}

Leave a Reply

Your email address will not be published. Required fields are marked *