Jaga checks suspicious calls and messages in Bahasa Malaysia, English, Manglish, Mandarin, and Tamil, then gives a clear plain-language verdict. The website includes a live text checker and Agora device support; the Telegram bot is available at @jagaguardianbot.
- Next.js 15 App Router, React 19, and TypeScript
- Tailwind CSS v4 and Framer Motion
- OpenRouter as the primary scam-analysis provider
- Groq as the secondary provider and speech-to-text service
- Offline keyword detection as the final, zero-configuration fallback
- Agora RTC and Conversational AI support
The website endpoint and Telegram webhook both call the same server-only analysis service and use the same system prompt:
- OpenRouter is tried first when
OPENROUTER_API_KEYis configured. - If OpenRouter is missing, rate-limited, times out, returns invalid JSON, or otherwise fails, Jaga tries Groq when
GROQ_API_KEYis configured. - If Groq is unavailable or fails, Jaga uses the existing offline keyword detector.
Provider responses are validated before use. Invalid statuses, malformed fields, empty content, or invalid arrays trigger the next fallback. API errors and private message content are never returned to the website or Telegram user.
app/
[locale]/ Localized website and guardian pages
api/analyze/route.ts Website analysis endpoint
api/telegram/webhook/route.ts Telegram webhook endpoint
api/agora/ Agora token endpoint
api/transcribe/route.ts Groq speech-to-text endpoint
components/ Website UI and Agora call components
lib/
analysis.ts Shared result type and offline detector
telegram.ts Telegram copy and bounded result formatter
server/analysis.ts Shared OpenRouter/Groq/offline provider chain
server/telegram.ts Telegram secret validation and delivery
messages/ English, BM, and Mandarin translations
legacy/ Original static prototype (reference only)
Install dependencies and copy the environment template:
npm install
Copy-Item .env.example .env.local
npm run devFill in only the services you use in .env.local. OpenRouter and Groq keys are optional because the checker can run offline. The Telegram webhook requires both TELEGRAM_BOT_TOKEN and TELEGRAM_WEBHOOK_SECRET.
OPENROUTER_API_KEY=
OPENROUTER_MODEL=~openai/gpt-latest
GROQ_API_KEY=
GROQ_MODEL=llama-3.3-70b-versatile
TELEGRAM_BOT_TOKEN=
TELEGRAM_WEBHOOK_SECRET=
APP_URL=https://codex-hackathon-cyan.vercel.appKeep the existing Agora variables from .env.example when using the live guardian. Next.js loads .env.local automatically, and the file is gitignored.
In the Vercel project, open Settings → Environment Variables and add the same variables for the Production environment. Redeploy after saving them so the server functions receive the new configuration.
For the Telegram bot, configure at minimum:
TELEGRAM_BOT_TOKENTELEGRAM_WEBHOOK_SECRET— choose a strong random value accepted by Telegram (letters, numbers,_, and-)APP_URL=https://codex-hackathon-cyan.vercel.app
Configure one or both AI provider keys. With both keys present, OpenRouter remains primary and Groq remains secondary.
Production webhook URL:
https://codex-hackathon-cyan.vercel.app/api/telegram/webhook
Deploy the application and Vercel environment variables before registering the webhook. This PowerShell example prompts securely instead of placing credentials in shell history:
$jagaBotTokenSecure = Read-Host "Telegram bot token" -AsSecureString
$jagaWebhookSecretSecure = Read-Host "Telegram webhook secret" -AsSecureString
$jagaBotTokenPlain = [Net.NetworkCredential]::new("", $jagaBotTokenSecure).Password
$jagaWebhookSecretPlain = [Net.NetworkCredential]::new("", $jagaWebhookSecretSecure).Password
$jagaWebhookBody = @{
url = "https://codex-hackathon-cyan.vercel.app/api/telegram/webhook"
secret_token = $jagaWebhookSecretPlain
allowed_updates = @("message")
} | ConvertTo-Json
Invoke-RestMethod `
-Method Post `
-Uri "https://api.telegram.org/bot$jagaBotTokenPlain/setWebhook" `
-ContentType "application/json" `
-Body $jagaWebhookBody
Remove-Variable jagaBotTokenPlain, jagaWebhookSecretPlain, jagaWebhookBodyThe webhook secret entered here must exactly match TELEGRAM_WEBHOOK_SECRET in Vercel.
Check registration with getWebhookInfo without printing the bot token:
$jagaBotTokenSecure = Read-Host "Telegram bot token" -AsSecureString
$jagaBotTokenPlain = [Net.NetworkCredential]::new("", $jagaBotTokenSecure).Password
Invoke-RestMethod -Method Get -Uri "https://api.telegram.org/bot$jagaBotTokenPlain/getWebhookInfo"
Remove-Variable jagaBotTokenPlainConfirm that url matches the production endpoint and inspect last_error_message if Telegram reports delivery problems.
Never commit .env.local, real credentials, copied request headers, or terminal output containing secrets. Never paste or display secrets in issues, screenshots, chat, or logs.
npm test
npx tsc --noEmit
npm run build
git diff --check