Skip to content

Repository files navigation

🐟 Telegram Fish Store Bot

An asynchronous Telegram bot tailored for a fish store. This application bridges a sleek and highly interactive Telegram customer interface with a powerful Strapi CMS backend for real-time inventory management, catalog distribution, and secure user processing.

By leveraging an asynchronous Redis connection pool, the bot manages independent customer session states (FSM) and high-speed memory locks to guarantee a non-blocking user experience under request concurrency. The entire network architecture is built on cooperative multitasking, utilizing aiohttp and python-telegram-bot v22.x to enable customers to seamlessly browse fresh product assortments, modify shopping carts, and finalize order details dynamically right from their devices.

Telegram Fish Store Bot

πŸ“Œ Table of Contents

βš™οΈ Tech Stack

  • Operating System: Linux, macOS, or Windows (via WSL2)
  • Language: Python 3.11+
  • Database: PostgreSQL & Redis (via Docker)
  • Configuration: pydantic-settings & pydantic
  • Backend: Node.js v24.x & Strapi
  • Async Telegram Bot Framework: python-telegram-bot v22.x
  • Async HTTP Framework: aiohttp
  • Containerization & Orchestration: Docker & Docker Compose

πŸ“ Project Structure

.
β”œβ”€β”€ logs/                     # Dynamically generated application logs folder
β”œβ”€β”€ strapi/                   # Strapi files
β”œβ”€β”€ .env.example              # Example of environment variable configuration
β”œβ”€β”€ config.py                 # Central application settings mapper
β”œβ”€β”€ database.py               # Connection pool setup for Redis
β”œβ”€β”€ logging_config.py         # Non-blocking async queue logger
β”œβ”€β”€ keyboards.py              # Dynamic InlineKeyboardMarkup factories for navigation controls
β”œβ”€β”€ screens.py                # Interface rendering functions layer for message transitions
β”œβ”€β”€ handlers.py               # Core asynchronous FSM step handlers routing user navigation
β”œβ”€β”€ strapi_api.py             # Asynchronous Strapi CMS HTTP integration engine
β”œβ”€β”€ main.py                   # Main entry point for the Telegram bot
β”œβ”€β”€ Dockerfile.strapi.dev     # Strapi container blueprint
β”œβ”€β”€ docker-compose-dev.yaml   # Docker services orchestration
└── requirements.txt          # Python dependencies

πŸ› οΈ Installation and Setup

Prerequisites:

Basic Setup:

1. Clone the repository:

git clone https://github.com/...
cd project-directory

2. Configure environment variables:

Create a .env file in the root directory based on .env.example and fill in the variables for PostgreSQL if you plan to run it through Docker, or leave them blank:

# PostgreSQL
DATABASE_PORT=5433
DATABASE_NAME=postgres_db
DATABASE_USERNAME=postgres_user
DATABASE_PASSWORD=your_postgres_password

# Adminer
ADMINER_PORT=8080

# Redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password

# Logging
LOG_LEVEL=INFO

# Strapi API
STRAPI_TOKEN=your_full_access_or_custom_token
STRAPI_URL=http://localhost:1337
STRAPI_USER_ROLE=1  # Authenticated user role id
STRAPI_USER_PASSWORD=your_password_for_strapi_user_creation

# Telegram
TG_BOT_TOKEN=your_bot_token

Backend Setup (Strapi)

1. Initialize a new Strapi project:

From the root directory, create a Strapi app inside the strapi folder:

cd project-directory
npx create-strapi-app@5.48.1 strapi

2. Configure environment variables in strapi/.env:

In the automatically created .env file in the strapi folder configure your database choice. Make sure the database variables in strapi/.env and the root .env match:

# Database
DATABASE_CLIENT=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5433
DATABASE_NAME=fish_store
DATABASE_USERNAME=fish_store_user
DATABASE_PASSWORD=your_postgres_password

Frontend Setup (Telegram Bot)

1. Set up a virtual environment:

python -m venv venv
venv\Scripts\activate # on Windows
source venv/bin/activate # on Linux / macOS

2. Install Python dependencies:

pip install -r requirements.txt

πŸš€ Quick Start Guide

Development Server Launch

1. Spin up the backend stack (PostgreSQL, Redis, and Strapi):

Make sure your environment variables are configured in the root .env and strapi/.env files. Then, run the following command from the root directory to build and launch all backend services in development mode:

docker compose -f docker-compose-dev.yaml up --build

ℹ️ Note: The infrastructure automatically configures internal networking. Strapi will wait until PostgreSQL is healthy before initialization.

You can access the admin panel at http://localhost:1337/admin.

2. Run the Telegram bot:

Open a new terminal window or tab in the project root directory, activate your Python virtual environment, and boot up the bot application:

python main.py

3. Test the bot:

Open Telegram, find your bot, and send the /start command.

4. Useful Docker Compose commands:

  • docker compose -f docker-compose-dev.yaml down - Stop and remove all containers and networks defined in the dev configuration.
  • docker compose -f docker-compose-dev.yaml up -d - Start all containers in detached background mode.
  • docker compose -f docker-compose-dev.yaml restart - Restart all containers.
  • docker compose -f docker-compose-dev.yaml logs -f strapi - View and follow real-time logs from Strapi.

πŸ“Š Database Models Architecture (Strapi v5)

The database relies on a junction model (CartProduct) to handle a custom Many-to-Many relationship between Carts and Products, allowing the bot to store unique metadata like product quantities.

1. User (System Model: users-permissions)

