Skip to content

Latest commit

 

History

History
114 lines (90 loc) · 5.41 KB

README.md

File metadata and controls

114 lines (90 loc) · 5.41 KB

Dijkstra: a modular telegram bot written in rust

Dijkstra is a modular telegram bot framework focused on group administration with features geared towards performance and manageability at scale. Dijkstra is built using botapi-rs, an companion project providing an autogenerated telegram api wrapper

An example instance is deployed at @SirDijkstraBot

Design goals

Dijkstra is designed from the ground up for scalability, modularity, and security

Scalability

Dijkstra is built to scale, with focuses on minimizing database IO bottlenecks, aggressive caching of telegram API calls, and an efficient workflow for rapidly responding to telegram error codes and api changes.

  • Whenever possible a redis cache is used over the main database to reduce disk IO bandwidth usage. The redis caching layer is designed to operate with or without persistence, falling back to raw postgres queries cached in redis for critical persistent data.
  • Runtime error reporting logs to an optional prometheus instance for realtime monitoring of bottlenecks, api errors, and other problems.
  • Use of an autogenerated bot api wrapper allows for minimal downtime during telegram api changes

Modularity

The bot framework itself provides a core library meant to be used by swappable "modules" providing self-contained features. Modules are self-contained rust source files bringing their own metadata, command helps, database migrations, and implementation. This allows modules to be easily shared as single source files and installed by non-technical users.

Modules are autoconfigured by a build script without the need to edit rust source files with a mod somemodule;, making their usage more familiar to users of python based bot frameworks.

Security

Transparent DoS mitigation is baked into the core API. Individual chats are intelligently ratelimited to prevent loss of service due to telegram 429 errors. and apis are provided for pattern matching via algorithms resistent to ReDoS. Dijkstra also uses granular permissions for restricting bot features behind familliar telegram admin permissions.

Cloning

Cloning this bot allows you to setup your own private instance with its own server, settings, name, and botpic. Before attempting to clone this bot please remember that this is a relatively technical proceedure requiring a basic understanding of the linux commandline and access to a server that is online 24/7.

A clone can be created in two ways, manually or by using an automatic script.

Automatic cloning

To setup a clone of this bot on any linux server or VPS in a single command, make sure you have either podman installed and configured for your user or root access available. First, create a bot token using @BotFather with group privacy disabled, then run

curl -L https://raw.githubusercontent.com/fmeef/dijkstra_bot/main/dbot.sh | sh

entering your bot token when prompted. Make sure that raw.githubusercontent.com is not blocked in your country or on your cloud provider. This should setup your Dijkstra clone to run under podman and autostart on boot. Because it uses long polling it should be noted that there will be a slight performance impact and a requirement for relatively stable internet.

Manually Deploying (the hard way)

The following steps will deploy an instance of Dijkstra using webhooks with the option to use custom postgres and/or redis deployments. This is suitable for more advanced admins with very large userbases.

  1. message @BotFather and generate an new bot. Make sure to disable "Group Privacy" in the bot settings module.
  2. Copy your bot token and save for later.
  3. Copy config/config.toml.example to config/config.toml and edit it. Replace the bot_token field with the token you copied.
  4. Change the postgresql password if desired. Also edit docker-compose.yml and change POSTGRES_PASSWORD
  5. run docker-compose build
  6. run docker-compose up

To enable webooks, set enable_webhook = true in your config.toml, set the wehbook_url parameter to your domain name, then setup your favorite https loadbalancer using the configuration in this guide. Add a reverse proxy pointing to the bot's local ip on port 8080 by default. An example config for nginx is:

server {
  server_name bot.example.com;
  ignore_invalid_headers off;
  listen 8443 ssl http2; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/bot.example.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/bot.example.com/privkey.pem; # managed by Certbot
  ssl on;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers 'EECDH+AESGCM:EECDH+AES256';

  ssl_ecdh_curve secp384r1;
  ssl_prefer_server_ciphers on;

  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 1d;

  ssl_stapling on;
  ssl_stapling_verify on;

  add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass          http://127.0.0.1:8080;
    }

}