/drawguessr

DrawGuessr game: Telegram Bot Web App

Primary LanguagePythonMIT LicenseMIT

DrawGuessr game: Telegram Bot Web App

Screenshots

  

Sample bot - https://t.me/DrawGuessrBot

Game mechanics

@DrawGuessrBot - a miniapp that mimics to Draw&Guess game. After adding the bot to the group, you can start the game (using the /game command), where the host, through the Telegram Web App, begins to draw the hidden word. Group users see the updated image and write words in the group chat. As soon as the correct word is written, the game ends.

If you get tired of playing, the host or group administrator can cancel the game using the /cancel command.

Built with

Telegram Web App consists of a simple HTTP server that serves static .html, .js and .css files, uses SSE to listen for game updates, and a vanilla js client with canvas controlled by Telegram chat/group bot.

Endpoints

/bot/* - Telegram Bot Webhook endpoint

/web/app - Telegram Web App

/web/app/static - Static resources for Telegram Web App

/web/app/update - Update host drawings; client side call

/web/app/word - Get current hidden word; client side call

/web/app/events - Server-Sent Events (SSE) endpoints with game events; client side call

/web/app/* endpoints calls secured by validating Telegram.WebApp.InitData string on server side.

Prepare

  1. Create Telegram Bot

    1.1. Disable privacy mode for accessing to user messages and allow adding to groups thru @BotFather (/mybots)

    1.2. You will need a domain with SSL; during development, you can use ngrok or the port forwarder built into vscode.

  2. Create Telegram Web App:

    Send command to @BotFather and attach app to the bot:

    /newapp
    
  3. Setup Postgres database or use it from Docker

  4. Fill .env with your data

    .env-example - env config example.

    .env overview
    # Bot token from @BotFather
    BOT_TOKEN=1234:fokspdokf
    # host.com/bot/{WEBHOOK_ENDPOINT_SECRET} (generated by yourself)
    WEBHOOK_ENDPOINT_SECRET=
    # Telegram Bot API security token (generated by yourself)
    TELEGRAM_BOT_API_SECRET_TOKEN=
    # Telegram Web app direct url from @BotFather
    TELEGRAM_BOT_WEB_APP_URL=
    # Database URL
    DB_URL=postgresql://user:user@postgres:5432/user
    # Host domain
    HOST=
    # Local port
    PORT=
    # Initial reusable image via `file_id`
    # can be obtained as follows:
    # 1. Send the image (`./resources/initial_canvas.jpg` ) to your bot
    # 2. Get `file_id` from this message (e.g., forward message to https://t.me/JsonDumpBot),
    # `file_id` should be usable only for your bot
    INITIAL_CANVAS_FILE_ID=

Deploy

nginx reverse proxy config
...
server {
    ...
    location /bot/ {
        proxy_pass http://localhost:PORT;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /web/ {
        proxy_pass http://localhost:PORT;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    ...
}
...

Docker:

docker-compose build # build
docker-compose up -d # start

Heroku buildpack:

Push to any PaaS that supports heroku buildpacks with provided environment variables

Locally:

  1. Create and activate python virtual environment

    python -m venv myvenv
    source ./myvenv/Scripts/activate # linux
    myvenv/Scripts/activate # windows
  2. Install dependencies

    pip install -r requirements.txt
  3. Run

    python main.py

Working with localizations (using Babel)

Localization files must be updated and compiled for almost every source code update (1, 3, 4 and 5 steps).

  1. Extract _("string") strings:

    pybabel extract --input-dirs=. --ignore-dirs=venv -o ./locales/messages.pot
  2. Add language (en - language code):

    pybabel init -i locales/messages.pot -d locales -D messages -l en
  3. Update localizations:

    pybabel update -d locales -D messages -i locales/messages.pot
  4. Do translation in localizations files (*.po)

  5. Compile localizations:

    pybabel compile -d locales -D messages