Skip to content

roataway/telegram-bot

Repository files navigation

image

GitHub license

Chat with the developers on Zulip

Use the chat bot on Telegram

Overview

A Telegram bot to provide ETA for public transport in Chișinău. A live instance is available at http://t.me/roataway_bot.

The bot is written in Python and it was tested with 3.6, though earlier versions will work too, if you install the backported version of the dataclasses module.

Discussions and development support

Head to to ask questions about the code and its structure, suggest new features or ask for tips on how to get started with running your own copy of the bot.

How to run it

Prerequisites

  1. Talk to @BotFather to register your bot and get a token, as described here: https://core.telegram.org/bots#6-botfather
  2. Make a copy of res/config-sample.yaml to your own config file, e.g. config-development.yaml, supplying the required information in the file
  3. Replicate the environment using virtualenv or pipenv, as described below
  4. When done, run it with python main.py res/config-development.yaml

The credentials as well as the server connection details are deliberately not a part of this repository. They can be found on rtec.dekart.com/infodash. The ability to figure it out on your own is the qualification barrier for getting started with this bot. Note that infodash uses WebSTOMP, rather than MQTT; however, the credentials are the same.

Virtualenv

  1. Create the virtualenv virtualenv venv-infopanel-chatbot to install the dependencies in it
  2. Activate the venv with source venv-infopanel-chatbot/bin/activate
  3. Install the dependencies with pip install -r requirements.txt

Pipenv

  1. Install pipenv pip install pipenv
  2. Then run pipenv install --dev. It will deal automatically with the venv creation and dependecy installing

Technical details

The bot uses MQTT to subscribe to updates related to ETAs and the locations of trolleybuses.

Message formats

There are 2 types of messages that are received via MQTT at the moment, all payloads are in JSON format:

1. ETA updates that contain a list of estimates for the next couple of incoming transports. Such messages arrive in batches, approximately twice per minute: :

{
  "station_id": 17,    # the station ID to which the prediction refers
  "name": "str. 31 August - sosire"   # the name of the station
  "eta": {
    "30": [            # the route number to which the prediction refers
      [3, "3898"],     # 3 minutes until board "3898" arrives
      [22, "3913"]     # 22 minutes until board "3913" arrives
    ]
  },
}

2. Transport coordinates, which contain data about the last known location and speed of a given trolleybus. These are sent every ~6s: :

{
"rtu_id": "004",  # internal identifier in the backend, you can ignore it
"board": "3900",  # the board number, it is written on the trolleybuses themselves
"route": "30",    # human-readable name of route (may contain letters)
"lat": "47.027388",
"lon": "28.885762",
"dir": "0",       # direction of motion, measured in degrees. Note that the
                  # coordinate system is _not_ cartesian, but the one you see
                  # on a compass. North is up at 0, East is right at 90,
                  # South is down at 180, West is right, at 270 degrees.
"speed": 0,       # in km/h
}

The JSON may contain other keys, do not rely on them if they're not documented.

Station details

The information about supported stations is loaded from CSV files located in res/routes, the format is station_id, station_order, station_name, direction. The identifiers are generated by the RTEC database, we just have to assume they are constants.

The resources in res/routes/drafts are treated as work in progress, and are ignored when the data are loaded.

How to contribute

For historical reasons, the code, comments and the instructions are written in English. Ideally, you should follow the same conventions. When opening issues, you can describe them in Romanian or Russian, besides English.

If you made any changes, send a pull request, explaining what you've done and why you've done it.

If you need any help, just ask.

Before commit

  1. Run make autoformat to format all .py files
  2. Run make verify and examine the output, looking for issues that need to be addressed

Building the readme

  1. Install rst2html (on Debian and its derivatives: sudo apt install docutils-common).
  2. Run rst2html readme.rst > readme.html to render the output and make sure it looks good.

Bot configuration

To set a lit of commands, go to @BotFather and send /setcommands for the bot, with the following data:

prognosis - Vezi prognoza pentru o rută
feedback - Transmite sugestiile sau întrebările tale
help - Află cum îți pot fi de folos
about - Despre mine

Notes on obtaining feedback_chat_id, it is a unique chat identifier, which you need if you want the bot to post messages somewhere. You can get this number using several methods:

  1. Go to https://api.telegram.org/bot<token>/getUpdates and look around
  2. Or add @RawDataBot to the group or the channel in question, and watch its debug output as you post a message. Don't forget to kick it out of the group once you've got the number.

Contributors and credits

  • Roata wăy relies on an external data stream. None of the features of this bot would work without the backend and the hardware designed for deployment on the trolleybuses themselves.
  • The production bot instance is hosted on a server generously provided by name withheld.
  • Initial proof of concept written by name withheld #2.
  • Others listed here: https://github.com/roataway/telegram-bot/graphs/contributors
  • How about 👉 you 👈?