<<<<<<< Updated upstream ======= >>>>>>> Stashed changes
All work

Personal Exchange Bot

Helps Russians living abroad exchange rubles for local currency, person to person, right in Telegram. Built by a team of two people and a crew of Claude Code agents, in production since October 2026.

A simplified walkthrough: create an offer, get responses, agree on a place, exchange and rate. The bot never holds money.

Role
Co-developer, team of two
First version
1 October 2026
Status
In production
Code
Private, demo on request

Rubles abroad: no banks, only chats.

Since the 2022 sanctions, most banks and exchange offices in Europe no longer exchange rubles. Yet many Russians live abroad and need local money, like Czech koruna. Until now they swapped it in Telegram chats.

Before. Posts typed by hand, rates pushed by changers, scammers in the crowd.
With the bot. A structured offer, the market rate beside it, a checked counterparty with a rating.
  • Posts typed by hand

    Structured offers

    You post what you give and what you want; others accept or suggest their rate.

  • Rates pushed by changers

    Rates to compare

    Market rate from ExchangeRate-API, exchanger rates from BestChange, Revolut and Wise for comparison.

  • Scammers in the chat

    Checks and reputation

    Phone and account checks, spam databases, weighted ratings, a risk score and complaints.

327

pull requests merged, each through CI and review

173

screens in the bot

2

days from the spec to a working first version

3

languages: English, Ukrainian, Russian

How a deal works

Four steps, all inside one Telegram chat.

  1. Post an offer

    “I give 50,000 RUB, I want 13,500 CZK.” Market and exchanger rates show whether the price is fair.

  2. Get responses

    Other people accept your rate or suggest their own. Ratings show who you are dealing with.

  3. Choose one

    You pick a response, and a private deal chat opens between the two of you.

  4. Meet and rate

    Agree on a place on the map, exchange cash, confirm and rate each other.

The bot never holds money. It runs the deal: relays messages in the deal chat, collects confirmations and ratings.

VIP offers

Offers can be promoted for Telegram Stars.

Inline mode and city channels

Share offers in any chat, or follow a channel for your city.

Moderation

A web admin and an Android app for the moderators.

Under the hood

Python 3.14 and aiogram 3 on our own server, with every piece of state in PostgreSQL.

Stateless bot

Even dialog state lives in PostgreSQL, so the bot process itself keeps nothing in memory.

Fresh rates

A background worker refreshes rates from four sources and stores them in the database.

Safe releases

A new release first goes live on trial in production and rolls itself back if the checks fail.

Trust is the product

Exchange chats are full of scammers, and people meet strangers to swap cash. These are the safety features I built so they can trust each other.

  • Encrypted deal log

    Every deal chat is logged, and the log is encrypted.

  • Account checks

    Phone verification, Telegram account age, and lookups in the CAS and LOLS spam databases.

  • Weighted reputation

    A reputation score built from weighted ratings.

  • Risk score

    A risk score that alerts moderators.

  • Complaints

    Users can file a complaint about a deal.

Quality

4,808

automated tests in pytest. Every pull request has to pass all of them.

  • Unit tests for the core logic.
  • Integration tests against a real PostgreSQL database.
  • End-to-end tests that run the bot, the worker and the admin together.
  • Property-based tests with Hypothesis, for inputs nobody thought of.

4 of 4 checks passed

GitHub Actions, on every pull request

  1. ruffLint
  2. mypyType checks
  3. pytest4,808 tests
  4. gitleaksSecret scan

I set up the test infrastructure underneath: database fixtures, a test bench for the bot and the end-to-end tests.

My role

The idea and the original spec came from my teammate. We write the issues, make the decisions and check the results; Claude Code agents write the code and the tests. 153 of the 365 commits and 103 of the 327 merged pull requests are mine.

What I built

  • Version one in two days. From the spec, on 30 September and 1 October: project skeleton, database, bot, offer feed, responses, deals, ratings, notifications, moderation, the web admin with two-factor login, Docker and tests.
  • Interface and design. Admin redesign, mobile version, System and Stats sections, ban management, and the Android admin app.
  • Trust and safety. Encrypted deal log, account checks, weighted reputation, risk score, complaints.
  • Rates and languages. Rate sources, reading amounts like “1000 euro” or “€1000” from text, Ukrainian and the language packs.

How we work with agents

  • One issue, one agent. A session manager watches the repo and starts a headless Claude Code agent for each GitHub issue, in its own git worktree and a fresh session.
  • Labels set the power. Issue labels pick the model, from model:haiku to model:opus, and the effort, from effort:low to effort:max. Without labels the agent runs on Opus at xhigh effort.
  • Confirm before coding. The agent posts how it understood the issue, with sample screens where relevant, and only then starts coding.
  • Plain-language handoffs. Agents hand off to the next session and talk through issue comments a person can read.
  • Tooling I built for them. Environment checks, a map of all 173 screens and automatic handoff between sessions.

Want a walkthrough?

The repository is private, so I’m happy to show the code, the tests and the admin panel on a call.