Skip to content

Latest commit

 

History

20 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Saima Bot

An AI-powered WhatsApp assistant built on Meta's WhatsApp Cloud API. Customers ask questions in plain language and get answered in seconds — no menus to memorise, no one at the keyboard.


What it does

Small businesses lose enquiries overnight. Someone messages at 11pm asking whether you build inventory systems, nobody replies until morning, and by then they have gone elsewhere.

Saima Bot answers immediately, and it answers properly. It knows the full portfolio, what each project does, which links are real, and where the boundaries are — so it can hold an actual conversation about a project instead of reciting a fixed menu.

Example exchange

Customer: do you build inventory systems for a small shop? Bot: Yes — that's close to Munshi Jee, a cloud khata built for wholesale traders with stock and billing included. What kind of shop is it, and what do you need to track? Customer: just one shop, around 300 items Bot: That's straightforward. Do you need basic stock tracking and billing, or also purchase orders and supplier management?

The second reply understands "just one" because the bot remembers the question it asked.

How it works

Customer sends a WhatsApp message
            │
            ▼
      Meta Cloud API
            │  POST
            ▼
     Express webhook  ──▶  greeting or numbered shortcut?  ──yes──▶  instant canned reply
            │                                                              │
            no                                                             │
            ▼                                                              │
    conversation history + business knowledge                              │
            │                                                              │
            ▼                                                              │
      DeepSeek API  ──▶  generated reply  ──────────────────────────────────┤
                                                                           ▼
                                                            Graph API sends it back
  1. Meta verifies the webhook once through a GET /webhook challenge
  2. Incoming messages arrive as POST /webhook
  3. The server returns 200 immediately so Meta does not retry
  4. Greetings and numbered shortcuts are answered from code without an API call
  5. Everything else goes to the model along with the last few turns of conversation
  6. The reply is sent back through the Graph API

Features

Conversation

  • Natural-language replies generated by DeepSeek, grounded in a detailed business knowledge prompt
  • Per-sender conversation memory covering the last five exchanges, so follow-up questions keep their context
  • Sessions expire after 30 minutes of silence and are swept from memory automatically
  • Sending a greeting starts a clean conversation
  • Replies in whatever language the customer writes in, including Roman Urdu
  • Numbered catalogue on greeting: six products, each with its real link where one exists

Guardrails

The bot represents a real business, so it is constrained in ways that matter commercially:

  • Never invents a URL. Only the links written into the prompt can be shared. Projects without a public link get "Saima will send it directly" rather than a plausible-looking guess.
  • Never quotes or agrees to a price. When a customer names a budget, the bot acknowledges it and defers to Saima. It cannot create a commitment on her behalf.
  • Never promises a timeline. Same reasoning.
  • Never claims a project is live unless a link for it exists in the prompt.
  • Speaks as the assistant, not as Saima. "Saima built…", never "I built…".
  • Says no where the answer is no. Native mobile, blockchain, and game engines are out of scope and the bot says so plainly instead of agreeing to everything.

Cost control

  • Greetings and the six numbered shortcuts are answered from code, never from the model
  • Replies capped at 350 tokens — WhatsApp messages should be short anyway
  • Conversation history trimmed to the last 10 turns before every call
  • Typical cost per AI reply is a fraction of a cent

Reliability

  • Immediate 200 acknowledgement prevents Meta retry storms
  • Model failures fall back to a helpful message instead of silence
  • Non-text messages (images, documents, voice notes) get a graceful reply rather than crashing
  • Malformed webhook payloads are caught and logged
  • Timeouts on both outbound APIs

Security

  • Every credential lives in an environment variable — nothing is committed
  • Webhook verification token checked on every verification attempt
  • System instructions are never revealed to the customer

Tech stack

Layer Technology
Runtime Node.js 18+
Framework Express
HTTP client Axios
Messaging WhatsApp Cloud API (Graph API v21.0)
AI DeepSeek (deepseek-chat)
Hosting Railway

Endpoints

Method Route Purpose
GET / Health check
GET /webhook Meta verification challenge
POST /webhook Receives incoming messages

Environment variables

Variable Where it comes from
VERIFY_TOKEN Any string you choose — must match what you enter in Meta
WHATSAPP_TOKEN Meta dashboard access token
PHONE_NUMBER_ID Meta dashboard, under WhatsApp → API Setup
DEEPSEEK_API_KEY platform.deepseek.com
PORT Set automatically by Railway

Running locally

git clone https://github.com/hamidsaima995-bit/SAIMA-BOT.git
cd SAIMA-BOT
npm install

Create a .env file:

VERIFY_TOKEN=your_chosen_string
WHATSAPP_TOKEN=your_meta_access_token
PHONE_NUMBER_ID=your_phone_number_id
DEEPSEEK_API_KEY=your_deepseek_key
PORT=3000
npm start

Meta needs a public HTTPS URL to reach the webhook. For local testing, expose the port with a tunnel:

npx ngrok http 3000

Then use the ngrok URL plus /webhook as the callback URL in the Meta dashboard.

Meta setup

  1. Create an app at developers.facebook.com and add the WhatsApp product
  2. Under WhatsApp → API Setup, copy the access token and phone number ID
  3. Under WhatsApp → Configuration, set the callback URL to https://your-domain/webhook and the verify token to whatever you set in VERIFY_TOKEN
  4. Subscribe to the messages webhook field
  5. Add your test number under recipients while the app is in development mode

Adapting it to another business

Everything the bot knows lives in one constant near the top of server.js:

const SYSTEM_PROMPT = `You are ... the assistant for ...

=== PRODUCTS AND PROJECTS ===
...
=== LINKS ===
...
=== PRICING ===
...
=== RULES ===
...`;

Replace that block and the bot becomes a different business's assistant. The numbered shortcuts in getReply() are the only other place with business-specific text.

To swap DeepSeek for another provider, the model call is isolated in askAI() — one function, one endpoint.

Design notes

Why memory is a Map rather than a database. Conversations are short and disposable; a WhatsApp enquiry that goes cold after thirty minutes is not worth persisting. A Map with a TTL sweep costs nothing and clears cleanly on redeploy. If sessions ever need to survive a restart, getHistory and remember are the only two functions that would change.

Why shortcuts bypass the model. A greeting has exactly one correct response. Paying for a model call to produce it is waste, and the canned reply arrives faster. The model handles the questions that actually need judgement.

Why the webhook responds before doing any work. Meta retries anything that does not return 200 quickly, which turns one slow reply into several duplicate messages. Acknowledging first and processing after removes that failure mode entirely.

Why links are enumerated rather than described. An earlier version let the model mention project links freely, and it produced a confident, well-formed, entirely fictional URL. Listing the real ones and forbidding construction is the only reliable fix — a model asked to be careful about links will still occasionally invent one.

Why the bot cannot quote prices. The same earlier version was given a budget figure and replied that the amount would cover the full build. That is a commitment a customer can reasonably hold you to. The bot now acknowledges budgets and hands them to a human, every time.

Roadmap

  • Persist conversations to Postgres for analytics
  • Media message support — read images and documents
  • Business hours awareness with an after-hours message
  • Handoff to a human when the customer asks for one
  • Admin dashboard for editing the knowledge prompt without a deploy

Notes

This runs in Meta development mode, which delivers only to numbers registered as test recipients. Production access requires business verification through Meta.


Built by Saima — Ninja Tech

About

AI-powered WhatsApp assistant built on Meta's Cloud API and DeepSeek. Node.js webhook with conversation memory.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages