Я не придумал, куда сходить — и скодил своего бота, который решает эту проблему за меня

Он рассказывает мне об интересных для меня событиях, которых не найдешь на популярных сайтах-агрегаторах мероприятий.

Рождение идеи

Примерно за неделю до нового 2022 года, сидя в гостях у друга и покуривая кальян, мы сидели и думали “чоб такого придумать-замутить, чтобы было интересно”. Начали накидывать идеи, но все были так себе. Сначала приходили на ум всякие сложные идеи, типа убийцу %PopularService%, но было решено начать с чего-то попроще, например, какого-нибудь бота для Телеграм... начали обсуждать, чего не хватает конкретно нам и что могло бы быть удобно для большого числа людей.

Потом кто-то сказал: “Мы почему-то дома часто сидим, не ходим никуда. На ** (одном из многих сайтов-агрегаторов мероприятий) всякий шлак, а что-то интересного нет”. И возникла идея - а что если сделать бота в Телеграме, которому ты просто однажды поставил, о каких мероприятиях хочешь получать уведомления, и после этого про него забываешь? А он тебе рассказывает только о тех событиях, которые тебе действительно интересны. Да еще впереди и праздники новогодние - идея должна стрельнуть.

Мы быстро раскидали зоны ответственности за бота - кто собирает мероприятия, кто пишет бота, кто думает о том, как продвигать. И забили нафиг.

Реализация идеи в MVP

Прошло примерно 4 месяца. Многое за это время поменялось, но главное у меня - я уволился, переехал и имел некоторое количество свободного времени. И решил - ну, надо попробовать написать этого бота. 

О себе: тестировщик-автоматизатор, основной стек C#. Но для бота решил использовать Питон - давно хотел попробовать, а тут прям отличная возможность решить задачу на новом ЯП. Должно быть интересно. Открыл я курсики по питону в браузере, скачал IDE, начал писать. И тут я офигел.

Несмотря на весь мой опыт в тестировании, написать с нуля вот это вот всё оказалось не самой простой задачей. Нужно продумать всё - архитектуру, как будут выглядеть модели данных, как это все взаимодействовать будет, где это все будет крутиться и так далее. А тут еще и новый ЯП со своими особенностями… В общем - было весело.

Но спустя какое-то время стало получаться что-то работающее. Можно было создать ивент и посмотреть ивенты в базе. И все это в Телеграм. И вот когда я начал видеть настолько новые результаты своих трудов - начал постоянно ловить всё новые и новые дозы дофамина. Сталкивался с новыми трудностями, консультировался, писал дальше. Гуляя - в голову приходила новая идея, что можно докрутить или реализовать. Приходил домой и дописывал. Бывало даже, что ложился спать, но в голове крутилась мысль “как же это реализовать”. Через 10 минут осеняло - я вставал, открывал ноут и писал, писал, писал…

Так прошел примерно месяц. У меня было что-то работающее, где можно было создать ивент, посмотреть текущие с фильтром по категориям и городам, создать подписку на те категории, о которых хочу получать уведомления. Я смог это все задеплоить в Heroku (а потом и в Digital Ocean), прикрутил бесплатную MongoDB к этому всему и решил - пора выкатывать в люди, в бой.

Тестировать начал на городе Белград, куда я и переехал. Так как сюда сейчас приехало достаточно много русских - есть потенциальные пользователи бота. Я наполнил базу ивентами и начал рекламировать бота во всех местных чатах и собирать фидбэк. Если коротко - идея людям зашла, народ стал достаточно хорошо в него заходить и подписываться на категории. Даже стали размещать анонсы своих мероприятий.

Из MVP в полноценный продукт

В то же время стали появляться некоторые оплошности по взаимодействию с ботом. Пришлось на ходу перепиливать функционал, улучшать то, что есть. Для этого сделал тестового бота и тестовую базу, подключил знакомых для этого. Из первой интересной добавленной фичи на этой стадии - напоминалка о событии за день. То есть человеку падает уведомление о том, что новый ивент по его подписке появился в базе, и он сразу в боте может поставить себе уведомление за день об этом событии, в один клик.

Как это реализовано технически (мы ж на Хабре все-таки):

  • По нажатию кнопки летит колбэк с id ивента

  • Из колбэка мы берем id чата (то есть кому присылать уведомление)

  • По id ивента из базы вытягиваем дату ивента и отнимаем один день

  • Берем все эти данные и в коллекцию напоминаний в Mongo сохраняем json типа “такого-то числа в такой-то чат напомни о таком-то мероприятии”

