Documentation
Open-source launchpad for deploying real-time, knowledge-aware AI agents on Telegram.
LinkolnOS lets you spin up a Telegram bot that fetches live content from websites you control, talks to an OpenAI model, and remembers the conversation. Admins manage the knowledge base from inside Telegram — no dashboard required.
Features
Telegram-native — users chat directly in Telegram, no extra app
Live website crawling — bot pulls fresh content per query (axios + cheerio)
Per-project knowledge bases — admins add/remove source URLs via bot commands
OpenAI-backed responses — configurable model, temperature, and token budget
Persisted state — projects, admin passwords, websites, and conversation history all in Postgres (survives restarts)
Polling or webhook mode — polling auto-enabled for local dev (no tunnel needed); webhook mode for production
Two access modes — Admin mode (manage knowledge) and User mode (ask questions)
Customizable personality — edit
personality.jsonto change tone and capabilities
Requirements
Node.js ≥ 18
PostgreSQL running locally or remotely (any recent version)
Telegram bot token — get one from @BotFather
OpenAI API key — from platform.openai.com
A public HTTPS URL — only required for webhook (production) mode. Local dev runs in polling mode automatically.
Quickstart (local dev, polling mode)
If anything is missing from .env, the app exits with a friendly list of what to fix.
Once running, open your bot in Telegram and send /start to create your first project.
Running tests
Configuration
All configuration lives in .env. See .env.example for the canonical list.
TELEGRAM_BOT_TOKEN
✅
—
From @BotFather
ADMIN_PASSWORD
✅
—
Password admins type to unlock admin commands
OPENAI_API_KEY
✅
—
Your OpenAI API key
OPENAI_MODEL
⬜
gpt-4o-mini
Any chat-completions model
OPENAI_MAX_TOKENS
⬜
500
Max response length
OPENAI_TEMPERATURE
⬜
0.9
0.0 = deterministic, 2.0 = wild
DB_USER / DB_HOST / DB_NAME / DB_PASSWORD / DB_PORT
✅
—
Postgres connection
DB_SSL
⬜
false
Set true for hosted Postgres that requires SSL (Render, Heroku, Supabase). Leave false for local Postgres.
WEBHOOK_URL
⬜
—
Public HTTPS URL (e.g. https://yourapp.onrender.com). Leave blank for polling mode. Set it to switch to webhook mode.
PORT
⬜
3000
HTTP port for the webhook server (only used in webhook mode)
MAX_WEBSITES
⬜
50
Per-project URL limit (documented; not enforced yet)
Architecture
Key files:
app.js— entry point, mode detection (polling vs webhook), top-level message routingcommands/— admin + user command handlerscrawler.js— website fetching and content extractionllm.js— OpenAI chat-completions integration and personality loadingstateManager.js— read-through cache backed by Postgres; sync reads, async writesdb.js— Postgres schema (projects + conversations) and poolpersonality.json— bot's name, bio, capabilities (editable)test/— unit tests run via Node's built-innode:test.github/workflows/ci.yml— runs lint + tests on Node 18, 20, 22 for every PR
Deployment
Local development — polling mode is automatic when WEBHOOK_URL is unset. Just run npm start.
Production — set WEBHOOK_URL to a public HTTPS URL and the bot switches to webhook mode. Recommended hosts:
Render, Railway, Fly.io — set
WEBHOOK_URLto your service URL; the bot binds to$PORT(Render sets this automatically)AWS / GCP / your own VPS — terminate TLS in front of the Node process
Local "production-like" testing — use ngrok or cloudflared to expose
http://localhost:3000and put that URL inWEBHOOK_URL
Use a process manager (PM2, systemd, your platform's restart policy) so the bot recovers from crashes. The app handles SIGTERM/SIGINT gracefully — webhook is removed from Telegram and Postgres pool is closed before exit.
Usage
Inside Telegram:
/start— Creates a new project (first time) or resumes your existing one/start <projectName>— Deep-link into someone else's project as a user/help— Show command referenceFor Admin button → enter
ADMIN_PASSWORD→ manage websites, change password, delete the agentRestart Conversation button — clears your conversation history
Known Limitations
Be honest with yourself before deploying this in production:
Shared admin password per project. No per-user admin auth — anyone with the password is admin.
Every user message re-crawls every URL. No caching. If a project has 5 sites × 3 subpages each, that's 20 HTTP fetches per Telegram message. Slow + bandwidth-heavy + may hit rate limits on the source sites. Caching is on the roadmap.
Keyword filtering before LLM is naive substring matching. Works for simple queries; misses paraphrases. Vector search would be a real improvement.
No file-upload support. Knowledge base is web pages only — no PDF, CSV, DOCX yet.
Roadmap
Contributing
PRs welcome. See CONTRIBUTING.md for setup, branch naming, and review expectations.
Security issues: please follow SECURITY.md — don't open a public issue.
License
MIT © 2026 Volaris Games
The MIT license requires attribution: if you ship code derived from LinkolnOS, please keep the copyright notice in the source. A mention in your README is appreciated but not legally required.
Acknowledgements
OpenAI for the LLM
node-telegram-bot-apifor the Telegram integrationPostgreSQL for persistence
Enjoy building with LinkolnOS!
Last updated