Built From Scratch with ❤️ by me | Video Demo
Nexus enables businesses to transform communication by boosting sales with intelligent AI assistants, securing calls from scammers, and offering 24/7 support via chatbots.
Nexusai was built from scratch with the following technologies:
- Gemini (Google AI Studio) (gemini-1.5-flash)
- Firebase (storage)
- Twilio (sms, phone number provisioning)
- Lemonsqueezy (subscription management)
- Puppeteer (web scraping)
- Cheerio (web scraping)
- Elevenlab (realistic text to speech)
- Browserless (offers headless browser automation)
- Cloudflare AI (qwen-1.5-14b-chat-awq)
- Telegram Bot API (telegram bot)
- NeonDB
- Postgresql
- Redis (caching)
- Upstash Qstash (bg-jobs)
- Nodejs
- React
- Tailwindcss
- Typescript
- Prisma (orm)
Headover to trynexusai.xyz to get started.
- Nodejs (v14 or higher) install
- Postgresql install
- Redis (for caching) install or brew (macos)
- Ngrok (for exposing localhost to the internet) install
- Twilio Account create
- Lemonsqueezy Account create
- Clone the repo
git clone https://github.com/benrobo/nexusai.git
- Install dependencies
# npm
cd nexusai && npm install
# yarn
cd nexusai && yarn
-
Create a
.env
file in the root directory and add all the environment variables in the.env.example
file. Update the values accordingly. -
Then run the following command to create the necessary tables and seed data.
# npm
npm run migrate
# yarn
yarn migrate
- Using pgAdmin or any database client of your choice, headover to
/packages/api/sql/function.sql
copy and run the sql content inside the database sql editor.
-- Drop function
DROP FUNCTION IF EXISTS match_embeddings;
-- Create function
CREATE OR REPLACE FUNCTION match_embeddings (
query_embedding text,
match_threshold float,
match_count int,
kb_ids text[]
)
RETURNS TABLE (
result json
)
LANGUAGE SQL STABLE
AS $$
SELECT json_build_object(
'id', public."knowledge_base_data".id,
'similarity', 1 - (public."knowledge_base_data".embedding <=> query_embedding::vector),
'content', string_to_array(public."knowledge_base_data".content, '.'),
'metadata', public."knowledge_base_data".title
) AS result
FROM
public."knowledge_base_data"
WHERE
public."knowledge_base_data".kb_id = ANY(kb_ids) AND
1 - (public."knowledge_base_data".embedding <=> query_embedding::vector) > match_threshold
ORDER BY
1 - (public."knowledge_base_data".embedding <=> query_embedding::vector) DESC
LIMIT
match_count;
$$;
That should create the necessary function for matching embeddings.
- Update the
Lemonsqueezy
subscription plan in/packages/api/src/data/twilio/sub-plan.ts
file, this values can be gotten from your lemonsqueezy store account.
First, headover to https://app.lemonsqueezy.com/products to create a product and variant for the subscription plan as seen in the image below.
Update your webhook URL in the Webhooks
section of the product to <ngrok>.ngrok-free.app/api/webhook/tw-phone/subscription
. Make sure you add in your signing secret in the .env
file and select subscription_created
and subscription_updated
events as seen below.
Now, update the TwilioSubPlanInfo
object in the /packages/api/src/data/twilio/sub-plan.ts
file with the necessary values.
const TwilioSubPlanInfo = {
local: {
name: "Local",
description: "Local phone numbers are specific to a city or region.",
product: {
test_id: 292219, // IN DEV MODE (update this)
prod_id: 292219, // IN PROD MODE (update this)
},
variant: {
test_id: 417672, // IN DEV MODE (update this)
prod_id: 417672, // IN PROD MODE (update this)
},
},
} as TwilioSubPlanInfo;
The voice call feature is powered by Twilio, to try it out, you would need to do the following:
- Get a Twilio account here
- Upgrade the account.
- Get a starter ($5) Elevenlab account here
- Purchase a twilio phone number.
- Update the
.env
file- Make sure
NODE_ENV
is set todevelopment
otherwise, when purchasing a phone number from Nexus, you would be charged from your twilio balance (even if you've used a test credit card credentials). - Top up your account with atleast (min)
$20
.
- Make sure
- On purchasing a specific number from nexus, two records would be updated in the db:
purchased_phone_numbers
andused_phone_numbers
. With the original twilio number you purchased directly with your twilio balance, copy that number and update theused_phone_numbers
table with thephone
fields.
Why? When you purchase a number on nexusai, your original balance
($20)
isn't getting deducted from your twilio account since the number was purchased from nexusai inDEVELOPMENT_MODE
as a result that number purchased isn't getting provisioned to your twilio account, which is why you first need to purchase the number directly from twilio. So, to make sure the number is linked to your account, you would need to update theused_phone_numbers
table with thephone
field with the number you purchased directly from twilio. your balance is only getting deducted when you either (1) puchase a number directly from twilio or (2) when you make a voice call or send sms.
- Headover to twilio and update the webhook URL for the phone number with
<ngrok>.ngrok-free.app/api/webhook/tw-phone/voice
. (You would only need to do this everytime your ngrok url get reset with a random new sub-domain). - Now call that specific number linked to your agent.
Nexusai leverages firebase storage in caching audio files generated by the elevenlabs api. To get started, headover to the firebase console and create a new firebase project.
Create a new firebase storage bucket and update the FIREBASE.STORAGE_BUCKET
in the .env
file with the name of the bucket or better still, update necessary firebase config found in .env.example
.
# FIREBASE
FIREBASE_API_KEY="xxxxxxx"
FIREBASE_AUTH_DOMAIN="<project-name>-<id>.firebaseapp.com"
FIREBASE_PROJECT_ID="<project-name>-<id>"
FIREBASE_STORAGE_BUCKET="<project-name>-<id>.appspot.com"
FIREBASE_MESSAGING_SENDER_ID="xxxxxx"
FIREBASE_APP_ID="1:xxxxx:web:xxxxxx"
- Start the API server
# npm
npm run dev
# yarn
yarn dev
It should start the API server on http://localhost:4001
successfully.
- Install dependencies
# npm
cd packages/app && npm install
# yarn
cd packages/app && yarn
- Start the APP
# npm
npm run dev
# yarn
yarn dev
It should start the web app on http://localhost:4000
successfully.
- Install dependencies
# npm
cd packages/chatbot && npm install
# yarn
cd packages/chatbot && yarn
- Start the CHATBOT client
# npm
npm run dev
# yarn
yarn dev
It should start the CHATBOT client on http://localhost:3010
successfully.
The telegram bot server can be found in the /packages/tg-bot
directory. To start the server, run the following commands:
# npm
cd packages/tg-bot && npm install
# yarn
cd packages/tg-bot && yarn
Run prisma generate
to generate the prisma client.
Then create a .env
file in the root directory and add the following environment variables:
NODE_ENV="development"
TG_BOT_TOKEN="xxxxxxxxxxxxxxxxxx"
API_URL="http://localhost:4001/api"
DATABASE_URL="postgres://postgres:12345@localhost:5432/nexusai"
Replace the TG_BOT_TOKEN
with your telegram bot token gotten from the @BotFather.
Then start the server using the following command:
# npm
npm run dev
# yarn
yarn dev
It should start the telegram bot server on http://localhost:4005
successfully with the following message printed in the console:
2024-07-29 18:22:14 PM [info] : ✅ Telegram Bot launched successfully
In order to view the chatbot widget, start up the embed client located at /packages/embed/index.html
using vscode-live-server
or any other server of your choice.
-
Update the
CLIENT_URL
andAPI_URL
found in/nexus.js
file with the local API_URL's i.e (Server)http://localhost:4001/api
and (Chatbot)http://localhost:3010
respectively. -
Create a
CHATBOT
agent then Update theindex.html
script
tag with your agent id.
<script src="./nexus.js" id="<your-agent-id>"></script>
After that, you should be able to view the chatbot widget on http://localhost:5500
(when started with vscode liver server extension only) successfully as seen below.
Considering the fact that this project was built within a short period of time (1.5 month
to be exact), the codebase might not be as clean as expected. I would be working on refactoring the codebase and adding more features in the future (if time permits).
Response between production instance of nexusai might be slow, considering it was hosted on a cheap shared server instance on render with the following specs:
# server specs
- 1 CPU
- 2GB RAM
# database specs
- 1 vCPU
- 2GB RAM
- 4GB SSD