A progressive Node.js framework for building efficient and scalable server-side applications.
Telegram watcher-forwarder using:
- MTProto user client (GramJS) to listen messages in a specific group without adding a bot to it;
- Bot API (Telegraf) to forward matched messages into the bot chat with the admin.
$ npm installCreate a .env or export environment variables before running:
- TELEGRAM_API_ID: your Telegram API ID (get from https://my.telegram.org)
- TELEGRAM_API_HASH: your Telegram API hash (my.telegram.org)
- TELEGRAM_PHONE: phone number of the user account that is a member of the target group (e.g. +79991234567)
- TELEGRAM_2FA_PASSWORD: optional, if your account has 2FA enabled
- TARGET_GROUPS: comma-separated list of target groups to watch. Each item can be @username, public link (https://t.me/...), numeric id, or exact title. Backward compatible: you can still set TARGET_GROUP with a single value.
- To listen only a specific forum topic inside a group, append the topic id to the group using one of the following forms: @group#, @group/, or https://t.me// (e.g. https://t.me/detkinovisad/8). If a group is listed without a topic id, all its topics are listened.
- BOT_TOKEN: Telegram bot token (used to chat with users and send them notifications)
- SUBSCRIPTIONS_PATH: optional path to store per-user subscriptions (default: ./subscriptions.json)
- TELEGRAM_SESSION_PATH: optional path to store session string (default: ./telegram.session)
- LOG_FILE: optional path to write user actions log (default: ./logs/app.log)
- TELEGRAM_KEEPALIVE_MS: optional keepalive interval in ms for user client (default: 60000)
Example:
export TELEGRAM_API_ID=123456
export TELEGRAM_API_HASH=abcdef0123456789abcdef0123456789
export TELEGRAM_PHONE=+381062943234
# multiple groups (comma-separated) or use TARGET_GROUP for single
# You can also target a specific forum topic using @group#<topicId> or a t.me/<username>/<topicId> link
export TARGET_GROUPS=@my_public_group,https://t.me/detkinovisad/8
export BOT_TOKEN=123456:AA...token
# optional: where to store per-user subscriptions
export SUBSCRIPTIONS_PATH=./subscriptions.json
# optional: path for storaging a session file
export TELEGRAM_SESSION_PATH=./telegram.sessionFirst run will ask for a login code (and 2FA password if enabled) in the console, then it will save a session file to avoid further prompts.
- Session file: set TELEGRAM_SESSION_PATH or rely on default ./telegram.session. In Docker, it is mounted to the host to survive restarts.
- Subscriptions: stored in JSON file at SUBSCRIPTIONS_PATH (default ./subscriptions.json); mount it on host to persist.
- Logs: user actions are written to LOG_FILE (default ./logs/app.log). Mount ./logs to persist logs.
docker-compose.yaml already mounts:
- ./telegram.session -> /app/telegram.session
- ./subscriptions.json -> /app/subscriptions.json
- ./logs -> /app/logs
So by default, everything is persisted outside of the container.
- A user client (MTProto) connects using your phone account and listens to new messages in the configured group.
- On /start the bot asks each user for their keywords and stores them.
- For every new message, the service checks each user’s keywords and sends a notification only to users with a match.
Note: This approach is required because the bot cannot be added to the group. Reading group messages requires a user account that is a member of that group.
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov