April 24
Криптобот: от говнокода до монолита
Каждый новый этап — это новая фича, которую выбирают юзеры. Голосуют в опросах на канале, пишут комменты — а мне потом это допиливать.
Как это работает:
API CoinGecko — дергали как дегенераты:
def get_price(coin: str) -> float: resp = requests.get(f"https://api.coingecko.com/api/v3/price?ids={coin}&vs_currencies=usd") return resp.json()[coin]["usd"] # если CoinGecko сдох — бот тоже
Хранение состояний — в оперативке:
user_states = {} # {"user123": {"step": "input_amount"}}
Итог: после рестарта — все сессии в мусорку.
Валидация ввода — «ну введи цифры, долбаёб»:
@dp.message_handler() async def handle_retard(message: Message): if not message.text.isdigit(): await message.answer("Чё за хуйню ты ввёл?")
Юзеры всё равно вводили: "BTC,-100"
, "1,,,,5"
, "миллион долларов"
.
v2.0 — чуть меньше позора
🔥 Таймауты запросов — 5 секунд и нахуй:
try: async with async_timeout.timeout(5): price = await get_price("bitcoin") except asyncio.TimeoutError: await message.answer("API сдохло. Иди нахуй.")
🚨 Алерты админам — «Сервис опять лежит, пидорасы»:
if api_is_dead: await bot.send_message(ADMIN_ID, "API — мудак. Чини.")
Грабли, в которые въебались лицом
@retry(max_retries=3, delay=1) async def fetch_price(): # Три попытки перед сдачей
amount = amount.replace(",", ".").strip() if not amount.replace(".", "").isdigit(): await message.answer("Ты че, долбаёб? Это не число!")
3. Состояния после деплоя
Костыль: JSON-файл вместо Redis:
def save_states(): with open("shitty_db.json", "w") as f: json.dump(user_states, f) # крики души
Что будет (если не забьем)
🔔 Алерты — «Блядь, Bitcoin просел на 10%!»:
if price_change < -0.1: await notify_all("ПАНИКА! BTC ЛЕТИТ В ПРОПАСТЬ!")
📉 Графики — кривые линии в Paint:
plt.plot(prices) # выглядит как кардиограмма после бухла
💸 Портфель — «Сколько я проебал?»:
def calculate_losses(): return "Всё."