Skip to content

A Telegram bot for my final project for my Advanced Programming course. Branches/features written by me are boardgame, boardgame-moves and visualfeatures.

License

Notifications You must be signed in to change notification settings

chadmadna/CSUIBot

Repository files navigation

CSUIBot

How the Bot Works

There are two ways for the bot to get updates from Telegram: long polling and webhook. In this project, we are using webhook. Using setWebhook method provided by Telegram API, we can associate a bot with a webhook URL so that whenever there is an update (a new message, a new member joining a group, etc.), Telegram will send the update data to the webhook URL in a JSON format. The general steps are as follows:

  1. An update occurs in a chat or group of which the bot is a member.
  2. Telegram sends the update to the bot's webhook URL as HTTP POST request containing JSON data.
  3. Server makes a request to Telegram via its Bot API to initiate bot's response, while responding with 200 status to the HTTP POST request made by Telegram.

More detailed information can be found here.

Development Guide

How to set up your machine

  1. Setup your Python virtual environment using venv as you did in week 8 tutorial. Name your virtual environment folder as env. If you use PyCharm, you may want to configure it to recognize your virtual environment too.

  2. Navigate to the directory where you've cloned this repo and create a virtual environment under the env directory. Then, activate the virtual environment.

  3. Still in the directory where you've cloned this repo, install all its dependencies.

    pip install -r requirements.txt

    Dependencies are all listed in requirements.txt. To re-generate this file (after you've installed new packages), simply run pip freeze > requirements.txt. For Linux users, if you have a problem installing the dependencies, install python3-dev or python3-devel system package first.

  4. Create .env file under the project root directory. It contains the configuration variables for the application. Sample .env file can be found in .env.example.

  5. Run the app

    python manage.py runserver
  6. The app is now running! To check that the bot is actually running, try to send a GET request to it, for instance:

    curl http://127.0.0.1:5000

    or open http://127.0.0.1:5000 from your browser. You should get a response that says:

    Bot is running

How to run the tests/linters

  1. Make sure you already installed pytest and flake8. Both are listed in requirements.txt so if you followed the instructions to setup your machine above then they should already be installed.

  2. Put an .env file under your tests directory. This file could be identical to the one in project root directory or you may also set some environment variables for testing to your liking.

  3. You can run the tests and linters with python manage.py test and python manage.py lint respectively.

  4. To run both linters and tests in one command, you can use python manage.py check. This is useful to check your code before making a merge request.

  5. For more info on what you can do with manage.py, run python manage.py --help.

How to Contribute

If you want to write new features to CSUIBot or fix bugs, that's great! Here is a step-by-step guide to contribute to CSUIBot's development.

General Flow

  1. You need an issue on Pivotal Tracker about your contribution. This can be a bug report (in which case your contribution is the bug fix) or feature suggestion (in which case your contribution is the implementation).

  2. Make sure that you are in master branch by running git status. If not, run git checkout master to move to master branch.

  3. Create a new branch on which you write your code. Use any branch name as you which. For example, cool-feature:

    git checkout -b cool-feature
  4. Implement your contribution in the branch.

  5. Periodically, and after you committed your changes, pull the latest changes from master. This ensures your branch is always up-to-date with the origin.

    git pull --rebase origin master

    Fix any conflicts that may arise.

  6. After you really finished writing the code, commit your changes. You may create one or more commits.

  7. Push the feature branch to origin:

    git push origin cool-feature
  8. Create a new merge request on Gitlab for cool-feature branch to be merged to master. Refer the Pivotal Tracker's issue in the merge request description.

  9. Wait for other project members and class instructors to review your contribution.

  10. If they approve your contribution, congrats! Your contribution may be merged to master. First, don't forget to rebase your branch against master:

    git pull --rebase origin master

    Again, fix any conflicts that may arise.

  11. Then, clean up your commits. Do a interactive rebase (please Google this term).

    git rebase -i origin/master

    Squash all your commits into one commit only and rewrite the commit message into a meaningful one, preferably mentioning what feature/bugfix your changes introduce.

  12. Force-push your feature branch to origin:

    git push -f origin cool-feature
  13. Ask the class instructors to merge your contribution to master.

  14. After your contribution is merged, you may safely delete your feature branch:

    git branch -D cool-feature

    Also delete your feature branch on origin from Gitlab.

    git push origin :cool-feature
  15. Done!

How to Test Your Bot Locally

Suppose we're going to test our handler for /about command.

  1. Set your .env file if you'd like. The following instructions will assume that you set your .env file exactly the same as the example provided in .env.example:

    APP_ENV="development"
    DEBUG="true"
    TELEGRAM_BOT_TOKEN="somerandomstring"
    LOG_LEVEL="DEBUG"
    WEBHOOK_HOST="127.0.0.1"
    
  2. Start your bot locally by running python manage.py runserver. Make sure you've already activate your virtual environment before issuing this command.

  3. Open csuibot/handlers.py file and take a look at help handler.

    @bot.message_handler(commands=['about'])
    def help(message):
        app.logger.debug("'about' command detected")
        about_text = (
            'CSUIBot v0.0.1\n\n'
            'Dari Fasilkom, oleh Fasilkom, untuk Fasilkom!'
        )
        bot.reply_to(message, about_text)

    Notice that we have bot.reply_to(message, about_text). This line means that we're sending a reply message containing the text stored in about_text variable to Telegram. However, note that in our configuration file (i.e. .env file) we are using a fake Telegram bot token, i.e. somerandomstring. So, this line will fail. Even if we're using real bot token, this line will most likely fail since we're going to use a fake data (this will be clear later). So, for testing locally, we don't want this behavior. We should assume that this line will work correctly since we're using PyTelegramBotAPI library for this. We should replace that line, for instance with a print statement:

    # bot.reply_to(message, about_text)
    print(about_text)  # we print the about text instead of sending it
  4. Now, we are going to simulate someone invoking /about command to our bot. From Telegram Bot API,

    Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.

    so we need to make a POST request containing an /about command. To do this, you may want to use an HTTP client tool, such as Cocoa REST client for OSX, Postman extension for Google Chrome, or RESTclient add-on for Firefox. If you prefer to use curl it's fine too.

    Our webhook URL is http://localhost:5000/somerandomstring. Telegram's Update object containing /about command in JSON format look like this:

    {
        "update_id": 1,
        "message": {
            "message_id": 1,
            "date": 12345,
            "chat": {
                "id": 123,
                "type": "group"
            },
            "text": "/about"
        }
    }

    The data above is obviously fake. The most important thing is our message has /about as its text. Other fields are mandatory so we can simply fill them with fake data. You can find what fields are required for each types in Telegram Bot API types documentation.

    Now, make a POST request to our webhook URL with the above JSON as its payload. If you're using curl, the command look like this

    curl -H "content-type: application/json" --data '{"update_id": 1, "message": {"message_id": 1, "date": 12345, "chat": {"id": 123, "type": "group"}, "text": "/about"}}' http://localhost:5000/somerandomstring

    Please find out by yourself on how to make such request using your chosen HTTP client.

  5. Take a look at your terminal window where you've started the bot. You should see the about text printed to the screen like so:

    CSUIBot v0.0.1
    
    Dari Fasilkom, oleh Fasilkom, untuk Fasilkom!
    

    This means when the /about command is invoked, our handler is run.

In summary, to test your bot locally all you need to do is simulating Telegram sending an Update to your webhook URL via HTTP POST request with the update data in JSON format as its payload. But be careful not to actually send a bot reply since the bot token and/or the data are fake.

About

A Telegram bot for my final project for my Advanced Programming course. Branches/features written by me are boardgame, boardgame-moves and visualfeatures.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages