Проект: s10ns_bot — Telegram-бот для учета платных подписок  Публичный пост
9 октября 2020     1628   
s10ns_bot — Telegram-бот для учета платных подписок

В наше время крайне популярна подписочная модель монетизации, и у активного пользователя интернета обычно подключено сразу несколько подписок. Сервисы стриминга музыки и видео, магазины видеоигр, приложения, Сбер, Mail.Ru и Вастрик — все хотят получать деньги с потребителя каждый месяц. Я тоже регулярно оплачиваю ряд сервисов и приложений, и мне всегда хотелось как-то это контролировать — считать общую сумму за месяц, переводить суммы в рубли, получать уведомления о приближающейся дате платежа, желательно с доступом к данным со всех своих устройств. Существует много мобильных приложений для учета подписок, но мне не хотелось устанавливать еще одно приложение ради такой несложной функциональности. Приложения показывают рекламу, пытаются собирать информацию о пользователях, постоянно обновляются и расходуют заряд батареи; отображение нескольких строчек текста того не стоит. В принципе, можно было бы вести список подписок в Excel-таблице и синхронизировать ее через Dropbox, но в таком варианте не получилось бы использовать актуальные курсы валют и отправлять уведомления.

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

Для такой цели проект подошел хорошо, так как был не очень масштабным, но и не совсем игрушечным. Он стал для меня песочницей, в которой я пробовал различные концепции и библиотеки из экосистемы Scala и несколько раз переписывал части кода, когда узнавал что-то новое. Это стало причиной долгой разработки, первые коммиты были сделаны в августе 2019-го года, и только сейчас бот приобрел некоторые законченные очертания первой версии. Получившийся продукт мне очень нравится, с удовольствием им пользуюсь. Надеюсь, что и другим он окажется полезен, особенно сейчас, когда за время самоизоляции и удаленки количество подключенных подписок у многих сильно увеличилось.

Как пользоваться

Функциональность аналогична нескольким приложениям для учета подписок, которые я пробовал. Список моих подписок выглядит так:

Список подписок
Список подписок

В списке отображается, сколько тратится на каждую подписку за неделю/месяц/год, а также общая сумма за период. Для удобства цены переводятся в дефолтную валюту — не забудьте выбрать ее в настройках (кнопка Settings или команда /settings). Курсы валют обновляются раз в сутки. В квадратных скобках указано, сколько времени осталось до следующего платежа.

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

Страница подписки
Страница подписки

Уведомления включаются отдельно для каждой подписки. Они стали главной проблемой при разработке бота — изначально хотелось сделать гибкую настройку оповещений, отправку сообщений за произвольное количество дней или часов, как в календарях. Но API для Telegram-ботов не позволяет узнать часовой пояс пользователя, а без этого не получится вычислить точное время отправки сообщения. Мне не удалось придумать, как реализовать простой и удобный выбор временной зоны в Telegram-боте, поэтому уведомления отправляются за сутки до даты платежа по времени UTC. Так один пользователь получит сообщение за 23 часа, а другой за час до платежа, это кривое решение, но ничего лучше пока нет, а мне уведомлений с такой точностью хватает.

Создание и редактирование подписок производится в диалоговом режиме, а если вы застряли или не понимаете, что происходит, всегда можно вызвать команду /reset или /start, чтобы выйти из диалога.

Бот полностью бесплатный, монетизация не планируется, за потенциальным исключением в виде ссылки для пожертвований.

Технологический стек

Главной целью разработки было попробовать современное функциональное программирование на Scala, IO-монады и концепцию Tagless Final. Это определило стек, бот написан с использованием библиотеки для ФП — Cats Effect, для взаимодействия с базой данных используется doobie. Разработка была интересной, об одном из решений написал отдельный пост в своем блоге: для данных в кнопках инлайн-клавиатур бота используется формат CSV с мапингом в алгебраические типы. Деплоится бот в виде systemd-сервиса с запуском jar-файла на VPS.

