Skip to content

Completely free bot to automate the publication of user-suggested content in the Telegram channel.

License

Notifications You must be signed in to change notification settings

iwatkot/affirmbot

Repository files navigation

Completely free bot to automate the publication of user-suggested content in the Telegram channel.

OverviewQuick StartStep-by-step guideCustom templatesEntry Types

AdministrationHow to use the botBugs and Feature RequestsFor developersUpcoming Features

GitHub release (latest SemVer) GitHub issues Docker pulls Maintainability

Overview

This bot is designed to automate the publication of user-suggested content in the Telegram channel. It supports custom templates for users to fill in, accept and reject suggestions, and automatically publish them after approval.
It's completely free and open-source, so you can host it yourself for your own needs without any restrictions, even for commercial purposes.

Quick Start

Long story short, you can run the bot with a single command (it will use default built-in templates):

docker run -e TOKEN="TELEGRAM_BOT_TOKEN" -e ADMINS="TELEGRAM_ID,TELEGRAM_ID" iwatkot/affirmbot

Or you can use your templates, in this case, you'll need to create a public GitHub repository with a config.yml file, containing your templates:

docker run -e TOKEN="TELEGRAM_BOT_TOKEN" -e ADMINS="TELEGRAM_ID,TELEGRAM_ID" -e CONFIG="github_username/repo_name" iwatkot/affirmbot

After the bot is started, remember to connect it to the channel where you want to publish the suggestions, you can learn how to do it in the Channel section.
If you ensured that the bot was added to the channel, you can add the environment variable CHANNEL with the channel ID to the docker run command. In this case, the bot will be connected to the channel from the start, but it won't check if it was added correctly.

docker run -e TOKEN="TELEGRAM_BOT_TOKEN" -e ADMINS="TELEGRAM_ID,TELEGRAM_ID" -e CHANNEL="CHANNEL_ID" iwatkot/affirmbot

Here's the full list of environment variables you can use:

Variable Required Description
TOKEN The token of your Telegram bot.
ADMINS A list of admin Telegram IDs.
CHANNEL The channel ID where the suggestions will be published.
CONFIG The GitHub repository with the config.yml file.
ENV For developers only, if set to "DEV", the bot will run in the development mode.

Step-by-step guide

If you're a rookie and don't know anything about Docker, GitHub, and all that stuff, this section is for you.

Step 1: Create a Telegram bot

In this step, you need to create a Telegram bot and get its token. To do this, you need to talk to the BotFather and follow the instructions, it's very simple. After the bot is created, you will receive a token. Save it, you will need it later. Friendly reminder: don't share your token with anyone, it's a secret key to control your bot.
The token looks like this: 1234567890:ABCdefGhIjKlmnOpqrStuVwXyz1234567890.

Step 2 (optional): Find a hosting

The bot needs to be hosted somewhere, but actually, you can run it on your local machine. This is why this step is optional. But if you rent a server, I suggest you deploy it on Ubuntu. And if you don't know what to do, and what is the hosting, you can use DigitalOcean since it has detailed instructions and a simple interface. You even can connect to the console from a web browser to avoid learning some scary words like "SSH".

Step 3: Install Docker

No matter where you host the bot, you need to install Docker. It's available for all popular operating systems, including Windows, macOS, and Linux.
So, here are the links to the installation guides:

If you decide to host the bot on Linux, you can copy-paste the following commands to install Docker:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Test the installation:
sudo docker run hello-world

Step 4: Obtain your Telegram ID

The bost must know who is the admin to accept or reject suggestions and must be started with the ADMINS environment variable. To get your Telegram ID, you can use the userinfobot. Just start a chat with it and it will show you your ID.
Note: I can't guarantee that this bot will work forever, but you can find a similar one by searching for userinfo in the Telegram search.
You can start the bot with at least one admin ID and add others later, but also you can add multiple IDs at once while running the bot.

Step 5 (optional): Add custom templates

To learn how to create custom templates, you can read the Custom Templates section. This step is optional, you can skip it and use the built-in templates.

Step 6: Run the bot

Now, when you installed Docker, created a bot, and got your Telegram ID, you can run the bot with the following command:

docker run -e TOKEN="1234567890:ABCdefGhIjKlmnOpqrStuVwXyz1234567890" -e ADMINS="1234567890" iwatkot/affirmbot

to use it with built-in templates, or, if you prepared custom templates, you can run the bot with the following command:

docker run -e TOKEN="1234567890:ABCdefGhIjKlmnOpqrStuVwXyz1234567890" -e ADMINS="1234567890" -e CONFIG="github_username/repo_name" iwatkot/affirmbot

Friendly reminder: don't forget to replace 1234567890:ABCdefGhIjKlmnOpqrStuVwXyz1234567890 with your bot token and 1234567890 with your Telegram ID.

Custom Templates

To use custom templates, you need to create a public GitHub repository with a config.yml file, containing your templates. The repository must be public, otherwise, the bot won't be able to access it.
So, again step by step for those who are not familiar with GitHub:

Step 1: Create a GitHub account

