Как встроить генерацию картинок в Telegram-бота
Живые данные: 1 пользователей · 0 оплаченных заказов
Соберём Telegram-бота, который принимает от пользователя текст и возвращает сгенерированную картинку. Вся логика — один файл на Python: бот ходит в OpenAI-совместимый API генерации изображений и отправляет результат обратно в чат. Очереди, Celery и база данных на старте не нужны.
Выбор модели
Для генерации картинок доступны три варианта:
- **kolors** — $0.005 за изображение (1024×1024, Kuaishou Kolors). По курсу 88 ₽/$ это около 0,44 ₽ за картинку — настолько дёшево, что можно давать пользователям бесплатный лимит.
- **qwen-image** — $0.08 (≈7 ₽), высокое качество детализации и надписей на изображениях.
- **qwen-image-2512** — $0.08, 1024×1024, новое поколение Qwen-Image.
Рабочая схема: разрабатываете и тестируете на kolors, а когда пайплайн отлажен, переключаетесь на qwen-image-2512 одной строкой в коде. Важный плюс API: неудачные задачи не тарифицируются, поэтому ошибки и повторы не съедают бюджет.
Шаг 1. Подготовка
1. Создайте бота через @BotFather и сохраните токен. 2. Получите API-ключ в личном кабинете сервиса и скопируйте base_url из документации. 3. Установите зависимости: `pip install aiogram openai`.
Токен и ключ лучше держать в переменных окружения, а не в коде — так проще деплоить и безопаснее при публикации репозитория.
Шаг 2. Код бота
Логика простая: хендлер ловит любое текстовое сообщение, вызывает `client.images.generate`, а затем отправляет результат через `answer_photo`. API может вернуть картинку ссылкой или в base64 — обрабатываем оба случая.
import asyncio
import base64
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart
from aiogram.types import BufferedInputFile, Message
from openai import OpenAI
TG_TOKEN = "ТОКЕН_ОТ_BOTFATHER"
client = OpenAI(
api_key="ВАШ_API_КЛЮЧ",
base_url="https://api.example.com/v1", # замените на base_url из личного кабинета
)
MODEL = "kolors" # для качества замените на "qwen-image-2512"
SIZE = "1024x1024"
dp = Dispatcher()
@dp.message(CommandStart())
async def cmd_start(msg: Message):
await msg.answer("Пришлите описание — нарисую картинку.")
@dp.message(F.text)
async def on_text(msg: Message, bot: Bot):
await bot.send_chat_action(msg.chat.id, "upload_photo")
try:
resp = client.images.generate(
model=MODEL,
prompt=msg.text[:1000],
size=SIZE,
n=1,
)
item = resp.data[0]
caption = f"Промпт: {msg.text[:900]}"
if getattr(item, "b64_json", None):
photo = BufferedInputFile(base64.b64decode(item.b64_json), "img.png")
await msg.answer_photo(photo, caption=caption)
else:
await msg.answer_photo(item.url, caption=caption)
except Exception as err:
await msg.answer(f"Не получилось: {err}. Попробуйте переформулировать запрос.")
async def main():
bot = Bot(TG_TOKEN)
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Что здесь важно:
- `send_chat_action("upload_photo")` показывает индикатор загрузки — генерация занимает несколько секунд, и без него чат выглядит «мёртвым».
- `prompt=msg.text[:1000]` — обрезаем слишком длинные запросы.
- Подпись к фото в Telegram ограничена 1024 символами, поэтому промпт в caption тоже обрезается.
- Блок `try/except` обязателен: пользователь пришлёт что угодно, а API может ответить ошибкой. Поскольку неудачные задачи не тарифицируются, повторные попытки бесплатны.
Шаг 3. Запуск и проверка
1. Сохраните файл как `bot.py`, подставьте токен и ключ. 2. Запустите: `python bot.py`. 3. В Telegram отправьте `/start`, затем описание картинки, например «рыжий кот-космонавт, цифровая живопись».
Для продакшена запускайте процесс под systemd или в Docker, чтобы бот переживал перезагрузку сервера. Long polling из примера работает без белого IP и SSL-сертификата; вебхуки можно подключить позже, когда появится нагрузка.
Улучшаем промпты дешёвой LLM
Пользователи пишут коротко: «кот в шляпе». Качество картинки заметно вырастет, если перед генерацией переписать запрос в детальный промпт. Добавьте шаг с `client.chat.completions.create` и моделью **glm-5.3-flash** — $0.15 за вход и $0.55 за выход за миллион токенов, reasoning и русский язык из коробки. Альтернатива — **qwen3.6-35b** ($0.5 / $2.2), универсальный чат Alibaba. Цена вопроса — доли копейки на один запрос, а промпт «кот в шляпе в стиле акварели, мягкий свет, детализация» даёт стабильно лучший результат.
Считаем стоимость
- kolors: 1000 генераций = $5 ≈ 440 ₽.
- qwen-image-2512: 1000 генераций = $80 ≈ 7040 ₽.
Если каждый пользователь получает 3 бесплатные картинки в день, 1000 генераций на kolors обойдутся примерно в 440 ₽ — приемлемая цена даже для небольшого сообщества. Для платных функций или бота с высокой нагрузкой берите qwen-image-2512: разница в качестве стоит около 7 ₽ за картинку.
Что добавить дальше
- Антифлуд: ограничьте число запросов в минуту на пользователя.
- Кнопки выбора модели и стиля (ReplyKeyboard или InlineKeyboard).
- Модерация промптов перед отправкой в API.
- Сохранение истории генераций в SQLite или PostgreSQL.
Каркас из этой статьи покрывает весь цикл: приём запроса, генерация, доставка картинки и обработка ошибок. Всё остальное — надстройки над ним.
Актуальные цены
| Модель | Описание | Цена |
|---|---|---|
kolors | 1024×1024 · Kuaishou Kolors | $0.005 $/шт ≈0.4₽ |
qwen-image | Qwen-Image · высокое качество | $0.08 $/шт ≈7.0₽ |
qwen-image-2512 | 1024×1024 · Qwen-Image 2512 · новое поколение | $0.08 $/шт ≈7.0₽ |
deepseek-v4-flash | быстрые рассуждения DeepSeek | $0.6 / $2.4 $/1M ток |
deepseek-v4-pro | мощные рассуждения DeepSeek | $2.6 / $7 $/1M ток |
glm-4.5-air | быстрая и дешёвая · RU | $0.25 / $1.2 $/1M ток |
glm-4.5v | зрение GLM · RU | $0.3 / $1.5 $/1M ток |
glm-5.2 | Zhipu · баланс цена/качество | $1.3 / $5.2 $/1M ток |
glm-5.3 | флагман Zhipu · reasoning | $1.8 / $7 $/1M ток |
glm-5.3-flash | флагманская flash-модель · reasoning · RU | $0.15 / $0.55 $/1M ток |
kimi-k2.7-code | код и агенты Moonshot | $1.4 / $6 $/1M ток |
qwen3-vl-32b | зрение: фото → текст | $0.25 / $1 $/1M ток |
qwen3.5-122b | флагманский MoE Alibaba | $0.6 / $2.4 $/1M ток |
qwen3.6-35b | универсальный чат Alibaba | $0.5 / $2.2 $/1M ток |
qwen3.8-27b | новейшая модель Alibaba · reasoning | $0.5 / $2.5 $/1M ток |
kimi-k3 | флагман Moonshot · агенты и длинный текст | $5 / $25 $/1M ток |
bge-m3 | эмбеддинги для RAG · ru/en/zh + 100 языков | $0.01 $/1M ток |
wan22-t2v | 480p · Wan 2.2 текст→видео · $0.40 за ролик | $0.4 $/сек ≈35.2₽ |
wan22-i2v | 480p · Wan 2.2 фото→видео · $0.40 за ролик | $0.4 $/сек ≈35.2₽ |
Курс: 1$ ≈ 88₽. Неудачные задачи не тарифицируются.