Главная → Блог → Телеграм-бот для проверки авто на API: как собрать за вечер
Интеграции и разработкаТелеграм-бот для проверки авто на API: как собрать за вечер

Бот для проверки авто собирается за вечер: Telegram Bot API принимает VIN или госномер, ваш бэкенд вызывает методы AvtoVinCod с одним Bearer-токеном и отправляет пользователю краткий ответ из JSON. Бесплатного бота с полными данными ГИБДД не бывает, но для разработки есть тестовые значения (VIN X7TEST00000000001, госномер Т000ТТ00), а в бою вы платите только за выполненную проверку, пополнение от 100 рублей.
Для кого этот бот и что он должен уметь
Чаще всего такие боты собирают в двух вариантах. Первый - внутренний: менеджер автосалона на площадке или оценщик выкупа стоит у машины, ему нужен ответ за десять секунд, а не вход в кабинет с ноутбука. Так же работают служба безопасности лизинга и диспетчеры автопарка. Второй - клиентский: бот как сервис для ваших пользователей, например для покупателей на вашей площадке.
Вводов обычно три: VIN, госномер и фото машины. С VIN всё понятно. Госномер удобнее, когда машину видно, а документы ещё не достали. Фото нужно, когда человек просто снял автомобиль на парковке, а номер набирать лень.
Сразу про "бесплатного бота". Данные ГИБДД платные уже у источника, поэтому полностью бесплатный бот с залогами, ограничениями и историей регистрации невозможен. У нас списание идёт за выполненную проверку, а ошибки и сбои источника бесплатны. Вашему боту это на руку: если реестр не ответил, ни вы, ни ваш пользователь ничего не потеряли.
Архитектура за 5 минут
Схема простая: Telegram, затем ваш сервер (webhook или long polling), затем API проверки авто, затем форматирование ответа и отправка в чат. Никакой магии. Для прототипа хватит long polling на любой виртуалке, для продакшена лучше webhook за обратным прокси.
Токен AvtoVinCod лежит только на сервере, в переменных окружения. Не в коде бота, не в мини-приложении, не в клиенте. Если токен утёк, вы платите за чужие запросы.
Первое, что делает бот с входящим текстом, - определяет тип ввода. VIN: 17 символов латиницы и цифр, без букв I, O и Q. Госномер РФ: буква, три цифры, две буквы и код региона, буквы из набора, который есть и на латинице, и на кириллице. Всё остальное - подсказка с примером формата. Перед проверкой уберите пробелы, переведите в верхний регистр и приведите латинские буквы в номере к кириллице, иначе "A123BC77" не совпадёт.
import re
VIN_RE = re.compile(r"^[A-HJ-NPR-Z0-9]{17}$")
PLATE_RE = re.compile(r"^[АВЕКМНОРСТУХ]\d{3}[АВЕКМНОРСТУХ]{2}\d{2,3}$")
LAT2CYR = str.maketrans("ABEKMHOPCTYX", "АВЕКМНОРСТУХ")
def detect(text):
t = text.strip().upper().replace(" ", "")
if VIN_RE.match(t):
return "vin", t
t = t.translate(LAT2CYR)
if PLATE_RE.match(t):
return "plate", t
return None, t
Шаг 1. Подключение и тест без оплаты
Регистрация в личном кабинете avtovincod.ru/lk занимает минуту, токен выдаётся сразу. Договор не нужен. Пополнение от 100 рублей банковской картой, чек приходит на email; депозит действует 90 дней.
Разрабатывать можно вообще без денег. На странице тестовый режим API описано, как это работает: подставляете VIN X7TEST00000000001 или госномер Т000ТТ00 и получаете образцы ответов бесплатно. Для отладки форматирования, кнопок и обработки ошибок этого хватает с запасом. Полный перечень методов лежит в документации API.
Шаг 2. Каркас бота и первая команда
Для первого ответа берите метод краткие данные ТС по VIN или госномеру. Он стоит 1 рубль и отдаёт марку, модель, год, мощность, тип и объём двигателя, руль, массу. Это быстрая карточка: человек сразу видит, что бот понял именно ту машину, которую он имел в виду. Если на VIN пришла "Камри", а у вас стоит Солярис, дальше платить нет смысла.
Проверим запрос руками:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://api.avtovincod.ru/brief?vin=X7TEST00000000001"
Теперь каркас на aiogram 3 с httpx:
import os, httpx
from aiogram import Bot, Dispatcher, types
from aiogram.filters import CommandStart
API = "https://api.avtovincod.ru"
HEADERS = {"Authorization": f"Bearer {os.environ['AVC_TOKEN']}"}
bot = Bot(os.environ["TG_TOKEN"])
dp = Dispatcher()
http = httpx.AsyncClient(timeout=30, headers=HEADERS)
async def call(path, **params):
r = await http.get(f"{API}/{path}", params=params)
return r.json()
@dp.message(CommandStart())
async def start(m: types.Message):
await m.answer("Пришлите VIN или госномер, например А123ВС77.")
@dp.message()
async def on_text(m: types.Message):
kind, value = detect(m.text or "")
if not kind:
return await m.answer("Не распознал. Нужен VIN из 17 символов или госномер РФ.")
data = await call("brief", **{kind: value})
await m.answer(format_brief(data))
Функцию format_brief пишете под реальные поля ответа из документации: собираете строку "марка модель, год, мощность" и добавляете кнопки проверок, о них дальше. Ответ каждого метода сверяйте со страницей в документации, а не с памятью: набор полей лучше не угадывать.
Шаг 3. Госномер и VIN: конвертация в обе стороны
Многие методы принимают VIN: залоги, ограничения, лизинг, ДТП. Пользователь же прислал госномер. Тогда сначала вызываем VIN по госномеру: GET /gos2vin?plate=, 8 рублей. В ответе VIN, номер кузова или шасси, СТС, марка, модель, год, мощность и признак такси. Обратная задача решается через /vin2gos, там 6 рублей.
Главное правило здесь - не платить дважды за одно и то же. Как только вы получили VIN по номеру, кладите пару в кэш на время диалога (словарь в памяти с TTL, а для нескольких инстансов - Redis). Пользователь нажмёт пять кнопок подряд, а конвертация будет оплачена один раз.
cache = {} # plate -> vin
async def resolve_vin(kind, value):
if kind == "vin":
return value
if value in cache:
return cache[value]
d = await call("gos2vin", plate=value)
vin = d.get("vin")
if vin:
cache[value] = vin
return vin
Для VIN, введённого руками, полезна проверка на опечатку. Регулярка ловит длину и недопустимые буквы, но не ошибку в одной цифре. Тут помогает расшифровка VIN за 1,6 рубля: если API не смог определить модель, скорее всего, VIN набран с ошибкой, и тратить деньги на дорогие методы рано. Подробнее про логику сборки отчётов - в материале сборка отчёта по VIN для бизнеса, а вариант со входом по номеру разобран в статье проверка по госномеру для автосалона.
Шаг 4. Кнопки проверок вместо одного большого отчёта
Соблазн - при вводе VIN сразу собрать полный отчёт из десяти методов. Для бота это плохо: дорого, медленно, а главное, большинству пользователей нужна одна-две проверки. Выкупщику важны залоги и ограничения, логисту - такси и техосмотр. Поэтому после карточки показываем инлайн-кнопки, а запрос уходит только по нажатию. Расходы под контролем, пользователь платит (или вы платите) за то, что реально смотрели.
| Кнопка | Метод | Цена за запрос, руб. |
|---|---|---|
| Залоги | GET /pledge?vin= | 2,4 |
| Ограничения и розыск | GET /score?vin= | 20 |
| Штрафы | GET /fines?sts= | 0,9 |
| ОСАГО | GET /osago?vin= | 1,5 |
| Техосмотр и пробег | GET /probeg?vin= | 3,5 |
| Лизинг | GET /lizing?vin= | 2,2 |
| Такси | GET /taxi?vin= | 1,8 |
| ДТП (архив) | GET /accidents?vin= | 0,8 |
Обратите внимание: штрафы ищутся по СТС, водительскому удостоверению или номеру постановления, а не по VIN. Если у бота есть только VIN, кнопку "Штрафы" сначала просим подтвердить вводом номера СТС. Вспомните, что СТС вам может отдать и /gos2vin, но для клиентского бота спрашивайте номер у пользователя, это честнее.
Пример кнопок и обработчика для залога и ограничений. По реестру залогов нужны поля status и active_count, по методу ограничения и розыск - поле found и список запретов на регистрационные действия.
from aiogram import F
from aiogram.utils.keyboard import InlineKeyboardBuilder
def kb(vin):
b = InlineKeyboardBuilder()
b.button(text="Залоги", callback_data=f"pledge:{vin}")
b.button(text="Ограничения", callback_data=f"score:{vin}")
b.button(text="ОСАГО", callback_data=f"osago:{vin}")
b.button(text="Пробег", callback_data=f"probeg:{vin}")
b.adjust(2)
return b.as_markup()
@dp.callback_query(F.data.startswith("pledge:"))
async def pledge(c: types.CallbackQuery):
vin = c.data.split(":")[1]
d = await call("pledge", vin=vin)
n = d.get("active_count", 0)
text = f"Залог действует ({n})" if n else "Действующих залогов нет"
await c.message.answer(text)
await c.answer()
@dp.callback_query(F.data.startswith("score:"))
async def score(c: types.CallbackQuery):
vin = c.data.split(":")[1]
d = await call("score", vin=vin)
if d.get("found") == 0:
return await c.message.answer("VIN не найден в базе ГИБДД")
await c.message.answer(format_restrictions(d))
await c.answer()
Для ограничений в ответе показывайте тип, основание и регион, а для запретов - ещё и номер исполнительного производства, если он есть. Менеджеру этого достаточно, чтобы понять: сделка стоит или идёт.
Шаг 5. Долгие и асинхронные методы
Часть методов отвечает не сразу. ДТП по базе ГИБДД - асинхронный: создаётся задача, затем опрос раз в 30 секунд, до 40 минут. CARFAX, AutoCheck и аукционные лоты тоже работают через taskId и опрос, обычно 5-15 минут. История полисов ОСАГО отвечает за 15-60 секунд. Держать открытым обработчик сообщения на это время нельзя.
Схема такая. Пользователь нажимает кнопку, бот отвечает "принял в работу, пришлю результат" и сохраняет задачу (chat_id, метод, taskId, время создания) в базе. Фоновый воркер раз в 30 секунд проходит по открытым задачам, делает GET /accidents-rt?task=... и, когда статус готов, отправляет сообщение с итогом. Для отчётов CARFAX и AutoCheck приходят ссылки на файлы report.files[].url: PDF оригинала и версия на русском. Присылайте их ссылками, а если нужно, перекладывайте в свой чат.
async def worker():
while True:
for t in db.open_tasks():
d = await call(t.method, task=t.task_id)
if d.get("status") == "done":
await bot.send_message(t.chat_id, format_report(d))
db.close(t.id)
elif d.get("status") == "error":
await bot.send_message(t.chat_id, "Источник не ответил, списания нет.")
db.close(t.id)
await asyncio.sleep(30)
Файлы отчётов хранятся у нас 90 дней. Если пользователю нужен постоянный доступ дольше, скачивайте PDF и складывайте к себе. Для CARFAX списание одно, при готовом отчёте, а ответ "нет данных" (NOT_AVAILABLE) бесплатный. Перед дорогим зарубежным отчётом (CARFAX и AutoCheck по 389 рублей) дёшево проверьте через /vin-precheck за 0,2 рубля, есть ли вообще записи по этому VIN.
Шаг 6. Бот с фото: номер и марка по снимку
Пользователь присылает фото, бот скачивает файл через Telegram Bot API и отправляет его методом госномер и марка по фото: POST /photo-plate. В ответе госномер кириллицей (plate), марка и модель латиницей, цвет и тип кузова, до трёх машин на снимке (cars). Метод стоит 0,1 рубля, и платно только если определён госномер или марка хотя бы одной машины. Затем найденный номер идёт в обычный сценарий через /gos2vin.
@dp.message(F.photo)
async def on_photo(m: types.Message):
f = await bot.get_file(m.photo[-1].file_id)
buf = await bot.download_file(f.file_path)
r = await http.post(f"{API}/photo-plate",
files={"photo": ("car.jpg", buf.read(), "image/jpeg")})
cars = r.json().get("cars", [])
if not cars:
return await m.answer("Номер не разобрал, пришлите кадр поближе.")
await m.answer(f"Нашёл: {cars[0].get('plate')}")
Если бот нужен для площадки объявлений, пригодится обратная задача: скрытие номера на фото. Метод /plate-hide закрывает номера размытием, мозаикой, заливкой или вашим логотипом, а /face-hide убирает лица. Принимает до 10 фото за раз. С параметром ?test=1 всё работает бесплатно, но картинка уменьшена и с пометкой TEST, так что для отладки самое то.
Контроль расходов, лимиты и безопасность
Внутренний бот без защиты быстро превращается в бесплатный кабинет для всех, кто узнал его имя. Минимум, который стоит сделать с первого дня: белый список Telegram ID или роли (менеджер видит базовые проверки, руководитель - всё), лимит проверок на человека в день и лог каждого запроса с методом, ценой и пользователем.
Лог окупается сразу. По нему видно, какие кнопки реально нажимают, сколько стоит типовой отчёт и кто делает аномально много запросов. Типовой пример для выкупа: карточка 1 + залоги 2,4 + ограничения 20 + ОСАГО 1,5 + пробег 3,5 = 28,4 рубля, плюс 8 рублей, если вход был по госномеру.
Про данные. Во многих ответах персональные данные уже скрыты: в исполнительных производствах ФИО, дата рождения и адрес закрыты звёздочками, в истории ОСАГО их нет вообще. Не пытайтесь "улучшать" это на своей стороне и не сохраняйте в логах лишнего. Ошибки обрабатывайте спокойно: при сбое источника списания нет, поэтому повтор через несколько секунд безопасен, но ограничьте число попыток (два-три) и покажите пользователю понятное сообщение вместо трейсбэка.
Юрлицам удобнее оплата по счёту: акт и акт сверки приходят в конце месяца, договор для самостоятельного подключения не требуется.
Что делать дальше: от бота к продукту
Если команде нужно проверить сразу много машин, бот - не лучший инструмент. Для таких задач есть массовая проверка без кода: список до 100 машин файлом или текстом, выбор проверок, расчёт стоимости до запуска и итоговая таблица. Это дополняет бота, а не заменяет его: бот для "здесь и сейчас", таблица для партии.
Дальше бот можно наращивать по мере появления задач: добавить кнопки для судебных дел и долгов у судебных приставов, а для грузового транспорта - проверку пропусков на МКАД и статуса в РНИС. Свои кнопки, роли, лимиты и фирменные ответы - как раз то, ради чего бот строят на API.
Частые вопросы
Можно ли сделать бесплатный бот для проверки авто?
Бесплатно можно разработать и протестировать: тестовые значения (VIN X7TEST00000000001, госномер Т000ТТ00) отдают образцы ответов без оплаты. В боевом режиме данные ГИБДД платные, поэтому полностью бесплатный бот с реальными данными невозможен. Вы платите только за выполненную проверку, пополнение от 100 рублей.
Как проверить авто по госномеру через телеграм-бота?
Бот определяет формат госномера, для быстрой карточки вызывает GET /brief?plate=, а для проверок, которым нужен VIN, сначала получает его через GET /gos2vin?plate= (8 рублей). Полученный VIN стоит кэшировать на время диалога, чтобы не платить за конвертацию повторно.
Сколько стоит одна проверка в боте?
Зависит от кнопок. Карточка по /brief стоит 1 рубль, залоги 2,4, штрафы 0,9, ОСАГО 1,5, техосмотр и пробег 3,5, лизинг 2,2, ограничения и розыск 20. Бот с кнопками списывает деньги только за то, что нажал пользователь.
Нужен ли договор для подключения API?
Нет. Регистрация в кабинете avtovincod.ru/lk занимает минуту, токен выдаётся сразу, пополнение картой от 100 рублей. Юрлица могут оплачивать по счёту, акт и акт сверки приходят в конце месяца.
Как протестировать бота без оплаты?
Используйте тестовый VIN X7TEST00000000001 и госномер Т000ТТ00: методы вернут образцы ответов бесплатно. Для методов с фото есть параметр ?test=1, он тоже не списывает деньги, а картинка приходит уменьшенной с пометкой TEST.
Что делать с долгими методами вроде CARFAX и ДТП по ГИБДД?
Работать через очередь. Бот сразу отвечает "принял в работу", сохраняет taskId, а фоновый воркер раз в 30 секунд опрашивает метод. Когда статус становится готовым, бот отправляет результат сообщением или ссылкой на PDF. Файлы отчётов хранятся 90 дней.
Проверка автомобилей через API
Без договора и долгих согласований: пополните баланс от 100 ₽ и проверяйте реальные машины. Тестовые значения бесплатно, документация с примерами на популярных языках.
Получить токен Документация API

