django-telegram-bot
Sexy Django + python-telegram-bot + Celery + Redis + Postgres + Dokku + GitHub Actions template. Production-ready Telegram bot with database, admin panel and a bunch of useful built-in methods.
t.me/djangotelegrambot
Check the example bot that uses the code from Main branch:Features
- Database: Postgres, Sqlite3, MySQL - you decide!
- Admin panel (thanks to Django)
- Background jobs using Celery
- Production-ready deployment using Dokku
- Telegram API usage in polling or webhook mode
- Export all users in
.csv
- Native telegram commands in menu
- In order to edit or delete these commands you'll need to use
set_my_commands
bot's method just like in tgbot.dispatcher.setup_my_commands
- In order to edit or delete these commands you'll need to use
Built-in Telegram bot methods:
/broadcast
— send message to all users (admin command)/export_users
— bot sends you info about your users in .csv file (admin command)/stats
— show basic bot stats/ask_for_location
— log user location when received and reverse geocode it to get country, city, etc.
Content
How to run
Quickstart: Polling & SQLite
The fastest way to run the bot is to run it in polling mode using SQLite database without all Celery workers for background jobs. This should be enough for quickstart:
git clone https://github.com/ohld/django-telegram-bot
cd django-telegram-bot
Create virtual environment (optional)
python3 -m venv dtb_venv
source dtb_venv/bin/activate
Install all requirements:
pip install -r requirements.txt
Create .env
file in root directory and copy-paste this or just run cp .env_example .env
,
don't forget to change telegram token:
DJANGO_DEBUG=True
DATABASE_URL=sqlite:///db.sqlite3
TELEGRAM_TOKEN=<PASTE YOUR TELEGRAM TOKEN HERE>
Run migrations to setup SQLite database:
python manage.py migrate
Create superuser to get access to admin panel:
python manage.py createsuperuser
Run bot in polling mode:
python run_polling.py
If you want to open Django admin panel which will be located on http://localhost:8000/tgadmin/:
python manage.py runserver
Run locally using docker-compose
If you want just to run all the things locally, you can use Docker-compose which will start all containers for you.
Create .env file.
You can switch to PostgreSQL just by uncommenting it's DATABASE_URL
and commenting SQLite variable.
cp .env_example .env
Docker-compose
To run all services (Django, Postgres, Redis, Celery) at once:
docker-compose up -d --build
Check status of the containers.
docker ps -a
It should look similar to this:
Try visit Django-admin panel.
Enter django shell:
docker exec -it dtb_django bash
Create superuser for Django admin panel
python manage.py createsuperuser
To see logs of the container:
docker logs -f dtb_django
Deploy to Production
Production stack will include these technologies:
- Postgres as main database for Django
- Celery + Redis + easy scalable workers
- Dokku as PaaS (will build app from sources and deploy it with zero downtime)
All app's services that are going to be launched in production can be found in Procfile
file. It includes Django webserver (Telegram event processing + admin panel) and Celery workers (background and periodic jobs).
What is Dokku and how it works
Dokku is an open-source version of Heroku.
I really like Heroku deployment approach:
- you push commit to Main branch of your Repo
- in couple minutes your new app is running
- if something breaks during deployment - old app will not be shut down
You can achieve the same approach with Dokku + Github Actions (just to trigger deployment).
Dokku uses buildpacks technology to create a Docker image from the code. No Dockerfile needed. Speaking about Python, it requires requirements.txt
, Procfile
files to run the things up. Also files DOKKU_SCALE
and runtime.txt
are useful to tweak configs to make the deployed app even better. E.g. in DOKKU_SCALE
you can specify how many app instances should be run behind built-in load balancer.
One disadvantage of Dokku that you should be warned about is that it can work with one server only. You can't just scale your app up to 2 machines using only small config change. You still can use several servers by providing correct .env URLs to deployed apps (e.g. DATABASE_URL) but it will require more time to setup.
Deploy using Dokku: step-by-step
I assume that you already have Dokku installed on your server. Let's also assume that the address of your server is <YOURDOMAIN.COM> (you will need a domain to setup HTTPs for Telegram webhook support). I'd recommend to have at least 2GB RAM and 2 CPU cores.
Create Dokku app
dokku apps:create dtb
You might need to added .env
variables to app, e.g. to specify Telegram token:
dokku config:set dtb TELEGRAM_TOKEN=.....
Postgres and Redis
Postgres and Redis are configured as Dokku plugins on a server. They will automatically add REDIS_URL & DATABASE_URL .env vars to the app after being linked. You might need to install these Dokku plugins before. Install Postgres, install Redis.
dokku postgres:create dtb
dokku postgres:link dtb dtb
dokku redis:create dtb
dokku redis:link dtb dtb
Deploy on commit with Github Actions
Go to file .github/workflows/dokku.yml:
- Enter your host name (address of your server),
- Deployed dokku app name (in our case this is
dtb
), - Set
SSH_PRIVATE_KEY
secret variable via GitHub repo settings. This private key should have the root ssh access to your server.
This will trigger Dokku's zero-downtime deployment. You would probably need to fork this repo to change file.
After that you should see a green arrow ✅ at Github Actions tab that would mean your app is deployed successfully. If you see a red cross ❌ you can find the deployed logs in Github Actions tab and find out what went wrong.
HTTPS & Telegram bot webhook
Why you need to setup webhook
Basic polling approach is really handy and can speed up development of Telegram bots. But it doesn't scale. Better approach is to allow Telegram servers push events (webhook messages) to your server when something happens with your Telegram bot. You can use built-in Dokku load-balancer to parallel event processing.
HTTPS using Letsencrypt plugin
For Telegram bot API webhook usage you'll need a https which can be setup using Letsencrypt Dokku plugin. You will need to attach a domain to your Django app before and specify a email (required by Letsencrypt) - you will receive notifications when certificates would become old. Make sure you achieved a successful deployment first (your app runs at <YOURDOMAIN.COM>, check in browser).
dokku domains:add dtb <YOURDOMAIN.COM>
dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=<[email protected]>
dokku letsencrypt:enable dtb
Setup Telegram Bot API webhook URL
You need to tell Telegram servers where to send events of your Telegram bot. Just open in the browser:
https://api.telegram.org/bot<TELEGRAM_TOKEN>/setWebhook?url=https://<YOURDOMAIN.COM>/super_secter_webhook/
After deployment
You can be sure that your app is deployed successfully if you see a green arrow at the latest workflow at Github Actions tab.
You would need to create a superuser to access an admin panel at https://<YOURDOMAIN.COM>/tgadmin. This can be done using a standard way using django shell:
Open shell in deployed app
dokku enter dtb web
Create Django super user
Being inside a container:
python manage.py createsuperuser
After that you can open admin panel of your deployed app which is located at https://<YOURDOMAIN.COM>/tgadmin.
Read app logs
dokku logs dtb -t