TutorialApril 202615 min read

Build a WhatsApp Astrology Bot with Twilio + Vedic API

WhatsApp has 500M+ Indian users. An astrology bot that works inside WhatsApp — no app install, no sign-up — reaches an audience that no native app can match. This tutorial builds the whole thing in Node.js.

What you need
  • Twilio account with WhatsApp Sandbox enabled (free)
  • VedIntel™ API key (free — 500 calls/month)
  • Node.js 18+ with Express
  • A public webhook URL (ngrok for local dev)

How it works

User sends a WhatsApp message → Twilio calls your webhook → you maintain a session state per phone number, collect birth details across 3 messages → call VedIntel endpoints → send back a formatted chart summary. No database needed — sessions live in memory (upgrade to Redis for production).

Step 1 — The webhook handler

// server.js — Express webhook for Twilio WhatsApp
import express from 'express'
import twilio from 'twilio'

const app = express()
app.use(express.urlencoded({ extended: false }))

const sessions = new Map() // store user state per phone number

app.post('/webhook', async (req, res) => {
  const { Body, From } = req.body
  const twiml = new twilio.twiml.MessagingResponse()
  const text = Body.trim()

  const session = sessions.get(From) ?? { step: 'start' }

  if (session.step === 'start') {
    twiml.message('🌟 Welcome to VedIntel AstroAPI Bot!\n\nPlease enter your date of birth in DD/MM/YYYY format:')
    sessions.set(From, { step: 'awaiting_dob' })

  } else if (session.step === 'awaiting_dob') {
    sessions.set(From, { ...session, dob: text, step: 'awaiting_tob' })
    twiml.message('Got it. Now enter your birth time in HH:MM (24-hour) format:')

  } else if (session.step === 'awaiting_tob') {
    sessions.set(From, { ...session, tob: text, step: 'awaiting_city' })
    twiml.message('Great. Finally, enter your birth city (e.g. Mumbai):')

  } else if (session.step === 'awaiting_city') {
    const { dob, tob } = session
    const coords = await getCityCoords(text) // your geocoding step
    const chart = await getKundaliSummary(dob, tob, coords)
    twiml.message(chart)
    sessions.delete(From)
  }

  res.type('text/xml').send(twiml.toString())
})

Step 2 — Fetching the chart and formatting

async function getKundaliSummary(dob, tob, { lat, lon, tz }) {
  const BASE = 'https://vedintelastroapi.com/api/v1'
  const key = process.env.VEDINTEL_KEY

  const params = `api_key=${key}&dob=${dob}&tob=${tob}&lat=${lat}&lon=${lon}&tz=${tz}`

  const [asc, planets, dasha] = await Promise.all([
    fetch(`${BASE}/extended-horoscope/find-ascendant?${params}`).then(r => r.json()),
    fetch(`${BASE}/horoscope/planet-details?${params}`).then(r => r.json()),
    fetch(`${BASE}/dashas/current-mahadasha?${params}`).then(r => r.json()),
  ])

  return `🌟 Your Vedic Chart Summary

Ascendant: ${asc.response.ascendant}
Moon Sign: ${planets.response[2]?.zodiac}
Sun Sign:  ${planets.response[1]?.zodiac}

📅 Current Dasha Period:
${dasha.response.name} Mahadasha
Ends: ${dasha.response.end}
Balance: ${dasha.response.balance_years?.toFixed(1)} years remaining

Powered by VedIntel™ AstroAPI 🪐`
}

Upgrades to build next

Start building with 500 free API calls/month.

Get free API key →