Intelligent spam protection for Ukrainian Telegram communities
UA Anti Spam Bot is a production-grade Node.js bot that detects and removes spam from Ukrainian-language Telegram groups and channels. It combines machine learning models (TensorFlow.js), natural language processing, and rule-based filters to keep communities safe and clean.
- ML-powered spam detection β TensorFlow.js models trained on Ukrainian-language data
- NSFW image filtering β automatic moderation of inappropriate media
- Swindler & scam detection β pattern-based identification of fraud attempts
- Configurable per-chat β admins can tune every filter through an in-chat menu
- grammY framework β built on the modern, type-safe Telegram bot framework (grammy.dev)
The project is organized into three services and shared infrastructure:
src/
βββ bot/ # Grammy Telegram bot service
β βββ index.ts # Bot entry point
β βββ bot.ts # Bot assembly & middleware chain
β βββ bot-server.ts # Bot health/admin REST API
β βββ commands/ # Telegram command handlers (public/ & private/)
β βββ composers/ # Grammy composers for features & message filters
β βββ middleware/ # Request processing middleware (parsing, guards, state)
β βββ filters/ # Boolean filter functions for conditional logic
β βββ handlers/ # Message & spam processing handlers
β βββ plugins/ # Custom Grammy plugins (self-destruct, auto-reply)
β βββ transformers/ # Grammy API call transformers
β βββ session-providers/ # Redis session storage
β βββ queries/ # Telegram callback query handlers
β βββ listeners/ # Event listeners (speech-to-text, tensor training)
β βββ menus/ # Grammy Menu definitions
β βββ messages/ # Bot response message templates
β
βββ server/ # ML API Express server (standalone)
β βββ index.ts # Server entry point
β βββ api.router.ts # REST API routes
β βββ middleware/ # Express middleware
β
βββ userbot/ # MTProto userbot for research
β
βββ services/ # Shared business logic services
βββ tensor/ # TensorFlow.js ML models (spam, swindler, NSFW)
βββ dataset/ # Dataset library (imported by app code)
β βββ dataset.ts # Main dataset loader
β βββ strings/ # JSON data files
β
βββ shared/ # Shared infrastructure
β βββ config.ts # Environment configuration
β βββ db/ # Redis client
β βββ types/ # TypeScript type definitions
β βββ const/ # Application constants
β βββ utils/ # Utility functions
β βββ video/ # Video processing service
β
βββ testing/ # Test utilities and mocks
βββ locales/ # i18n translation files
βββ assets/ # Static assets
dataset/ # Dataset CLI scripts (standalone tools)
β βββ scripts/ # check-swindlers, download, optimize scripts
scripts/ # Developer tooling scripts
tests/ # Vitest test suite (mirrors src/ structure)
- Before you start
- Installation
- For external users
- Running your bot
- Code Style
- Credits
If you from Master of Code Global (MOC), PM me for next things:
ua-anti-spam-bot-ml-v3.zip
.env.new
You need to be added into UA Anti Spam Bot Developers team.
git clone git@github.com:MoC-OSS/ua-anti-spam-bot.git
cd ua-anti-spam-botIf you have Linux or MacOS, it's better to use nvm. We have .nvmrc file which includes the current version of node that we use on the project. Just run the following command at the root of the folder:
nvm useIf you have Windows or want to install Node into the system, find the download Node.js version specified in .nvmrc.
If you have docker and docker-compose, just run the following command:
docker-compose up -d redisIf you don't want to use docker-compose, you can install redis in system.
npm iCopy .env.template file to .env:
cp .env.template .envNow you need to get BOT_TOKEN from @BotFather. You may find instruction here: https://core.telegram.org/bots/tutorial#obtain-your-bot-token
Set it into .env file:
BOT_TOKEN=4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qcYou can ask @RawDataBot to get your ID. Simply write /start and find message.from.id. E.g, it will be 999999999.
Set it into .env file:
CREATOR_ID=999999999We recommend to set the following variables in your .env file like this:
ENV=local
USE_SERVER=false
DISABLE_LOGS_CHAT=trueYou need to obtain your own credits (or ask me if you from MOC team) and set them here:
GOOGLE_CREDITS=
GOOGLE_SPREADSHEET_ID=
We use https://alerts.com.ua/ to obtain air raid alarms. You need to ask for a key from the API developer (or me if you from MOC).
ALARM_KEY=
Extract and copy ua-anti-spam-bot-ml-v3.zip to src/tensor/temp.
If you are an external user, you need to set the following parameters for the following fields in .env
If you don't have GOOGLE_CREDITS and GOOGLE_SPREADSHEET_ID, you need to specify the value like this:
DISABLE_GOOGLE_API=trueIf you don't have ALARM_KEY, you need to specify the value like this:
DISABLE_ALARM_API=true
If you're outside the MOC organization, use the copy-swindlers.sh script to copy models from `./src/tensor/swindlers-temp` into the `./src/tensor/temp` destination:
```bash
./copy-swindlers.shTo start your bot, simply run the following command:
npm run start:botAfter it, navigate to your bot and call /start command. If you receive the answer, your bot is working.
Then, try to call /enable command. If you receive the answer, your bot is set correctly and ready to be used.
If you are a group administrator and want to test moderation without a second Telegram account, use the /role command directly in that group:
/role
This toggles a per-chat test mode for your account only, so the bot will moderate your messages as if you were a regular user. To restore the normal behavior for administrators, run the same command again:
/role
Note: this does not change your real Telegram permissions. Anonymous admins must temporarily disable anonymity before using /role, otherwise Telegram sends the command as GroupAnonymousBot.
If you want to run the bot via Docker, make sure that you have Docker and Docker Compose installed. Then, run the following command to start the bot in Docker:
docker-compose up --buildWe use branch-name-lint.
To push a branch, be sure you have right prefix, ticket name in uppercase, and description split by underscore. Example branch name:
- feature/UABOT-8_create_lp_ui_elements
- hotfix/UABOT-11_add_missing_login_routes
Read more: https://github.com/barzik/branch-name-lint
We use Conversational Commits Conversational with commitlint.
To make a commit, be sure you follow it. Example:
- feat(UABOT-20): add the users page
- refactor(UABOT-10): refactor tests
Read more: https://www.conventionalcommits.org
We have a pretty heavy eslint and prettier setup, so you don't need to be worried about code style. Tools will make everything for you.
Don't forget to setup your IDE:
- WebStorm: Enable
eslintplugin in this repo; - VSCode: Download and enable
eslintplugin in this repo.
Made with β€οΈ to save Ukraine πΊπ¦ 2023