/MoneySplittingBot

Telegram bot for easier management money in groups of people.

Primary LanguageJava

MoneySplittingBot

Telegram bot for easier management expenses in groups of people.

Technologies stack:

  • Application: We used Spring Boot framework to create a telegram Bot using this library
  • Database: MongoDB Atlas. We used Spring Boot Data Mongodb to connect to the database and creating collections with documents.

Database

For the purpose of our project we chose MongoDB, mainly because of its flexibility of data model.
In order to gain the availability of the database between contributors we decided to create MongoDB Atlas Cluster which is running in AWS / Frankfurt (eu-central-1)

Setup

In order to connect your MongoDB Atlas Cluster fill the following propetries with:

spring.data.mongodb.username: <your_username>

And add the following line to the envorinment variables of your project:

spring.data.mongodb.password: <your_password>

If you are not fimiliar with MongoDB Atlas please checkout the tutorail here

Structure

We design a database structure with following collections:

  • Person
    {
      "_id": {
          "$oid": <personTelegramId>
      },
      "fullName": <fullName>,
      "chatId": {
          "$numberLong": <telegramChatId>
      },
      "groupChatsStates": {
          <groupChatId>: <state>,
          <groupChatId>: <state>
      },
      "botChatState": <state>
    }
  • Group - represents a group of telegram users
    {
      "_id": {
          "$oid": <telegramChatId>
      },
      "groupTitle": <titleOfTheGroup>,
      "people": [<arrayOfPersons>]
    }
  • Purchases - when you buy something for the some group of people and you want to split the bill between them
    {
       "_id":{"$numberLong": <purchaseId>},
       "groupChatId":{"$numberLong":"-1001313819728"},
       "buyer": <buyerUsername>,
       "date":{"$date":{"$numberLong": <dateInMiliseconds>}},
       "title": <title>,
       "amount":{"$numberDouble": <amountOfPurchase>},
       "description": <description>,
       "recipients": <arrayOfRecipientsUsername>
    }
  • Payment - when a user made a payment to somebody, user should register it in telegram group
    {
       "_id":{"$numberLong": <paymentId>},
       "groupChatId":{"$numberLong": <groupChatId>},
       "date":{"$date":{"$numberLong": <dateInMiliseconds> }},
       "payer": <payerUsername>,
       "amount":{"$numberDouble": <amountOfPayment>},
       "recipient": <recipientUsername>,
       "isConfirmed": <false | true>
    }
  • Sequence_id - Spring boot mongo data does not provide utility for making ids auto-generated (incremented). So we created our own collection and service for handling records id.
    {
      "_id": {
          "$oid": <autoGeneratedId>
      },
      "seq": {
          "$numberInt": <lastUsedId>
      }
    }

Database models are in model.db

Features:

  1. Creating group of Telegram people.
  2. Adding purchase with information about product, buyer, person who that purchase is made for and total amount; current balances are updated after adding the new purchase.
  3. Adding new payment with update of current balances when some user paid to another user.
  4. Displaying the information about current balances of the user, i.e. displaying the list of all users belonging to a grup with total amount of debt, where positive numbers mean that someone owes that user and negative numbers mean that the user owes someone.
  5. Displaying performed payments of the user.

Project guide

Repositories

Repositories allow us to hide the data store specific implementation details and enable you to implement business code on a higher abstraction level. In our project we used Spring Boot Starter Data MongoDB to implement below mentioned repositories.

Services

Services are responsible for receiving and updating current information in the database. They are used in ability handlers handling user’s requests.

  • GroupService is responsible for handling requests related to group chats. It can add a new user to the group, check if the user belongs to a certain group, add a new group, update group or find group by its ID.
  • PersonService is responsible for handling requests related to users. It can add new users to the database, update user states or get its states.
  • PaymentService is responsible for handling requests related to user’s payments. It can find payments of a certain user, confirmed and unconfirmed payments of certain recipient or payer, confirmed or unconfirmed payments of a group or find a payment by ID.
  • PurchaseService is responsible for handling requests related to purchases. It can add new purchases or remove them from the database, return all purchases of a certain group, return purchases of a certain buyer or receiver and find a purchase by ID.
  • BalanceService is responsible for getting balance states of a certain user, i.e. how much this user owes others or how much others owe him/her (this difference is shown by the sing before amount: positive amounts mean that others owe to the user and negative numbers mean that the user owes them).

Handlers

Handlers respond to various user's actions and events. We use them directly in MoneySplittingBot class.

There are two situations when bot gets in contact with users.

  1. When user directly asks bot to do something - Ability handlers

    User types one of these commands in Telegram chat:

    Then bot notices them and appropriately responds to the user asking for more information or displaying handy buttons.

    Every one of these handlers implements CommandHandler interface. The most important methods from this interface are:

           List<BotApiMethod<?>> primaryAction(Update update);
           List<BotApiMethod<?>> secondaryAction(Update update);

    The primaryAction method is called as soon as user texts command starting with '/'.

    The secondaryAction method is called later, after user specifies what exactly he/she wants to get or to do or clicks a button.

    Both of these methods use the update from Telegram and return list of BotApiMethods. BotApiMethod is something that displays information to the user. We execute them in the mentioned above MoneySplittingBot.

  2. When something related to the bot happens - Reply handlers.

    The bot constantly gets a lot of updates from Telegram with different events. To separate important from unimportant ones we use conditions. To respond to the events we choose, we use handlers. There two types of these handlers:

    1. When bot responds to the events generated solely by user.
    2. When bot responds to the events generated by user interacting with bot messages.
      • user clicks a button to say that user wants to be involved in group expenses management - NewMemberInGroupHandler.

Contributors

  • Ksenia Fiodarava:
    • Development of user and group services.
    • Development of /checkbalance bot feature.
  • Nazar Kordiumov
    • Configuration of MongoDB Atlas database.
    • Incorporating Spring Boot into the project.
    • Securing project credentials.
    • Initial creation of repositories and services.
    • Development of unit tests for repositories
    • Development of /addpayment bot feature
  • Stanislav Shelemekh
    • Design of the structure of the database.
    • Design of the bot features.
    • Creation of state, balance services more specific to bot’s features.
    • Development of /addpurchase, /checkpayments bot features.
    • Development of bot’s reactions to being added to a group chat.