Extends the standard Strapi user model to associate customers with their active sessions.

  • cart (Relation) - User has and belongs to one Cart.
  • orders (Relation) - User belongs to many Orders.

2. Product

Stores the shop's assortment data.

  • title (Short Text) - Name of the fish / seafood item.
  • description (Long Text) - Detailed product description.
  • price (Decimal Number) - Price per 1 kilogram.
  • picture (Media: Single Media) - Image file uploaded to the Media Library.
  • cart_products (Relation) - Product belongs to many CartProducts.

3. Cart

Maintains live Telegram user sessions.

  • tg_id (Short Text) - Unique Telegram Chat ID.
  • users_permissions_users (Relation) - Cart has and belongs to one User.
  • cart_products (Relation) - Cart belongs to many CartProducts.

4. CartProduct (Junction Model)

Acts as a pivot table to keep track of dynamic quantities for items inside specific carts.

  • cart (Relation) - Cart has many CartProducts.
  • product (Relation) - Product has many CartProducts.
  • quantity (Decimal Number) - The weight of items added.

5. Order

Stores order data.

  • order_id (Short Text) - Unique order identifier.
  • users_permissions_users (Relation) - User has many Orders.
  • phone_number (Short Text) - The phone number provided by the user.
  • active (Boolean) - Order status (active or inactive). Only one order can be active at a time.
  • order_items (JSON) - A list of products including the item name, quantity, and price at the time of the order in JSON format.

πŸ”‘ Strapi v5 Backend Configuration

To ensure the Telegram bot can successfully communicate with Strapi v5, you need to configure specific roles and permissions in your Strapi Admin Panel http://localhost:1337/admin.

How to Find the Authenticated Role ID

When the bot automatically registers a new customer using their email during checkout, it forces Strapi to assign them to a default system role (typically Authenticated). To find the exact ID of this role for your strapi_api configuration:

  1. Navigate to Settings βž” Roles (under the Users & Permissions Plugin section).
  2. Click on the Authenticated role to open its settings.
  3. Look at your browser's address bar. The URL will end with a specific number (e.g., .../users-permissions/roles/1).
  4. This number is your Authenticated Role ID. Set this value in your .env file.

Permissions Required for a Custom API Token or Full Access Token

If you are connecting your Telegram bot to Strapi using a Custom API Token (generated via Settings βž” API Tokens with token type set to Custom), you must explicitly check the boxes for the following permissions at the bottom of the token settings page:

πŸ“¦ Core Store Models (Custom Content-Types)

Cart:

  • find (allows checking if a user already has a shopping cart)
  • create (allows creating a new shopping cart for a first-time user)
  • update (allows linking a Strapi User to an existing Cart during checkout)

Cart-Product:

  • find (allows reading cart items to display them in the telegram cart screen)
  • create (allows adding a new item to the cart)
  • update (allows incrementing or decrementing product quantities)
  • delete (allows removing an item from the cart)

Order:

  • find (allows locating an active order)
  • create (allows creating a new order)

Product:

  • find (allows pulling the full list of products for the catalog)
  • findOne (allows opening a detailed product description card)

πŸ‘₯ System Models (Advanced Plugins):

Users-Permissions (under the User subsection)

  • find (allows looking up if a customer's email is already registered)
  • create (allows registering a new user profile with their email during checkout)
  • update (allows updating the user's email)

Upload (Media Library plugin):

  • find (allows the bot to deep-populate and extract relative URLs for fish images stored inside product relations)

πŸ” Managing PostgreSQL via Adminer (Docker only)

This project includes Adminer, a lightweight and fast database management interface available via web browser. It is configured to run inside a Docker container alongside PostgreSQL.

How to Access Adminer

1. Make sure your Docker container is running:

docker-compose -f docker-compose-dev.yaml up -d

2. Open your web browser and navigate to: http://localhost:8080.

3. Fill in the login form using your environment variables from the .env file:

  • System: PostgreSQL
  • Server: postgres (This must match the service name defined in your docker-compose-dev.yaml file)
  • Username: [Your DATABASE_USERNAME]
  • Password: [Your DATABASE_PASSWORD]
  • Database: [Your DATABASE_NAME]

4. Click login. You can now view tables, run custom SQL queries, and manage data directly from your browser.

πŸ” Inspecting Redis Data via Docker

1. Access the Redis container CLI.

Run the following command to open the interactive Redis CLI inside your running container:

docker compose -f docker-compose-dev.yaml exec redis redis-cli
127.0.0.1:6379> AUTH <your_redis_password>

Or you can log in via the CLI arguments:

docker compose -f docker-compose-dev.yaml exec redis redis-cli -a <your_redis_password>

⚠️ Use this command only for local development.

2. Useful Redis commands.

Once inside the CLI, you can use these basic commands to inspect the bot's state:

  • KEYS * - List all keys currently stored in the database.
  • GET <key> - View the content of a specific text key.
  • TTL <key> - Check the remaining Time-To-Live for temporary keys.
  • DEL <key> or DEL <key1> <key2> - Remove specific keys from the database.
  • UNLINK <huge_key> - Asynchronously delete huge keys without blocking the main thread.
  • FLUSHDB - Clear all data from current database.
  • FLUSHALL - Clear all data from all databases.

3. Exit the CLI.

Type exit or press Ctrl + C to return to your local terminal.

About

An asynchronous Telegram bot for a fish store integrated with Strapi headless CMS. Powered by Python (python-telegram-bot), Node.js, Redis (FSM & caching), PostgreSQL, and Docker.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages