LicenseChain Telegram Bot for license operations, support flows, and admin controls over Telegram.
This repository currently runs as:
- A Telegram bot (
node-telegram-bot-api) started fromsrc/index.js, in either polling or webhook mode (see below). - PostgreSQL-backed state (e.g. Supabase;
DATABASE_URL). - An HTTP health/stats server (Express) on
PORT(default3005), with optionalPOST /webhookwhen in webhook mode. - A modular command system loaded dynamically from
src/commands/*.js.
- Node.js
>=18(required bypackage.json) - npm
- Telegram bot token from BotFather
- LicenseChain API key
git clone https://github.com/LicenseChain/LicenseChain-TG-Bot.git
cd LicenseChain-TG-Bot
npm installCreate .env in project root:
# Required
TELEGRAM_TOKEN=your_bot_token
LICENSE_CHAIN_API_KEY=your_licensechain_api_key
# Recommended
LICENSE_CHAIN_API_URL=https://api.licensechain.app
LICENSECHAIN_APP_NAME=your_app_id_or_name
# Bot/runtime
PORT=3005
LOG_LEVEL=info
LICENSECHAIN_APP_VERSION=1.0.0
# Admin controls (comma-separated IDs for admin list)
ADMIN_USERS=123456789,987654321
BOT_OWNER_ID=123456789
# Database (PostgreSQL, e.g. Supabase)
DATABASE_URL=postgresql://...
# Optional: Webhook mode (if set, polling is disabled)
# USE_WEBHOOK=true
# TELEGRAM_WEBHOOK_URL=https://your-domain.com/api/webhook
# WEBHOOK_SECRET=optional_secret_tokenNotes:
DATABASE_URLmust be a PostgreSQL connection string (e.g. Supabase). SQLite is not supported.LICENSECHAIN_APP_NAMEis needed for app-scoped commands (create/list/analytics/status flows).- For webhook mode: set
USE_WEBHOOK=trueandTELEGRAM_WEBHOOK_URLto the full URL Telegram will POST to (e.g.https://tg.licensechain.app/api/webhook). Optionally setWEBHOOK_SECRETand pass it tosetWebHookso the bot verifiesX-Telegram-Bot-Api-Secret-Token.
# Production
npm start
# Development
npm run devWhen running, the process starts:
- Telegram bot (polling or webhook, see below)
GET /health(response includesmode: "polling"ormode: "webhook")GET /statsPOST /webhook(only when in webhook mode)
-
Polling (default)
IfUSE_WEBHOOKis not set orTELEGRAM_WEBHOOK_URLis missing, the bot uses long-polling: it runs 24/7 and fetches updates from Telegram. No public URL is required for receiving updates. -
Webhook
SetUSE_WEBHOOK=trueandTELEGRAM_WEBHOOK_URLto the full HTTPS URL where Telegram should POST updates (e.g.https://tg.licensechain.app/api/webhook). The app exposesPOST /webhook; your reverse proxy must forward the chosen path to this route. Optionally setWEBHOOK_SECRETso the bot verifies theX-Telegram-Bot-Api-Secret-Tokenheader. On startup the bot callssetWebHook; on shutdown it callsdeleteWebHook.
Choose per deployment: same codebase, env vars decide the mode.
This repository includes a Dockerfile.
docker build -t licensechain-telegram-bot .
docker run --name lc-tg-bot \
-p 3005:3005 \
-e TELEGRAM_TOKEN=your_bot_token \
-e LICENSE_CHAIN_API_KEY=your_licensechain_api_key \
-e LICENSECHAIN_APP_NAME=your_app_id_or_name \
-e BOT_OWNER_ID=123456789 \
-e ADMIN_USERS=123456789 \
-e DATABASE_URL=postgresql://... \
licensechain-telegram-botFor webhook mode, add -e USE_WEBHOOK=true and -e TELEGRAM_WEBHOOK_URL=https://your-domain.com/api/webhook (and optionally -e WEBHOOK_SECRET=...).
Commands are loaded from src/commands and handled by src/handlers/CommandHandler.js.
Primary user commands:
/start/help/license/validate <license_key>/analytics/profile/settings/list/info <license_key>
License/admin operations:
/create <issued_to_or_email> <plan> <expires>/update <license_id_or_key> .../revoke <license_id_or_key>/extend <license_id_or_key> <days>/licenses/status/setstatus <online|offline|maintenance>/stats/reload/admin/logs [lines]/errors/performance/usage [timeframe]/user <id>/ban <id> [reason]/unban <id>/ticket .../tickets/close <ticket_id>/m licenses
Admin-gated commands are enforced with ADMIN_USERS and BOT_OWNER_ID.
The bot client (src/client/LicenseChainClient.js) targets API v1-style routes, including:
POST /v1/licenses/verifyPOST /v1/apps/:appId/licensesPATCH /v1/licenses/:idPATCH /v1/licenses/:id/status(used by current update path)DELETE /v1/licenses/:id(used by current revoke path)GET /v1/licenses/:id/analyticsGET /v1/licenses/statsGET /v1/appsGET /v1/apps/:idGET /v1/apps/:id/licensesGET /health
GET /health- process status, uptime, versionGET /stats- bot identity + local usage counters
npm start
npm run dev
npm run lint
npm run lint:fix
npm testYou can run the TG-Bot on hosting only if the host supports long-running Node.js applications (the bot uses Telegram long-polling and must stay running 24/7). PHP-only or request-response-only hosting cannot run this bot as-is.
- Requirements (Node 18+, persistent process, PostgreSQL e.g. Supabase, env vars)
- Upload,
npm install,.envsetup - Starting the bot (Node.js app, SSH + pm2, or host’s Node/Worker)
- Health check and keeping the bot running
If your host does not support a persistent Node process, use a VPS or PaaS (e.g. Railway, Render, Fly.io) and run npm start or the Docker image there.
- Bot not responding:
- verify
TELEGRAM_TOKEN - ensure process is running and polling is not blocked
- verify
- License commands failing:
- verify
LICENSE_CHAIN_API_KEY - verify
LICENSECHAIN_APP_NAME - verify API reachability from host
- verify
- No data persistence:
- verify
DATABASE_URLpath and write permissions
- verify
- ROADMAP.md — planned work and current state.
- CHANGELOG.md — version history and release notes.