Skip to content
Troy Köhler

Вступление в Google Cloud Functions & Google Pub/Sub (на примере моего личного проекта)

программирование4 min read

  • личный проект – система ведения личных финансов
  • почему мне понадобились эти сервисы и почему я не решил это сделать иначе
  • как выглядит архитектура
  • примеры кода и технические трудности с которыми я столкнулся по дороге. Как я их решал
  • стабильность и поддержка - что я могу сказать спустя два месяца использования моей системы
Prototyping wireframes in Figma for a live events website (web app) for an international client. Testing it on a smartphone in a remote — work from home setup.

Мой личный проект – системы управления семейными финансами

Так получилось, что девушка, с которой мы познакомились и начали серьезные отношения, оказалась в горе кредитов. Совместно мы разработали жесткую систему финансового учета, с помощью которой мы закрыли все кредиты (более 100 000 гривен или в пересчете на текущий курс доллара – более 3500$).

Эта система помогла нам расправиться с кредитами в сравнительно короткие сроки: около 8 месяцев. Мой доход тогда еще был очень скромным – всего 500$ в месяц при том, что мы оба живем в столице.

Система довольно простая и выглядит вот так:

  • каждый раз как моей девушке приходят деньги, мы начинаем "новый период". Каждый "период" мы скидывали в общий бюджет определенную сумму, в которой уже заложены расходы на еду, квартиру, коммунальные, кредиты и т.д. Все остальное, что остается – личные расходы и каждый их тратит, как захочет.
  • Все общие расходы учитываются: каждый чек, каждая единица в чеке должны быть заведены в систему. Ну и наличные расходы, конечно же, тоже.

Периоды начинаются три раза в месяц: 5, 15 и 23 числа. В эти числа мы каждый раз скидываем одинаковые суммы в общий бюджет и на них и живем до начала следующего периода.

Я решил использовать телеграм как интерфейс для заведения чеков

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

Проблема была в том, что 5, 15 и 23 числа мне приходилось вручную "автопополнять" балансы всех нашей статей расходов и эта мелкая ручная работа раздражала. Статей расходов у нас несколько: на еду нам и коту, на бытовые штуки типа моющего, доставки, пакетов, на аренду и коммуналку, а раньше была и на кредиты. У всех них свои отдельные балансы и учет.

Почему я решил использовать serverless от Google Cloud и Google Pub/Sub?

Каждое 5, 15 и 23 число месяца звучит, как классическая cron job. Теоретически можно было бы написать скрипт на питоне и запускать его по крону, поэтому то, как сделал я – это отнюдь не самое простое решение данной проблемы.

Я просто увидел, что у этих сервисов есть free tier, который вполне удовлетворяет моим потребностям, и мне захотелось поэкспериментировать с бессерверными функциями, которые сделал Google Cloud.

До этого я уже пользовался решением Amazon Lambda и потому мне было очень любопытно, как продвигаются дела с этим продуктом у основного конкурента Amazon.

Сервисы Google мне лично выглядят более удобными, чем у Amazon, но это я так думал еще до того, как попробовал их бессерверные функции.

Как выглядит реализация моей задумки

Google Pub/Sub триггерится по крону и вкидывает в стрим сообщение (я так понял, это кафка, которую Google приспособил в качестве стриминга сообщений из одного своего продукта в другой). Google Cloud Function проект отрабатывает каждое сообщение из стрима: ловит, распаковывает и на основании данных внутри делает обновления в моей базе данных (я под это использую Notion, чтобы для моей девушки всегда был доступен удобный интерфейс и в вебе, и с мобильного приложения). После того, как необходимые обновления сделаны, функция отправляет уведомление на клиент о том сколько мы сэкономили в этом периоде и о том, что новый период открыт.

Код и технические трудности, с которыми я столкнулся в процессе реализации

В интернете довольно мало работающих и актуальных примеров кода. Как именно зашифровано сообщение в кафке я так и не нашел, поэтому методом проб и ошибок удалось установить, как с этим работать.

Вот так выглядит entrypoint для моей Google Cloud Function.

def main_function(event, context):
    """Triggered from a message on a Cloud Pub/Sub topic.
    Args:
         event (dict): Event payload.
         context (google.cloud.functions.Context): Metadata for the event.
    """
    pubsub_message = base64.b64decode(event['data']).decode("utf-8")
    pubsub_message = json.loads(pubsub_message)
    day_triggered = pubsub_message.get("day")
    print(f"day triggered is {day_triggered}")
    if not day_triggered:
         return 
    remain_categories_map = {}
    for title in categories_to_update.keys():
        res = notion.databases.query(**prepare_query_kwargs(title))
        remain_value = get_remain_from_res(res)
        remain_categories_map[title] = remain_value
    message = "скинуть в банку нужно вот такие значения {}".format(
        remain_categories_map
    )
    bot.send_message(chat_id=our_home_chat_id, text=message)
    print("message sent")

    for title, dates_dict in categories_to_update.items():
        sum_for_open = dates_dict.get(day_triggered)
        if sum_for_open:
            print("data exist. Executing auto adding money.")
            title = f"{title}_бот_открывает_период"
            notion_page = notion_page_builder(
                title,
                dates_dict.get("id"),
                0,
                sum_for_open,
                remain_flag=True,
                bullets=None,
            )
            notion.pages.create(**notion_page)
    bot.send_message(
        chat_id=our_home_chat_id, text="Деньги пополнены, новый период открыт [с заботой о вас, ваш персональный робот]"
    )

Локальное тестирование и дебаггинг Google Cloud Functions

Для локального тестирования я нашел вот такой вот проект от Google.

Я использовал его для локального тестирования, но там не совсем актуальный способ шифрования сообщений в паб/саб. Когда я задеплоил функцию в облако, то оказалось, что паб/саб шифрует сообщение иначе.

Стабильность и поддержка

Эта система работает уже 2 месяца и что я могу сказать – это был веселый эксперимент и все работает отлично.

Функционал ведет себя стабильно, не беспокоит его создателя (меня) и я сделал его абсолютно бесплатно. Надеюсь, что его стабильность не изменится и спустя какое-то время я вообще забуду, что он там есть.

У меня есть email рассылка.

Не могу сказать, что она о чем-то конкретном, поэтому подписывайтесь на свой страх и риск!

Высылаю 1 письмо в месяц.