一键导入
telegram-bot-patterns
Паттерны Telegram-ботов на aiogram 3: FSM, middleware, rate limiting, SQLite WAL. Готовые сниппеты для быстрого старта.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Паттерны Telegram-ботов на aiogram 3: FSM, middleware, rate limiting, SQLite WAL. Готовые сниппеты для быстрого старта.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
End-to-end content creation from idea to monetization.
Self-healing and self-learning loops for AI agents. Auto-recover from errors, remember what works.
Automatic memory preservation hooks for Hermes sessions.
Полный цикл публикации open-source проекта на GitHub — от инициализации до релиза v1.0.0. Включает создание логотипа, проверку валидности SVG, шаблон README, MIT лицензию, pre-commit hooks, тесты, версионирование x.5, и публикацию релиза.
Configure Hermes Agent gateway platforms in DPI-restricted or censored networks — Telegram, Discord, and AI providers behind DPI/packet-inspection filters.
Patterns for deploying and running CEX trading bots (freqtrade, custom) in DPI-restricted environments — proxy configuration, exchange API access, WebSocket vs REST, and bot lifecycle.
| name | telegram-bot-patterns |
| description | Паттерны Telegram-ботов на aiogram 3: FSM, middleware, rate limiting, SQLite WAL. Готовые сниппеты для быстрого старта. |
| tags | ["telegram","bot","aiogram","python","patterns","russia"] |
Активировать: когда нужно создать или улучшить Telegram-бота на Python.
Цель: Не изобретать велосипед. Готовые паттерны, которые работают.
80% Telegram-ботов ломаются на одних и тех же вещах: FSM без таймаутов, SQLite без WAL, rate limiting без логики. Эти паттерны решают типовые проблемы.
import sqlite3
def get_db():
conn = sqlite3.connect("bot.db")
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("PRAGMA synchronous=NORMAL")
conn.execute("PRAGMA foreign_keys=ON")
conn.execute("PRAGMA busy_timeout=10000")
return conn
Почему WAL:
from aiogram import Router, F
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Message
import asyncio
class Form(StatesGroup):
name = State()
email = State()
router = Router()
@router.message(F.text == "/start")
async def start(message: Message, state: FSMContext):
await state.set_state(Form.name)
await message.answer("Как тебя зовут?")
@router.message(Form.name)
async def name(message: Message, state: FSMContext):
await state.update_data(name=message.text)
await state.set_state(Form.email)
await message.answer("Email?")
@router.message(Form.email)
async def email(message: Message, state: FSMContext):
data = await state.get_data()
await state.clear()
await message.answer(f"Готово: {data['name']}, {message.text}")
# Таймаут FSM (в middleware или в хэндлере)
async def fsm_timeout(state: FSMContext, timeout: int = 300):
await asyncio.sleep(timeout)
current_state = await state.get_state()
if current_state is not None:
await state.clear()
# Отправь сообщение пользователю
import time
from collections import defaultdict
class RateLimiter:
def __init__(self, limit: int = 10, window: int = 60):
self.limit = limit
self.window = window
self.calls = defaultdict(list)
def is_allowed(self, user_id: int) -> bool:
now = time.time()
self.calls[user_id] = [
t for t in self.calls[user_id]
if now - t < self.window
]
if len(self.calls[user_id]) >= self.limit:
return False
self.calls[user_id].append(now)
return True
limiter = RateLimiter(limit=10, window=60)
# В хэндлере
@router.message()
async def handler(message: Message):
if not limiter.is_allowed(message.from_user.id):
await message.answer("⚠️ Слишком много запросов. Подожди минуту.")
return
# ... основная логика
import httpx
# Локальный прокси
PROXY = "http://127.0.0.1:1082"
async def make_request(url: str):
async with httpx.AsyncClient(proxy=PROXY) as client:
response = await client.get(url)
return response.json()
# curl
curl -x http://127.0.0.1:1082 https://api.example.com
# npm/node
export HTTP_PROXY=http://127.0.0.1:1082
npm install
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
scheduler = AsyncIOScheduler()
@scheduler.scheduled_job(CronTrigger(hour=9, minute=0))
async def daily_post():
# Ежедневный пост в 9:00
await bot.send_message(channel_id, "Доброе утро!")
scheduler.start()
OWNER_ID = 405065016 # твой Telegram ID
def owner_only(func):
async def wrapper(message: Message, *args, **kwargs):
if message.from_user.id != OWNER_ID:
await message.answer("⛔ Нет доступа")
return
return await func(message, *args, **kwargs)
return wrapper
@router.message(F.text == "/admin")
@owner_only
async def admin(message: Message):
await message.answer("Панель администратора")
from PIL import Image, ImageDraw, ImageFont
def create_report(data: dict) -> str:
img = Image.new("RGB", (800, 600), "#1a1a2e")
draw = ImageDraw.Draw(img)
# Заголовок
draw.text((20, 20), data["title"], fill="white")
# Данные
y = 60
for key, value in data.items():
draw.text((20, y), f"{key}: {value}", fill="#00ff41")
y += 30
path = "/tmp/report.png"
img.save(path)
return path
.env