Analyze with AI

Get AI-powered insights from this Mad Devs article:

Introduction

Traditionally, Mad Devs pays for employees' lunches. The process starts with food ordering. In the morning, a responsible person chooses cafes from Namba Food, opens 2 corporate orders, and asks everyone to choose the food. Then it is necessary to control that everyone ordered food, place the corporate order no later than a given time (otherwise, lunch will come too late), and wait for the operator's call (to replace dishes that are absent in the cafe — this happens in 95% of cases). When all the food is delivered, it is necessary to notify everyone one more time.

The process seems very simple, but it consumes undeservedly much time of the employees. Therefore, we decided to create a bot.

Intern's test

People talk, creating a bot will take several evenings with beer for a qualified junior developer. However, we are not juniors yet; we are Mad Devs interns and within the scope of routine processes automatization, we got our first real task — to write a bot for ordering food from the delivery service app Namba Food.

Before, we had been working on tasks that gave us knowledge but did not create any value for the company. In addition, we did not even know how to order food for a small but very friendly team. At first, we started with the collection of information. The process turned out chaotic and therefore not very productive. The prototype of the bot we did blindly.

For further implementation, we contacted the True Developer. The position was held by Nakylai, the main backend developer of NambaFood. We discussed the plan of the project, and the puzzle folded. The first revelation happened, and we got the whole picture of the project. Nakylai created endpoints for us for opening, closing, viewing, and order statistics, wrote documentation, and personally showed how everything works. We proceeded to the realization.

Our team mainly uses two messengers — Telegram и Slack. Therefore, our bot can send messages to both of them. Though it is not a significant achievement, it gives valuable knowledge as the search for a token in the diversity of API documentation and forces us to use different libraries.

We used Python-telegram-bot for Telegram. This is a small library with understandable documentation. For Slack, we have written our own functions that definitely took more time, but granted flexibility to the system that is not provided in standard Slack libraries.

Namba Food Bot for Slack.

CRON is one more important notion when creating the bot for food ordering. It allows you to run functions at the necessary time and not be distracted from work. CRON can invoke your functions outside of the program or can be implemented right into the code. We were working in parallel: one intern was writing an external CRON and the other one — a small and accurate internal one. By running an external CRON, you face external code and unnecessary complications in the program. An internal CRON may confuse you if you are not sure of your code. Unfortunately, there is no ideal decision. We chose the Schedule library as the result.

At this stage, we have a bot that can send specific messages at a specific time: it can ask people to order food or to complete the ordering process since the order is closing. It can refer to endpoints: open, close, and view the order. Looking at the bot, we understood that it has several functions and correctly performs all of them. Yet, we did not know how to link them into one program that will solve the real problem.

Everything that we wrote earlier is called functional programming. But now the dilemma occurred since we ordered from two cafes. Should we invoke functions twice? This is not the approach of a programmer. Thanks to the mentor's advice, we paid attention to object-oriented programming. One object is created to order food from the 1st cafe, and the other object is created for the 2nd cafe. It sounds very simple, but actually, while we were writing the bot, a lot of new requirements were demanded. Features are changing; everything is broken. Now the fatal issue with the token happened!

We decided that it is perfectly fine to use a real token right in the code. Fast and convenient. It seems like there are only pluses of using a token in the code. It is actually, but only until the moment you have to send a project to the remote repository for the joint development process. So, the token got into the repository along with the code. We were laughed at and shouted at. I cannot say that we got a serious punishment, but this was the first nervous case during our internship in Mad Devs. The best lesson we learned in this situation is the creation of environment variables.

When we first faced the notion of an environment variable, we identified that it is a dictionary. We created a variable, equated it to the environment variable, but instead of the variable itself, we put its value. There is a key and its value. Is there something wrong?

The wrong thing is the destruction of the essence of environment variables. They are created to hide values, but we displayed them. The right option looks the following way:

  • The document with the title and value of the environment variable that will be activated further should be added to .gitignore and kept by you personally.

Namba Food Bot Schedule Code for Slack.
  • The code keeps only variable titles and the references to environment variables. The document is activated by you on your personal computer.

