В Узбекистане доллар — это не просто иностранная валюта, а часть повседневной реальности.
Аренда квартиры всегда считается в долларах. На базаре цены на мясо и технику продавцы указывают в долларах, особенно в периоды нестабильности курса сума.

Для многих семей вопрос «по какому курсу сегодня менять» — это не абстрактная финансовая теория, а вполне бытовая необходимость: от оплаты жилья и машины до того, чтобы не потерять на обмене несколько сотен тысяч сумов.
И вот сидишь ты, молодая мама, с ребёнком на руках: одной рукой качаешь коляску, другой — листаешь сайты банков и Республиканскую валютную биржу, пытаясь поймать выгодный момент. Обновляешь страницы по десять раз в день, нервничаешь из-за разницы в 50–100 сумов на долларе — а это реальные деньги на памперсы или молочку.
В какой-то момент я просто устала от этого хаоса и подумала: так жить нельзя. Надо автоматизировать.
Как меняется курс доллара каждый рабочий день
Если сильно упростить, весь процесс выглядит примерно так (в рабочие дни, без праздников):
Утро (~08:00–10:00) Начинаются торги на УзРВБ (Узбекская республиканская валютная биржа). Банки и крупные компании покупают/продают доллары в режиме реального времени. Курс формируется рыночно — по принципу спроса и предложения. Появляется «курс открытия» и дальше он колеблется в течение сессии.
В течение дня (торги до ~15:00–16:00) Происходят все сделки. В конце дня биржа рассчитывает средневзвешенный курс по всем заключённым сделкам с долларом (USD/UZS).
Вечер (обычно ~16:00–17:00)Центральный банк публикует официальный курс на следующий рабочий день. Он берётся именно как средневзвешенный курс предыдущих торгов на УзРВБ. Этот курс — официальный ориентир: для бухгалтерии, налогов, таможни, статистики и т.д. Сам ЦБ по нему не продаёт валюту населению.
Коммерческие банки и обменники Смотрят на вчерашний официальный курс ЦБ (как минимальную базу) и на текущие рыночные реалии. Выставляют свои курсы покупки и продажи. Разница (спред) — их заработок. В течение дня банки могут менять курсы несколько раз: если на бирже доллар укрепился/ослаб, если конкуренты поменяли, если большой клиент пришёл — курс корректируется. Иногда изменения бывают по 3–5 раз за день, особенно в волатильные периоды.
Итог для обычного человека:
Хочешь поймать самый выгодный курс на сегодня — мониторь именно курсы банков в реальном времени, а не только официальный ЦБ.
Официальный курс ЦБ — это «вчерашний» средний по бирже, он обновляется раз в день.
Реальные деньги на обмене — в спреде банков и их оперативных изменениях.
Поэтому и нужен бот: чтобы не сидеть вручную и не пропустить момент, когда кто-то из банков вдруг поднял курс покупки на 50–100 сумов выше остальных.
Идея бота: уведомления, когда курс реально изменился
Всё это привело к простой, но очень нужной мне мысли: хочу получать уведомления в Telegram только тогда, когда курс в обменниках банков действительно поменялся — причём не официальный курс ЦБ (он обновляется раз в день в 16:00), а именно реальные курсы покупки/продажи в пунктах обмена конкретных банков.
Поэтому бот должен:
Периодически (например, каждые 10–30 минут в рабочие часы) парсить страницы с курсами валют у популярных банков (NBU, Kapitalbank, Anorbank, Hamkorbank, Octobank, Ipak Yuli, Universal bank и ещё несколько, где курсы часто бывают самыми выгодными).
Сравнивать новые значения с предыдущими (хранить в базе).
Если курс покупки или продажи по доллару (а можно и по евро/рублю) изменился хотя бы на 10–20 сумов — присылать мне уведомление

Техническая реализация: C# и микросервисы с самого начала
Когда пришло время переходить от идей к коду, выбор стека был очевиден и однозначен: C# на .NET 8. Других вариантов я даже не рассматривала — это мой основной рабочий инструмент, в нём я чувствую себя как рыба в воде. Опыт с .NET позволил сразу сосредоточиться на логике проекта, а не на изучении нового языка или фреймворка.
Микросервисная архитектура тоже была запланирована с первого дня — не как модный хайп, а потому что она идеально ложилась на задачи проекта:
чёткое разделение ответственности (парсинг, бизнес-логика уведомлений, доставка в Telegram),
независимая разработка и отладка каждого компонента,
удобство масштабирования в будущем (если вдруг добавятся новые банки, валюты или пользователи),
простота тестирования и мониторинга отдельных частей.
В итоге получилось три микросервиса:
Parser Service Работает по расписанию (BackgroundService + Timer), парсит сайты банков с помощью AngleSharp, сравнивает новые курсы с предыдущими (хранятся в PostgreSQL), и при любом изменении отправляет событие «CurrencyRateUpdated» в Kafka.
Notification Logic Service Консьюмер Kafka-топика с обновлениями. Проверяет подписки пользователей (таблица subscriptions: user_id, bank_id, currency, min_change_threshold), формирует персонализированные сообщения и кидает их в следующий топик — «UserNotifications».
Telegram Delivery Service Финальный консьюмер: берёт готовые сообщения, находит chat_id пользователя и отправляет их через Telegram.Bot библиотеку. Есть retry, rate-limiting и базовое форматирование (эмодзи, bold, inline-кнопки).
Кода немного — весь проект уложился примерно в 1500–2000 строк (без ��онфигов и тестов). Любой разработчик на .NET мог бы собрать подобное за неделю плотной работы.
Но я писала его по ночам, в декрете, выкраивая по 30–90 минут, когда ребёнок спал. Поэтому вместо недели проект растянулся на три месяца. Зато за это время я:
пережила несколько «переездов» структуры страниц у банков,
добавила надёжную обработку ошибок и логи,
настроила Kafka + Victorya Logs для логов,
протестировала всё на реальных скачках курсов.
В итоге получился крепкий, масштабируемый и очень удобный для меня инструмент — именно такой, каким я его и задумывала с самого начала.
Заключение
Телеграм бот уже спас мне кучу нервов и времени: теперь я не сижу сутками с обновлением страниц банков, а получаю точное уведомление именно тогда, когда курс в обменнике реально изменился и стоит бежать менять.
Если вы тоже в Узбекистане, тоже следите за курсами и тоже устали от ручного мониторинга — буду очень рада, если мой опыт и код кому-то пригодятся.
Огромное спасибо всем, кто дочитал до конца! ❤️ Особенно благодарна буду за ваши отзывы, предложения и критику — пишите в комментариях, что можно улучшить, какие банки добавить, какие фичи были бы полезны (например, алерты на определённый порог, топ-курсы в одном сообщении и т.д.).
Спасибо, что вы есть, хабровчане!💙
