Skip to content

Repository files navigation

🧉 Yerbi — Conversational Ordering Agent for Telegram

English · Español

A B2B ordering agent that lets clients of a specialty yerba mate roaster browse the catalog, register, place orders and check delivery status — entirely by chatting on Telegram, in natural language. Orchestrated in n8n, reasoning with Claude (tool-calling), backed by Salesforce (CRM + Apex) and MongoDB (event broker + history).

n8n Claude Salesforce MongoDB Telegram

Portfolio note: the brand Yerbatera del Litoral and all data are fictional. The integration (Telegram · n8n · Claude · Salesforce · MongoDB) is real. Secrets live only in n8n credentials — never in this repo.


The problem

B2B orders arrive by chat, scattered and at every hour: a client types “hola”, then “mandame 2 tradicionales”, then “y 1 barbacuá” — three messages, one intent. The sales team has working hours; the client doesn't. By the time someone replies, the client has already bought from whoever answered first. And every order still has to be typed into the CRM by hand.

Yerbi answers 24/7, understands natural language (typos and all), quotes from the live catalog, confirms, and writes the order straight into Salesforce — in seconds.


What it does

  • 🧉 Live catalog — reads active products, prices and types from Salesforce in real time.
  • 🛒 Conversational ordering — builds the order from plain language, shows a summary, waits for explicit confirmation before creating anything.
  • 🪪 Auto-registration — unknown clients are onboarded into Salesforce via a multi-step flow.
  • 📦 Order history & status — looks up past orders and their delivery stage.
  • 🌿 Domain expert — answers questions about yerba types, brewing temperature, storage.
  • 🔒 Business rules server-side — never invents data, never modifies confirmed orders, never exposes internal IDs.

Architecture

Event-driven, single workflow (publisher → broker → consumer):

  • Publisher (intake) — each Telegram fragment is stored in MongoDB (buffers) and fires an HTTP event to the consumer. It does not reply.
  • Broker — MongoDB Atlas: buffers (ephemeral, for debounce) + conversations (durable history).
  • Consumer (debounce) — a webhook receives the event, acks instantly, waits a 5s silence window, and only proceeds if no newer fragment arrived. It merges the burst, runs the agent, and sends one reply. The buffer is deleted on process (idempotent).
  • Agent — Claude reasons over the merged message + client context and calls tools; the data (catalog, prices, orders) always comes from Salesforce, never from the model.
  • Resilience — 2 retries + an error branch: the client always gets an answer.
flowchart TD
    U(["Telegram client"]) -->|fragments| TT["Telegram Trigger"]
    subgraph PUB["Intake (Publisher · push)"]
        TT --> EX["Extract Message Fields"]
        EX --> MF1["MongoDB — Find Buffer"]
        MF1 --> AF["Append Fragment (messages + lastAt)"]
        AF --> MU["MongoDB — Upsert Buffer"]
        MU --> EMIT["Emit Event → Consumer (HTTP)"]
    end
    MU -. writes .-> MONGO[("MongoDB Atlas<br/>buffers / conversations")]
    EMIT -. event .-> WH["Webhook EVENT_IN"]
    subgraph CON["Consumer (push · deadline)"]
        WH --> WAIT["Wait 5s (deadline)"]
        WAIT --> MF2["MongoDB — Find Buffer"]
        MF2 --> GATE{"silence ≥ 5s?"}
        GATE -->|no| ABORT(["abort"])
        GATE -->|yes| MDEL["merge + Delete Buffer"]
        MDEL --> SF1["Salesforce — Identify Client"]
        SF1 --> CF{"Client found?"}
        CF -->|no| REG["Multi-step registration"]
        CF -->|yes| CTX["Set Client Context"]
        CTX --> PROMPT["Prepare Agent Prompt"]
        PROMPT --> AGENT["AI Agent · Claude"]
        AGENT -->|ok| SEND["Send Telegram Response"]
        AGENT -->|error| FB["Fallback — Notify User"]
        SEND --> MLOG["MongoDB — Log Conversation"]
    end
    MONGO -. reads .-> MF2
    AGENT <-->|tools| TOOLS{{"search_catalog · get_orders · create_order"}}
    TOOLS <--> SFAPI[("Salesforce REST + Apex")]
    SEND -->|1 reply| U
Loading

The full diagram is in flujo.mermaid; component view in docs/architecture.md.


Tech stack

Service Role Cost
Telegram Bot API Receive & send messages (webhook) Free
Anthropic · Claude Agent reasoning (tool-calling) Paid (cents/message)
Salesforce REST API SOQL: identify client, catalog, orders Free (Dev org)
Salesforce Apex REST POST /apexrest/pedidos — atomic order creation Free (Dev org)
MongoDB Atlas Debounce broker + conversation history Free (M0)
n8n Orchestration of the whole flow Self-host / Cloud

The Salesforce API contract lives in openapi.yaml.


Run it yourself

You'll need a Telegram bot, a Salesforce Dev org, an Anthropic key and a MongoDB Atlas M0 cluster. Full step-by-step setup for each service is in README.es.md (section 3) and the workflow import guide in n8n/workflows/README.md.

Short version:

  1. Import n8n/workflows/yerbi-agent.json into n8n.
  2. Assign credentials (Telegram, Salesforce OAuth2, Anthropic, MongoDB) and replace YOUR_INSTANCE with your Salesforce instance in the HTTP nodes.
  3. Deploy the Apex class in salesforce/apex and load the catalog seed from salesforce/data.
  4. Activate the workflow and message your bot: hola → catalog → an order → confirmo.

Demo variant: the tools and client lookup can be swapped for mock Code nodes so the agent runs standalone (no Salesforce/Mongo) — handy for recording. This repo ships the real Salesforce + Apex + MongoDB integration.


Project structure

├─ n8n/workflows/          # yerbi-agent.json — the full workflow + import guide
├─ salesforce/             # Apex REST controller + tests, object metadata, catalog seed
├─ docs/                   # architecture
├─ specs/                  # spec-driven design (requirements, plan, tasks, contracts)
├─ openapi.yaml            # Salesforce API contract
├─ flujo.mermaid           # full flow diagram
└─ SECURITY.md             # how secrets are handled

Security

No secrets in this repository. Every credential (Anthropic, Telegram, Salesforce OAuth, MongoDB) lives only in n8n. Infrastructure values are placeholders (YOUR_INSTANCE.my.salesforce.com, REPLACE_WITH_YOUR_WEBHOOK_ID). See SECURITY.md.


Built by Valentino Millimaci.

Releases

Packages

Contributors

Languages