We were done with the project, so it was ready to work. Yet, at this stage, one more technical issue appeared. To run the script, we had to put the project into a Docker container and put it on the server. No sooner said than done.

When you work with scripts without the databases and other joys of the backend, everything is simple and carefree. We created requirements documented that are connected to Docker and allow it to download all necessary things. What is more, we specify the base image and commend docker to rerun automatically if it fails.

The first time of launch! Everything was checked for a lot of times, and the results were successful. The bot is opening the order… But one cafe appeared from nowhere, not from our list! This happened due to the differences between cafe indexes at the staging and at production. The mistake helped us to understand the importance of data rechecks for a “real” server.

The next day is Saturday. It is a day when we usually have a rest and do not go to the office; the bot should relax as well. However, he opened an order as if he were a very diligent worker. What is worse is that the cafes on the list were the same as the day before, while two cafes should be opened from the list randomly. We concluded two things from the situation. The first thing we should do is to write the script for time updates in Docker. The second one is that random choice is not always random. Therefore, it is better to use a "for" cycle and to clearly set a sequence of cafes.

Screenshot from Namba Food website.

Here is one more mistake. Since we order different bread from different cafes (flat cakes or boorsoks), we decided not to place “if” clauses into the code and write the information about the bread into the comments for operators. The comments were similar to this: "If the order is from 'Diyar' cafe, then order 2 kilos of boorsoks; if the order is from 'Taste of the East,' then order 5 flat cakes, etc." We described all 12 cafe options in comments… As a result, we got very angry Namba Food operators and a blow-up from mentors. This experience taught us a new lesson:

It is necessary to care about the end users of the product more than about the accuracy of the code. Users in no case should suffer from your unwillingness to write bad code and your inability to avoid it.

A long time passed before we could run the bot. Now, it fully works and orders food for everyone in the office. Unfortunately, the bot can not entirely replace people in food ordering. Can not do this yet, but will definitely do so in the future.

Namba Food Bot Notification for Slack.

Now we have plenty of feedback from users and plans for improvement:

  • Check the status of the order and automatic delivery information.
  • Entrust the choice of cafe to the staff through voting.
  • Automatic order of bread.
  • Automatic replacement of the dish if the dish is not ordered in the cafe.
  • And some more wishes like "…considering the current weather, weekday, and moon phase, determine the employee's mood and order him food according to it without the participation of the employee himself…" (I hope that it will be implemented by our future interns)
Namba Food Bot Notification for Telegram.

Lessons learned

  • You should learn to use environment variables from the very beginning; otherwise — FAIL!
  • You must check the time inside the Docker container.
  • Random choice between very few options often gives out a similar or identical set and therefore seems not to work.
  • Data on the "real" production server may and likely will differ from the data on the test server.
  • Code may not be accurate, but it has to work as expected. If you doubt it, it is better not to release.
  • In the production environment, you can run only well-tested features. All the routine performance checks have to be conducted in the test environment, without disturbing future users.
  • It is better to collect all the feedback for the product in one document instead of listening to the users (otherwise, it is easy to forget something).

The main conclusion:

The product that we create, has to solve the problem. We write code to improve the life, solve real problems instead of creating new ones.

Namba Food Bot Notification for Slack.
Custom Software and Mobile App Development.

Latest articles here

Functional vs Non-Functional Requirements in Software Development.

Functional vs Non-Functional Requirements in Software Development

Having an idea for a software product is only the beginning of the long journey of realizing the product and bringing it to market. To ensure a...

Lessons Learned from a Project Where the Client Had Predefined Requirements and a Limited Budget.

Lessons Learned from a Project with a Fixed Price Contract

Predefined product requirements and a limited budget is not as good as it might seem. We have recently completed our partnership with a SaaS company...

Cross-Functional Collaboration: What Is This and How It Works in IT.

Cross-Functional Collaboration in 2026: What Is This and How It Works in IT

Imagine a company where all departments work as a single organism. Everyone speaks the same language, uses terminology and is familiar with the...

Go to blog