I assume this is an obvious step, which doesn't require any additional explanation.

Step 2: Create a new repository with templates

Create a new repository which contains config.yml file with templates.

Step 3: Edit the config.yml file

You can edit the file directly on the GitHub website, just click on it and then click the pencil icon in the upper right corner. Again, I won't describe how to edit the file locally and push it to the repository.
Note: please pay attention to the file structure, it must be correct, otherwise, the bot won't be able to read it and will use the built-in templates.
So, let's take a look at the example config.yml file:

welcome: "Hello! With this bot, you can fill out the form, which will be posted to the channel, if admins accept it."
templates:
  - title: "Form for posting to channel"
    description: "This form will be posted to channel if accepted."
    toend: "Please, use the reactions so author will know that you're going to the event."
    complete: "Thank you for completing the form, the bot will notify you when it will be accepted or rejected."
    entries:
    - mode: "text"
      title: "Event title"
      incorrect: "You entered an incorrect title, please try again."
      description: "Please, enter the title for your event."
    - mode: "date"
      title: "Event Date"
      incorrect: "It was an incorrect date, please try again."
      skippable: true
      description: "Please enter the date in DD.MM.YYYY format (e.g. 31.05.2024)."
    - mode: "oneof"
      title: "Where will your event take place"
      incorrect: "Please, try again and use the buttons."
      description: "Please select the answer from one of the buttons."
      options:
        - "Outdoor"
        - "Indoor"

On the first level, there are two keys: welcome, which is a welcome message when the bot starts a conversation with a user, and templates, which is a list of templates.

Template structure

So here's a list of keys which represent the template:

Key name Required Description
title The title of the template, which will be shown to the user.
description The description of the template, which will be shown to the user.
complete The message that the user will receive after filling out the form.
toend The text that will be added to the end of the filled form.
entries A list of entries that the user must fill out.

✅ - required, must be entered in the yaml file.
❌ - optional, can be omitted in the yaml file.

Entry structure

There are several types of entries, learn more about them in the Entry Types section.
But for most of them, you can use the following keys:

Key name Required Description
mode The type of entry, must be entered exactly as in documentation.
title The title of the entry, which will be shown to the user.
description The description of the entry, which will be shown to the user.
incorrect The message that the user will receive if the entry is incorrect.
skippable A boolean value that allows the user to skip the entry.
options *️⃣ A list of options that the user can choose from. Required for oneof.

✅ - required, must be entered in the yaml file.
❌ - optional, can be omitted in the yaml file.
*️⃣ - required for specific entry types, for others is optional.

Some keys are optional for most entry types, but may be required for specific entry types. For example, the oneof entry type requires the options key, which is a list of options that the user can choose from. For other entry types, this key is optional and will add additional buttons to the message. In the next section, you can learn how to use different entry types.

Entry Types

Before we start talking about entry types, I beg you to NOT USE specific entry types (like date) if you don't need them. Let me explain to you why. Imagine that the user wants to suggest an event that will take place for example on Friday and enters something like 7 June. If you set the field to text, it would be okay, but if you set it to date, the bot will reject the answer because it doesn't understand the date since it waits for the date in popular formats like 07.06.2024. And it will tell the user that the date was incorrect again and again. So, please, be careful with the entry types you choose. And if you're not sure, just use the text entry type.

Text

mode: text
additional keys: none
This is the simplest entry type, the user must enter any text. The bot doesn't check the correctness of the text, it just accepts it. Here is an example:

- mode: "text"
  title: "Event title"
  incorrect: "You entered an incorrect title, please try again."
  description: "Please, enter the title for your event."

Number

mode: number
additional keys: none
This entry type is used to enter the number. The bot checks the correctness of the number. Here is an example:

- mode: "number"
  title: "Number of participants"
  incorrect: "You entered an incorrect number, please try again."
  description: "Please enter the number of participants."

Date

mode: date
additional keys: none
Note: don't use this entry type if you don't need it.
This entry type is used to enter the date. The bot checks the correctness of the date by several popular formats. Here is an example:

- mode: "date"
  title: "Event Date"
  incorrect: "It was an incorrect date, please try again."
  description: "Please enter the date in DD.MM.YYYY format (e.g. 31.05.2024)."

OneOf

mode: oneof
additional keys: options
This entry type is used to select one of the options. The user can choose the option by clicking on the button. All other answers will be rejected. Here is an example:

- mode: "oneof"
  title: "Where will your event take place"
  skippable: true
  incorrect: "Please, try again and use the buttons."
  description: "Please select the answer from one of the buttons."
  options:
    - "Outdoor"
    - "Indoor"

Url

mode: url
additional keys: none
This entry type is used to enter the URL. The bot checks the correctness of the URL. Here is an example:

- mode: "url"
  title: "Event URL"
  incorrect: "You entered an incorrect URL, please try again."
  description: "Please enter the URL of the event."

File

mode: file
additional keys: none
This entry type is used to upload the file. The bot doesn't check the correctness of the file, it just accepts it. Here is an example:

- mode: "file"
  title: "Data archive"
  incorrect: "You uploaded an incorrect file, please try again."
  description: "Please upload the archive with the data."