А в соседнем процессе с ботом крутится scheduler с командой “раз в день проверяй коллекцию напоминаний”, а именно:

  • Получи все напоминания за сегодня

  • В каждом напоминании возьми id ивента, вытащи данные об ивенте, и отправь в чат из этого напоминания инфо об ивенте

В целом - ничего сложного. Но когда идея после обдумывания проходит реализацию и оно работает - передоз дофамина мне был гарантирован. До сих пор считаю ее одной из самых удобных фич в боте - просто в один клик ставить напоминалку о событии.

Вторая из удобных фич - это подписка на “такие же мероприятия”. Когда новый человек, у которого нет подписки, заходит в просмотр событий - то под каждым анонсом есть еще кнопка “Уведомлять о таких же”. Как это работает тут? В целом - почти так же, как и в напоминалке:

  • После нажатия кнопки летит колбэк с id ивента

  • Из колбэка берется id чата

  • По id ивента берем о нем данные о городе и категориях

  • Эти город и категории сохраняем для пользователя как его подписку на город и категории

Опять ничего сложного, но когда это работает - трава становится зеленее, воздух чище, самозванец внутри меня куда-то девается.

А как же мультиязычность?

Через некоторое время я задумался о том, как прикрутить второй язык в бота - английский. И тут я понял, что вся моя архитектура в боте совершенно никуда не годится. На данном этапе я хранил категории ивентов и городов прямо словами - типа “Белград”, “Тусовки”. И проблема в том, что эти названия брались из переменной окружения, подставлялись везде, где надо, а особенно использовались на отображении названий на кнопках в настройки подписки. И использовались для поиска мероприятий в базе.

“Пупупу…” - подумал я - “И что делать?”. После нескольких неуспешных попыток самостоятельно решить этот вопрос я воспользовался подсказкой “Помощь друга”. В итоге сделал так:

  • Добавил пару коллекций с городами и категориями в БД

  • В каждой коллекции завел объект под каждую локаль, в котором хранилось название на нужной локали и id (например, ‘Белград’: 1)

  • В мероприятиях и подписках стал хранить города и категории не по названиям, а по айдишникам

  • И при работе с ботом бралась локаль, которую выставил пользователь, и под эту локаль вызывались названия городов и категорий по айдишнику

Для этого пришлось на боевой базе изменить структуру данных, сделать так, чтобы новый бот работал и со старыми, и новыми данными. А всякие сообщения от бота перевелись легко с помощью встроенной библиотеки - там проблем было меньше всего.

Скажу честно - после этого релиза на следующий день залил еще два багфикса. Но сейчас все работает на двух языках!

О юзерфлоу

Я старался сделать управление ботом интуитивно понятным и очень простым. Но когда выкатил это все людям, то я понял одну сложную для меня вещь: то, что понятно для меня, другим совсем не юзерфрендли. Примерно выглядит все так:

Если вы ищите, куда пойти, вам нужно:

  1. Зайти в бота.

  2. Выбрать свой город.

  3. Подписаться на интересные для вас категории. 

  4. Как только появится подходящее мероприятие - вам придёт уведомление.

Либо вы можете получать сводку уведомлений по понедельникам на неделю вперед - это включается в настройках уведомлений.

Без использования подписки можно просто просматривать запланированные мероприятия. Выбрав город в команде /events, дальше есть несколько вариантов на выбор: просмотреть все события по категории на выбор, изучить события на сегодня-завтра в кратком изложении, получить все события на неделю вперед и полистать их постранично. Последние возможности добавил только сегодня.

Если вы организатор и хотите собрать людей, то вы:

  • Тоже заходите в бота.

  • Заполняете все поля о своём мероприятии в команде добавления ивента.

  • После модерации о нем улетают уведомления всем, событие появляется в базе.

Категории мероприятий, которые уже есть: 

  • Тусовки

  • Спорт

  • Музыка

  • Бизнес

  • Туризм

  • Развитие

  • Мастер-класс

  • Юмор

  • Игры

  • Общение

  • Дети

Сейчас бот заточен на такие города, как Москва, Санкт-Петербург, Тбилиси, Нови-Сад и Белград (естественно).

В заключение

Вот так кальянная идея превратилась в pet-проект - и этот проект продолжает развиваться и совершенствоваться. В голове уже сидят некоторые фичи, которые можно внедрить в бота для удобства пользования.

И самое главное - где же бот, где посмотреть его вживую? Вот: https://t.me/EventsList_bot 

Буду рад услышать ваши мысли по всему этому. И с технической точки зрения, и с пользовательской.