Skip to content

st-matskevich/audio-guide-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

header

Audio Guide Bot

Telegram bot for taking audio tours, built on top of Telegram Mini App Template.

Guide is available at @audio_guide_bot.
Bot supports only mobile Telegram clients with Telegram Bot API version of at least 6.9.
Payments are working in test mode. Transactions must be made using test cards like 4242 4242 4242 4242, other cards can be found in payments provider docs.
QR codes for the bot can be found in /admin/test-data.

qrs demo

Features

  • Integration with Telegram Payments - Guide Bot tickets can be bought directly in Telegram
  • Integration with Telegram CloudStorage - after activation, the user's ticket is available to all user devices
  • UI delivered as Telegram Mini App - no need for a standalone application, Guide Bot is available as a part of Telegram bot
  • Adaptive UI - Guide Bot will automatically pick up the user's color theme and adapt the size to both expanded and minimized modes
  • Local environment with docker-compose- spin-up bot environment locally in one command
  • Continious deliviery to Google Cloud Platform - all changes to the main branch are automatically delivered to the production

Usage

  1. Complete setup prerequisites
  2. Start the bot locally or deploy it to the production
  3. Configure bot and enter data about your objects
  4. Message your bot, buy a ticket, scan the code, and start listening

Setup prerequisites

Telegram Bot token is required to interact with Telegram Bot API. To get one, сreate a bot using @BotFather or follow Telegram bot instructions.

Telegram Payments token is required to start accepting payments for tickets. To get one, request it from @BotFather or follow Telegram payments instructions.

Local environment

This repository provides an easy-to-use local development environment. Using it you can start writing your bot business logic without spending time on the environment.

Local environment includes:

  • ngrok reverse proxy to server local mini-app and bot deployment over HTTPS
  • nginx reverse proxy to host both API and UI on one ngrok domain and thus fit into the free plan
  • React fast refresh to avoid rebuilding docker container on each change of the UI code
  • PostgreSQL database instance and pgAdmin instance to manage it
  • s3gw S3 instance and s3gw-ui instance to manage it

Local environment setup:

  1. Create an account on ngrok
  2. Get a ngrok auth token and save it to NGROK_AUTHTOKEN variable in .env file in the project root directory
  3. Claim a free ngrok domain and save it to NGROK_DOMAIN variable in .env file in the project root directory
  4. Copy Telegram Bot token and save it to TELEGRAM_BOT_TOKEN variable in .env file in the project root directory
  5. Copy Telegram Payments token and save it to TELEGRAM_PAYMENTS_TOKEN variable in .env file in the project root directory
  6. Generate random string for JWT signing secret and save it to JWT_SECRET variable in .env file in the project root directory
  7. Install Docker

To start or update the environment with the latest code changes, use:

docker compose up --build -d

After successful deployment, your local bot API will be available at https://ngrok-domain/api. Use this URL to set the bot webhook as described switching bot environment.

Production deployment

This repository provides a workflow to automatically deploy the code to Google Cloud Platform. The deploy job is triggered on each push to the main branch.

GCP services used for deployment:

Deployment setup:

  1. Create a project in GCP
  2. Copy project ID and save it to GCP_PROJECT_ID GitHub variable
  3. Pick a region for your app and save it to GCP_PROJECT_REGION GitHub variable
  4. Create a service account with the following rights:
    • Service Account User (to create resources by the name of this account)
    • Cloud Run Admin (to create Cloud Run instances)
    • Artifact Registry Administrator (to manage images in the registry)
    • Secret Manager Secret Accessor (to access GCP secrets)
    • Cloud SQL Client (to connect to the Cloud SQL instance)
    • Storage Object User (to access objects in Cloud Storage bucket)
  5. Copy the service account email and save it to GCP_SA_EMAIL GitHub variable
  6. Export the service account key and save it to GCP_SA_KEY GitHub secret
  7. Enable the following GCP APIs:
    • Cloud Run Admin API (to create Cloud Run instances)
    • Secret Manager API (to securely store secrets)
    • Compute Engine API (to create Cloud SQL instances)
    • Cloud SQL Admin API (to connect Cloud Run to Cloud SQL)
  8. Create Artifact Registry for Docker images in GCP_PROJECT_REGION region
  9. Copy Artifact Registry name and save it to GCP_ARTIFACT_REGISTRY GitHub variable
  10. Create a PostgreSQL Cloud SQL instance in GCP_PROJECT_REGION region
    • If you want to reduce the cost of the instance:
      • You can implement instance scheduler
      • You can set "Zonal availability" to "Single zone" instead of "Multiple zones (Highly available)"
      • You can set the machine configuration to the minimal one (1 shared vCPU, 0.614 GB RAM)
      • You can set the storage type to HDD
      • You can reduce storage size to 10 GB
  11. Copy Cloud SQL instance connection name, that can be found on the Overview page for your instance, and save it to GCP_SQL_INSTANCE_CONNECTION_NAME GitHub variable
  12. Create a user for your Cloud SQL instance
  13. Create a database for your Cloud SQL instance
  14. Create a Cloud Storage bucket in GCP_PROJECT_REGION region
  15. Create an HMAC key for your service account
  16. Create the following secrets in Secret Manager:
    • Telegram Bot token and save the secret name to GCP_SECRET_TG_BOT_TOKEN GitHub variable
    • Telegram Payments token and save the secret name to GCP_SECRET_TG_PAYMENTS_TOKEN GitHub variable
    • Random string for JWT signing secret and save the secret name to GCP_SECRET_JWT_SECRET GitHub variable
    • PostgreSQL connection string and save the secret name to GCP_SECRET_DB_URL GitHub variable
      • Connection string format is postgres://{USER}:{PASSWORD}@/{DATABASE}?host={HOST}, where:
        • {USER} is the name of the user created for Cloud SQL instance above
        • {PASSWORD} is the password of the user created for Cloud SQL instance above
        • {HOST} is the /cloudsql/{INSTANCE_CONNECTION_NAME}, where {INSTANCE_CONNECTION_NAME} is the Cloud SQL instance connection name, that is equal to GCP_SQL_INSTANCE_CONNECTION_NAME
        • {DATABASE} is the name of the database created for Cloud SQL instance above
    • Cloud Storage connection string and save the secret name to GCP_SECRET_S3_URL GitHub variable
      • Connection string format is https://{KEY}:{SECRET}@storage.googleapis.com/{BUCKET}, where:
        • {KEY} is the key of the service account HMAC key created above
        • {SECRET} is the secret of the service account HMAC key created above
        • {BUCKET} is the name of the bucket created in the Cloud Storage above
  17. Define the following GitHub variables:
    • GCP_SERVICE_MIGRATOR_NAME with the desired name of DB migration Cloud Run job
    • GCP_SERVICE_UI_NAME with the desired name of UI Cloud Run instance
    • GCP_SERVICE_UI_MAX_INSTANCES with the desired maximum number of UI service instances
    • GCP_SERVICE_API_NAME with the desired name of API Cloud Run instance
    • GCP_SERVICE_API_MAX_INSTANCES with the desired maximum number of API service instances

After successful deployment, obtain the bot API URL from either deploy-services job results or from GCP Project Console and proceed to switching bot environment.

Switching bot environment

After the bot is either launched locally or deployed in GCP, Telegram needs to be configured with a proper webhook URL. To set it, use:

curl https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/setWebhook?url=${BOT_API_URL}/bot

Administration

In the case of local environment, pgAdmin for DB management and s3gw-ui for S3 management are already running as containers. Discover their addresses in your docker daemon.
In case of production deployment, S3 management is available from GCP Project Console, but for DB management you need to setup an instance of pgAdmin with cloud-sql-proxy to connect to your Cloud SQL instance. Instructions are available in /admin.

To configure the Guide Bot you need:

  1. Connect to the DB using DB management tool
  2. Create a row in config table with key equal to TICKET_CURRENCY and value equal to the ticket price currency code
  3. Create a row in config table with key equal to TICKET_PRICE and value equal to the ticket price in the smallest units of the currency

To create an object in the Guide Bot you need:

  1. Prepare the data
    • Title: string that will be displayed as a title of the object. It must not exceed 64 characters. Title string can be added in different languanges to provide translations for users.
    • Code: string that will be encoded in a QR code to access your object
    • Covers: collection of image files that will be displayed while listening to the Guide. Amount of covers is not limited. Cover image can be any size but will be cropped to 1:1 proportions to fit in the UI. Also, keep in mind that a large size slows down the loading of the object.
    • Audio: audio file that will be played when viewing the object. It can be any size, but keep in mind that a large size slows down the loading of the object. Audio file can be added in different languanges to provide translations for users.
  2. Connect to the S3 bucket using S3 management tool
  3. Upload Covers and Audio to the bucket and save paths to the uploaded files. Make sure to include the original file extension in the file name otherwise, some clients will not be able to play audio tracks.
  4. Connect to the DB using DB management tool
  5. Create a new row in the objects table
    • Set code to the value of Code
  6. Create a new row in the objects_i18n table
    • For each language (at least data for en language must be provided):
      • Set object_id to the id of the row created in the previous step
      • Set language to language code in ISO 639-1 format
      • Set title to the value of Title in the specified language
      • Set audio_path to the path of the uploaded file Audio in the specified language
  7. Create a new row in the covers table for each uploaded file from Covers collection
    • Set object_id to the id of the row created in the previous step
    • Set index to the number indicating the order in which the picture will be displayed
    • Set path to the path of the uploaded file from Covers collection
  8. Encode Code to the QR Code to access your object from the Guide Bot

For testing purposes you also can use files from /admin/test-data.

Project overview

Project is built of 4 parts:

  • API Service - implements integration with Telegram API and Guide business logic
  • UI Service - user interface in the format of Telegram MiniApp
  • Database - stores entity data such as tickets or objects
  • Blob storage - stores binary files such as object images or audio tracks

Project design:

  • Base project entity is called Object - any point of interest that will be available in the system
  • All objects include:
    • Title - name of the object
    • Code - unique text data that is used for object identification
    • Covers - array of images associated with the object
    • Audio - audio track associated with the object
  • Access to the objects is provided by scanning QR codes with encoded object code
  • Access to the objects is limited by token-based authorization
  • Token validity is limited by the expiration date
  • Token must be persisted until it becomes invalid
  • Token can be acquired by activating a separate entity - Ticket
  • Ticket includes:
    • Code - unique text data that is used for ticket identification
    • Activation flag - once set to true, cannot be activated anymore
  • Ticket can be bought via Telegram Payments

Project structure

  • Project root directory - contains files for local environment
  • api - contains files for the bot backend written in Go, check the README file for details
  • ui - contains files for the mini app UI written in JS with React, check the README file for details
  • admin - contains files for production administration environment, check the README file for details

Built with

License

Distributed under the MIT License. See LICENSE for more information.

Contributing

Want a new feature added? Found a bug? Go ahead and open a new issue or feel free to submit a pull request.