Lexiverse
Lexiverse - AI contextual reading engine for English learners. Your next article is your next review.
Sam is a Vapi-powered voice agent that talks to prospective students and logs every call straight into Google Sheets.
EducationGitHub @shobhit-shuklOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
this is an ai which attends the call and take info from that
Taken from the repository README
Loading the full README.
Read the full README ↗Sam is an AI voice admissions counselor that talks to prospective students on the phone (in Hindi, English or Hinglish), and after each call this app:
/api/vapi-webhook,/admin: status pipeline (New → Contacted → Interested → Applied → Enrolled / Lost), follow-up dates, notes, call history with transcripts, search and filters, CSV export, and analytics,Sam's voice, prompt and knowledge of the university are configured in the Vapi dashboard, not in this repo.
Next.js 16 (App Router) · MongoDB (Mongoose) · Google Sheets API · Gemini API · Vapi
npm install
cp .env.example .env.local # then fill in the values
npm run create-admin -- [email protected] 'a-strong-password' "Admin Name"
npm run dev
Open http://localhost:3000/admin and log in.
Without VAPI_WEBHOOK_SECRET, the webhook accepts unauthenticated requests in development only, so you can test it with curl.
.env.example in your host (e.g. Vercel). VAPI_WEBHOOK_SECRET is required: in production the webhook rejects all requests without it.https://<your-domain>/api/vapi-webhook and set the same secret as VAPI_WEBHOOK_SECRET (as the server secret, or as a Bearer-token credential).GOOGLE_SERVICE_ACCOUNT_EMAIL as an Editor, and make sure the tab named in GOOGLE_SHEET_NAME exists.npm run create-admin (pointed at the production MONGODB_URI). There is no public sign-up. Running it again for an existing email resets the password and clears any login lockout./api/test-mongodb, /api/test-sheets, /api/test-gemini.npm run backfill-leads against the production MONGODB_URI. It's safe to re-run.x-vapi-secret header or Authorization: Bearer).after()), so slow Gemini/Sheets calls never cause Vapi timeouts and retries.SMTP_HOST and ALERT_EMAIL_TO are set, a "Hot" call triggers an email with the caller's details and a link to the lead. A failed email never blocks saving the lead.lib/time.ts).The assistant can phone leads back: a 📞 Call now button on each lead page, and (optionally) an automatic daily run that calls leads whose follow-up date has arrived. Callbacks open with a personal greeting ("Hello Priya, this is Sam from Maya Devi University, calling you back about BBA admissions…"), leave a short voicemail if nobody answers, and are filed under the same lead when they end (marked "Callback" in the call history).
It's built in but dormant until configured — until then the button says callbacks aren't set up. To turn it on:
VAPI_API_KEY)VAPI_ASSISTANT_ID)VAPI_PHONE_NUMBER_ID), the ID, not the number itselfVAPI_API_KEY as a Secret), then Redeploy.CRON_SECRET (a long random string) and AUTO_CALLBACKS_ENABLED=true, then redeploy. Every Monday–Saturday around 11 AM IST, the job calls up to CALLBACK_BATCH_LIMIT leads whose follow-up date is today or earlier.Unanswered calls. When a call this app places isn't answered (no answer, busy, voicemail), it stays in the lead's call history and the lead, Call list row or Website lead shows Last call: No answer (or Line busy, Went to voicemail). It doesn't create a lead, isn't added to the Google Sheet and doesn't run extraction.
Rules the automatic job follows:
CALLBACK_HOURS (IST, default 10–19), Monday–Saturday.Notes:
vercel.json (e.g. hourly), or have any external scheduler call GET /api/cron/callbacks with Authorization: Bearer <CRON_SECRET>.Admin → Call list lets you upload students who haven't called yet (e.g. from a school fair or an enquiry form) and have the assistant call them.
.xlsx or .csv file (up to 1 MB / 5,000 rows) with a Name and a Phone column, plus an optional Course column that personalises the call. Common headers are recognised ("Student Name", "Mobile No.", "Contact Number", "Course Interested"…); files without headers work too. Download sample file on the page shows the format. Old .xls files: open in Excel and Save As .xlsx.Enquiry / apply / callback / brochure forms on the university website are forwarded here and listed under Admin → Website leads: search and filter by status, form and course; set a status (New → Contacted → Converted / Closed); see the message, page and campaign; 📞 Call the student (uses the Outbound callbacks setup); and jump to the call Lead once Sam has spoken to them. Repeat enquiries from the same number are flagged (×2, ×3…).
Connecting a website: set the same long random string as WEBSITE_LEADS_SECRET here and in the website's backend, then have the backend (never the browser) send each submission:
POST https://<this-app>/api/website-leads
Authorization: Bearer <WEBSITE_LEADS_SECRET>
Content-Type: application/json
{
"externalId": "website-enquiry-id", // makes retries safe (optional)
"name": "Priya Sharma", // required
"phone": "+91 98765 43210", // required
"email": "[email protected]",
"course": "BBA",
"city": "Dehradun",
"message": "Is hostel available?",
"formType": "enquiry", // enquiry | apply | callback | brochure | contact
"sourcePage": "/programs/bba",
"utmSource": "google", "utmMedium": "cpc", "utmCampaign": "admissions-2026",
"submittedAt": "2026-10-20T10:15:00Z"
}
Responses: 201 {id} created, 200 {id, duplicate: true} already received (same externalId), 400 {errors} invalid, 401 wrong secret.
Students message your WhatsApp Business number and an AI assistant replies, in English, Hindi or Hinglish, about courses, fees, eligibility, scholarships, hostel and the admission process. It runs as an n8n workflow (n8n/whatsapp-admissions-bot.json) on the official WhatsApp Cloud API. Everything it knows comes from this app.
Admin → Courses is where you manage it:
Edits reach the bot from its next reply, with no redeploy and no change in n8n.
What students get:
What your team gets:
You need a Meta Business account, a phone number that is not already registered on the WhatsApp or WhatsApp Business app (or remove it from the app first), an n8n Cloud workspace and a free Gemini API key from Google AI Studio (the same kind of key as GEMINI_API_KEY).
BOT_API_SECRET (a long random string) in Vercel and redeploy. Add your courses and admission info under Admin → Courses.whatsapp_business_messaging and whatsapp_business_management. (The token on the API Setup page expires after 24 hours.)Authorization, Value Bearer <BOT_API_SECRET>.n8n/whatsapp-admissions-bot.json. Open Read message and set RIYA_URL to this app's address. Pick the credentials on each node: WhatsApp OAuth on the trigger; WhatsApp API on Send menu, Show typing, Send reply, Send sorry and Ask to type; Header Auth on Get courses and save_student_details; Google Gemini on Gemini.Notes:
gemini-3.6-flash on Gemini's free tier. Two limits apply. The free tier has per-minute and per-day request limits; if many students message at once, some get the "Sorry, try again" reply. On the free tier, Google may also use the conversations to improve its products. If either matters, enable billing on the same key; nothing in n8n changes. To use another model, change it on the Gemini node.API used by the workflow (both need Authorization: Bearer <BOT_API_SECRET>; without the secret they reject everything in production):
GET /api/bot/knowledge → { institutionName, text, courses, updatedAt }, where text is the active courses and admission info as plain text for the AI.POST /api/bot/leads with { phone*, name, course, city, email, message, wantsCallback } → 201 {id} new, 200 {id} updated, 400 {errors}.| Command | What it does |
|---|---|
npm run dev | Start the dev server |
npm run build / npm start | Production build / serve |
npm run lint | ESLint |
npm run create-admin -- <email> <password> ["Name"] | Create an admin or reset their password |
npm run backfill-leads | Group existing calls into leads (one-off, safe to re-run) |