Administration

To change the bot's admin settings, click on the Administration button in the bot's menu.

Channel

After you run the bot, first of all, you need to add the bot to the channel where you want to publish the suggestions. When the bot is added to the channel, go to the bot's Administration and click on the Channel button. In this menu, you can connect the bot to the channel or disconnect it. By the way, you'll need to know your channel ID. This can be done with one of the Telegram bots, for example, GetTheirIdBot.
Note: If this bot doesn't work, you can find a similar one by searching for channel id in the Telegram search.

Team

In the Team menu, you can add or remove moderators and admins. The difference between them is that the admin can change the bot settings, and the moderator can only accept or reject suggestions. The moderators can't do anything else. Basically, moderators are ordinary users with the ability to accept or reject suggestions.

Admins

In the Admins menu, you can add or remove admins by their Telegram IDs. Just a tip: you can't remove yourself from the list of admins.

Moderators

In the Moderators menu, you can add or remove moderators by their Telegram IDs.

Templates

In the Templates menu, you can enable or disable templates. The users will see only enabled templates.

Config

In the Config menu, you can reload the configuration from the GitHub repository. This is useful if you made changes to the config.yml file and want to apply them without restarting the bot.

Get Logs

If something goes wrong, you can click on the Get Logs button to get the logs from the bot. The bot will send you an archive with all logs and tracebacks. If you want to open an issue, please attach these logs, otherwise, I won't be able to help you.

Settings menu

In the Settings menu, you can change different admin settings, like the number of approvals and rejections needed to publish or reject the suggestion, and also here you can backup and restore the settings.

Minimum approvals

This setting allows you to set the minimum number of approvals needed to publish the suggestion. For example, if you have 3 admins and set this value to 2, the suggestion will be published if at least 2 admins accept it. The default value is 1 and the maximum value is the number of admins.

Minimum rejections

This setting allows you to set the minimum number of rejections needed to reject the suggestion. For example, if you have 3 admins and set this value to 2, the suggestion will be rejected if at least 2 admins reject it. The default value is 1 and the maximum value is the number of admins.

Backup settings

After clicking on this button, the bot will send you a file with the settings. You can use it to restore the settings in case of redeploying the bot. Friendly reminder: if you won't clean the history of the chat, the file will always be available for you, so you don't need to save it on your device.

Restore settings

After clicking on this button, the bot will ask you to upload the file with the settings. After uploading the file, the bot will restore the settings from it. The file has a pretty simple JSON structure, so you can edit it manually if needed.
Here's an example of the settings file:

{
    "admins": [
        1234567890,
    ],
    "moderators": [
        1234567890,
    ],
    "channel": -1234567890,
    "active_templates": [
        0
    ],
    "inactive_templates": [],
    "min_approval": 1,
    "min_rejection": 1
}
Key name Required Description
admins A list of admin Telegram IDs.
moderators A list of moderator Telegram IDs.
channel The channel ID where the suggestions will be published.
active_templates A list of indexes of active templates.
inactive_templates A list of indexes of inactive templates.
min_approval The minimum number of approvals needed to publish the suggestion.
min_rejection The minimum number of rejections needed to reject the suggestion.

✅ - required, must be entered in the JSON file.
❌ - optional, can be omitted in the JSON file.

How to use the bot

How users can suggest content

The users have only one button Forms which opens the list of active templates. The user can choose the template and fill it out. After filling out the form, the user will receive a message that the form has been sent for review. The admins will receive a notification about the new suggestion and can accept or reject it. If the suggestion is accepted, it will be published in the channel. If it is rejected, it won't. In both cases, the user will receive a notification about the decision.

How admins can accept or reject suggestions

When the user sends a suggestion, each admin will receive a notification about the new suggestion with two buttons: Accept and Reject. By clicking on the button, the admin can accept or reject the suggestion.

Bugs and Feature Requests

If you found a bug, please first save the logs, you can learn how to do it in the Get Logs section, and then open an issue. If you have a feature request, you can also open an issue or use the Discussions tab.
Friendly reminder: this bot is free and open-source, so I can't guarantee that I will fix all bugs and implement all feature requests, but I will try to do my best. You can also contribute to the project by opening a pull request or forking the repository.

For developers

If you want to set the bot in development mode, you can add the ENV environment variable with the value DEV.
In this mode:

  • All entry checks will be disabled and always return True.
  • All errors will be raised without catching them.

If you don't want to change the core features, you can use the src/event.py file to easily add new buttons, callbacks and so on. It's designed in a very simple way, so mostly you just need to add a string for the event and implement the process() method, which will be called when the button or callback is clicked.

Wontfix

  • ❌ Adding multiple languages support. Since the main interaction of a user happens with the template, you can create a template in any language you want. But for the menus and buttons, I'm not planning to add any other languages, since it's a lot of (useless) work. But if you want to add a new language, you can fork the repository and do it yourself.

About

Completely free bot to automate the publication of user-suggested content in the Telegram channel.

Topics

Resources

License

Stars

Watchers

Forks

Languages