An AI-powered Telegram bot for private chats and group chats, with long-term memory, optional image understanding, and automated news delivery.
The bot is provider-agnostic: any OpenAI-compatible LLM provider can be used by configuring llm.baseUrl, llm.apiKeyEnvVar, and the role models in config.json. If you want private, uncensored AI access out of the box, Venice.ai is a good default platform and is what the sample defaults point to.
- Every text message goes straight to the AI agent
- Photo messages can be analyzed when the configured chat model supports vision
- Conversation history is stored in Redis and compressed into hierarchical summaries so the bot can keep context over time
- Group text and photo messages are persisted for shared memory
- The bot only replies when it is explicitly mentioned
- Messages are stored with sender attribution, for example
Alice: can you summarize this?, so shared context stays readable - News subscription commands are limited to group admins
This makes the bot usable as both a personal assistant in DMs and a passive-memory assistant in team or community groups.
- Telegram chat agent powered by LangChain + OpenAI-compatible chat models
- Three separate LLM roles: chat, summarizer, and news relevance scoring
- Hierarchical memory with recent context plus daily, weekly, and monthly summaries
- Optional vision support for photo messages
- Tool-enabled responses with built-in calculator, help, and time tools
- Configurable web-search-aware chat role (
supportsWebSearch) - RSS news polling, relevance scoring, storage, and per-chat delivery
- Per-chat news topics and delivery cadence
- On-demand recent news retrieval and 24-hour news summaries
- Optional private-chat username whitelist
The bot registers these Telegram commands:
/start Show a quick overview for this chat
/help Show commands, ingress behavior, and news status
/abort Abort the current interactive operation
/clear Clear stored conversation history for this chat scope
/info Show chat scope and subscription details
/news [count] Get recent news (1-10 articles, default: 5)
/summary Summarize the most relevant news from the last 24 hours
/subscribe Enable relevant news delivery for this chat
/unsubscribe Disable relevant news delivery for this chat
/interval [seconds] Show or set the news cadence
/topics [a, b, c] Show or set news topics for this chat
In private chats, subscription commands are self-service. In group chats, /subscribe, /unsubscribe, /interval, and /topics require admin access.
- Node.js 24
- TypeScript
- Telegraf for Telegram bot handling
- LangChain with @langchain/openai for the agent runtime
- Redis for sessions, conversation memory, summaries, and news storage
- BullMQ for polling and delivery scheduling
- tsx for local development
- Pino +
pino-prettyfor logging - Vitest for tests
- Docker / Docker Compose for containerized local runs
- Node.js
>=24.0.0 - npm
- Redis
- A Telegram bot token from @BotFather
- An API key for your chosen OpenAI-compatible provider
Copy env.sample to .env:
cp env.sample .envRequired values:
TELEGRAM_BOT_TOKEN=
REDIS_URL=redis://localhost:6379
LLM_API_KEY=
LOG_LEVEL=infoconfig.defaults.json is the baseline configuration shipped with the repo.
To override it, copy config.sample.json to config.json:
cp config.sample.json config.jsonImportant config areas:
telegram.botUsername- used for mention handling in groups (do not include the@prefix)telegram.whitelistedUsers- optional allowlist for private chatsnews.feeds- RSS feeds to monitornews.pollIntervalMinutes- how often feeds are pollednews.deliveryCheckIntervalSeconds- how often subscriptions are checked for deliverynews.relevanceThreshold- minimum score to deliver an article to a chat (scored per-chat)news.topics- default topics used when a chat has not set custom topicsllm.apiKeyEnvVar- env var holding the provider API keyllm.baseUrl- OpenAI-compatible base URLllm.roles.*- separate model/system-prompt settings for chat, summarizer, and news relevance
By default, config.defaults.json points to Venice's API base URL, but you can swap that to any compatible provider.
Install dependencies:
npm installStart Redis only:
docker compose up redisRun the bot in development mode:
npm run start:devBuild and run the production build locally:
npm run build
npm startBuild and run the full stack:
docker compose up --buildRun in the background:
docker compose up -d --buildStop containers:
docker compose downThe compose setup starts:
redis- Redis 7 with append-only persistencebot- the Node 24 application container
npm run start:dev
npm run build
npm start
npm run tscheck
npm test
npm run lint
npm run lint:fix
npm run format
npm run format:checkConversation state is stored in Redis.
- Recent messages are kept as the live context window
- Daily summaries are generated from raw conversation history
- Weekly summaries are generated from daily summaries
- Monthly summaries are generated from weekly summaries
This keeps the bot context-aware without letting conversation history grow unbounded.
The bot continuously monitors configured RSS feeds and stores recent articles in Redis.
- Feeds are polled on a schedule
- New articles are stored and indexed in Redis (duplicates are skipped, and items expire after 7 days)
- Subscribed chats receive articles according to their own delivery interval
- At delivery time, each candidate article is scored against that chat's own topics using the dedicated news relevance model
- The first article that meets the relevance threshold and has not been delivered to that chat before is sent
- Users can also request recent articles manually with
/newsor ask for a digest with/summary
Per-chat topic customization is supported through /topics. When a chat sets custom topics, those topics are used for relevance scoring at delivery time and for on-demand /news and /summary requests. Chats that have not customized topics fall back to the global default.
src/index.ts- bootstrap and service wiringsrc/lib/telegram/- Telegram routing, command handling, reply formattingsrc/lib/agent/- LangChain agent service and built-in toolssrc/lib/memory/- hierarchical memory and summarizationsrc/lib/news/- feed reading, scoring, storage, subscriptions, schedulingsrc/lib/redis/- Redis-backed persistenceconfig.defaults.json- default runtime configconfig.sample.json- example override configenv.sample- environment template
- If the chat model does not support vision, photo messages are still persisted to memory, but the bot will not answer image-specific questions about them.
- In groups, Telegram privacy mode affects how much context the bot can see. Disabling privacy mode is recommended if you want passive group memory capture for all messages.
- Only one Telegram polling instance should run at a time. If you get a Telegram
409 Conflict, another bot instance is already connected.