Для взаимодействия с Telegram Bot API используется библиотека Telegramium. Это функциональная библиотека на Scala, которую я помогаю разрабатывать, пользователи и контрибуторы приветствуются.

Заключение и ссылки

В итоге бот помог мне сделать вывод, что на подписки уходит не так много денег, и пока что можно на них не экономить. Если не включать в список оплату съемной квартиры, конечно.

На этом все, замечания и пожелания пишите в комментарии или мне в Telegram johnspade. Исходный код бота можно найти на Github.

Еще раз ссылка на добавление бота в Telegram: s10ns_bot

Связанные посты
44 комментария 👇

Идеально
Идеально

  Развернуть 1 комментарий
Вастрик, Блогер, питонист, мизантроп 12 октября 2020

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

  Развернуть 1 комментарий

@vas3k, теперь забить еще проще, надо просто потерять чат с ботом :)

  Развернуть 1 комментарий

Тема! А часовой пояс у юзера можно спрашивать. Пусть город вбивает, дальше через geocoding api Яндекса нормализовать его и определять пояс.

  Развернуть 1 комментарий

@gEQBnAMlwJb3TUUK, можно и не так сложно, просто спросить пояс и всё =]

  Развернуть 1 комментарий

@V_exeR, ну это не так юзер-френдли. Может, человек переехал и не особо помнит, сколько у него там часов от UTC и вот это всё. Просто написал «Питер» или «Нюрнберг» и ок.

  Развернуть 1 комментарий

@gEQBnAMlwJb3TUUK, тут проблема в том, что Питеров в мире несколько десятков, все равно придется заставлять пользователя делать выбор из большого списка

  Развернуть 1 комментарий

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

  Развернуть 1 комментарий

Как вариант - старое изящное решение со списком из 24 зон (UTC+3 Moscow, SPb,.. )

  Развернуть 1 комментарий
Alexander Kovalev, программист, Maker 12 октября 2020

Удобно, хорошо, спасибо за бота)
Создал платежи с начальной датой на пару лет назад, чтобы видеть, сколько было уплачено. Далее редактирую amount, т.к. с этого месяца изменяется цена. Цена изменилась и пересчиталась для всего предыдущего периода. Было бы здорово иметь возможность отключать пересчет для предыдущего периода при изменении цены.

  Развернуть 1 комментарий

@Ray, думал над этим, но пока не знаю, как сделать правильно и удобно. Нужно будет сделать возможность изменения суммы в прошлом, отображение и редактирование истории цен, получается сложно.

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

  Развернуть 1 комментарий

@Ray, та же история со Scaleway, до августа платил по 4 евро, теперь по 6

  Развернуть 1 комментарий
Nick Chursin, Все подряд 14 октября 2020

Оч круто :)

Клавиатура с датам - вообще огонь

  Развернуть 1 комментарий

Бот крутой, буду использовать, спасибо.

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

  Развернуть 1 комментарий

@graynk, спасибо за фидбэк, выбор года добавлю

  Развернуть 1 комментарий

Добавил выбор года и месяца, нужно нажать на соответствующие кнопки календаря

  Развернуть 1 комментарий

@johnspade, круть!

  Развернуть 1 комментарий
Stanislav Shubin, Senior Python Raspizdyay 12 ноября 2020

Классный бот, спасибо. Нашел его в теме про ежемесячные подписки, заполнил, теперь думаю так ли мне все они нужны 😃

  Развернуть 1 комментарий

Круто, спасибо за бота

Не мог добавить туда ещё UAH?;)

  Развернуть 1 комментарий

@Programistich, UAH есть, можно ввести код руками при создании подписки или выборе дефолтной валюты.

  Развернуть 1 комментарий

@johnspade, Спасибо) интуитивно не ясно было)
А ещё я бы поправил немного кнопочки, потому что открываются когда не надо

Респект за бота!

  Развернуть 1 комментарий

@Programistich, спасибо :) Изменил приглашение на "Enter or select the currency code", чтобы было яснее.

Кнопки основных действий доступны вне диалогов всегда, чтобы было понятно, куда нажимать. Предлагаешь прятать их по умолчанию?

  Развернуть 1 комментарий

@johnspade, я про кнопки Валюты имел ввиду

  Развернуть 1 комментарий

@Programistich, ага, поправил

  Развернуть 1 комментарий

Не получится сделать чтобы пользователь мог самостоятельно через команду задать свою таймзону (по умолчанию также и оставить как есть) - как нибуть вроде /timezone UTC+6 ?

  Развернуть 1 комментарий

@nanotexnik, сдвиг от UTC может изменяться, если применяется летнее/зимнее время

  Развернуть 1 комментарий
Dmitry Kochkin, Engineering Manager 10 октября 2020

Где хранятся персональные данные?

  Развернуть 1 комментарий

@Cooch, данные хранятся в базе данных на VPS, территориально это во Франции. Из данных Telegram-пользователя сохраняется только его уникальный идентификатор и имя (first name).

  Развернуть 1 комментарий

Привет, очень круто!
Я правильно понимаю, что свою валюту не зарегистрировать?

  Развернуть 1 комментарий

@benyamin, кастомные валюты добавлять нельзя, но все распространенные должны присутствовать. А какой валюты не хватает?

  Развернуть 1 комментарий

@johnspade, шекель (NIS)

  Развернуть 1 комментарий

@benyamin, посмотрел на Википедии, официальным кодом считается ILS, шекель поддерживается с таким кодом

  Развернуть 1 комментарий

@johnspade, хммм

  Развернуть 1 комментарий

@benyamin, код надо ввести руками, в клавиатуре только 9 популярных валют

  Развернуть 1 комментарий

@johnspade, аааа, понял, спасибо!

  Развернуть 1 комментарий

Клево. Монетизировать будете?

  Развернуть 1 комментарий

@xwildarchitect, нет, собираюсь только добавить ссылку для пожертвований

  Развернуть 1 комментарий

@johnspade, и ежемесячную подписку надо ввести :)

  Развернуть 1 комментарий

@johnspade, подумайте может быть над тем чтобы добавить парсирование CSV-выписок транзакций из банка и поиск в них рекуррентных платежей автоматически.

выгружаешь CSV в бота или в сайт, опционально указываешь колонки "цены", "даты" и "назначения платежа", бот тебе выдает список подписок (алгоритм небольшой поиска совпадений). за это можно брать деньги, например 3 первых показываются, остальные открываются за доллар.

стоит пошерстить только в каком формате какие банки дают выписку и дают ли они вообще CSV.

  Развернуть 1 комментарий

@xwildarchitect, это может быть интересная фича для продвинутых пользователей, возникнет только вопрос, стоит ли передавать полный список своих транзакций какому-то Telegram-боту.

  Развернуть 1 комментарий

@johnspade, просто напишите черным по белому в лоб что данные по транзакциям не хранятся на вашем сервере.

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

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

  Развернуть 1 комментарий

А можно добавить BYN (беларусскую валюту)?
P.S. бот крутой!

  Развернуть 1 комментарий

@Hamanovich, она есть, надо только ввести код руками.

После нескольких комментариев здесь с просьбами добавить валюты изменил приглашение на "Enter or select the currency code" и добавил в справку (вызывается командами /start и /help) предложение "Enter a currency code manually if it's not on the list.", но, похоже, пользователям все равно неочевидно, что код валюты можно ввести вручную :(

  Развернуть 1 комментарий

Так вот что народу нужно, бот для отслежиавния подписок, а я дурак думал сообществу пользу принесу, уведомения из Bitbucket в Telegram сделаю, дурак :D

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб