[{"data":1,"prerenderedAt":3115},["ShallowReactive",2],{"blog-posts-ru":3},[4,364,1119,1643,2307],{"id":5,"title":6,"body":7,"date":347,"description":348,"extension":349,"meta":350,"navigation":351,"path":352,"readTime":353,"seo":354,"slug":355,"stem":356,"tags":357,"__hash__":363},"blogRu\u002Fru\u002Fblog\u002Favtomatizaciya-biznesa-telegram.md","Автоматизация бизнеса через Telegram — что реально экономит время и деньги",{"type":8,"value":9,"toc":329},"minimark",[10,15,19,26,31,34,41,47,53,56,60,65,68,79,85,89,92,97,101,104,110,114,117,133,136,140,154,157,161,164,169,173,176,178,182,260,262,266,269,275,278,280,284,311,313,317,320],[11,12,14],"h1",{"id":13},"автоматизация-бизнеса-через-telegram-что-реально-работает","Автоматизация бизнеса через Telegram — что реально работает",[16,17,18],"p",{},"Telegram давно перестал быть просто мессенджером. Для малого и среднего бизнеса это полноценная платформа: приём заявок, поддержка клиентов, внутренние инструменты, уведомления, мини-приложения. В этой статье — конкретно о том, что автоматизировать в первую очередь и сколько это стоит.",[16,20,21],{},[22,23],"img",{"alt":24,"src":25},"Автоматизация бизнеса через Telegram — схема","\u002Fimages\u002Fblog\u002Fautomation-workflow.svg",[27,28,30],"h2",{"id":29},"почему-telegram-а-не-сайт-или-приложение","Почему Telegram, а не сайт или приложение",[16,32,33],{},"Три простых причины:",[16,35,36,40],{},[37,38,39],"strong",{},"1. Аудитория уже там."," В России и СНГ Telegram — основной мессенджер. Клиенту не нужно скачивать ничего лишнего.",[16,42,43,46],{},[37,44,45],{},"2. Скорость запуска."," Бот в Telegram запускается за 1–3 дня. Мобильное приложение — от месяца.",[16,48,49,52],{},[37,50,51],{},"3. Стоимость."," Простой бот стоит $40–100. Мобильное приложение — от $500.",[54,55],"hr",{},[27,57,59],{"id":58},"топ-7-процессов-для-автоматизации","Топ-7 процессов для автоматизации",[61,62,64],"h3",{"id":63},"_1-приём-заявок-и-запись","1. Приём заявок и запись",[16,66,67],{},"Бот собирает имя, контакт, описание задачи — и сразу пишет вам в личку или в CRM. Без пропущенных сообщений, без «я вам ответил в другом чате».",[69,70,75],"pre",{"className":71,"code":73,"language":74},[72],"language-text","Клиент: \u002Fstart\nБот: Привет! Как вас зовут?\nКлиент: Алексей\nБот: Опишите вашу задачу\nКлиент: Нужен сайт...\nБот: ✅ Заявка принята! Алексей, ответим в течение 2 часов.\n→ [Вам приходит уведомление с данными клиента]\n","text",[76,77,73],"code",{"__ignoreMap":78},"",[16,80,81,84],{},[37,82,83],{},"Экономия:"," менеджер не тратит время на сбор данных вручную. При 20 заявках в день — это 1–2 часа ежедневно.",[61,86,88],{"id":87},"_2-faq-и-поддержка-клиентов","2. FAQ и поддержка клиентов",[16,90,91],{},"80% вопросов в поддержке повторяются: «как оплатить», «где мой заказ», «какие сроки». Бот отвечает мгновенно, сложные вопросы переключает на человека.",[16,93,94,96],{},[37,95,83],{}," 1 оператор вместо 3 при том же объёме обращений.",[61,98,100],{"id":99},"_3-интернет-магазин-с-автовыдачей","3. Интернет-магазин с автовыдачей",[16,102,103],{},"Продажа цифровых товаров: ключи, доступы, файлы. Оплата через Telegram Stars или криптовалюту — товар выдаётся автоматически, без участия человека.",[16,105,106,109],{},[37,107,108],{},"Реальный кейс:"," магазин на 200+ SKU, 50–100 продаж в день — полностью автоматический.",[61,111,113],{"id":112},"_4-уведомления-и-мониторинг","4. Уведомления и мониторинг",[16,115,116],{},"Бот сообщает команде:",[118,119,120,124,127,130],"ul",{},[121,122,123],"li",{},"Новый заказ на сайте",[121,125,126],{},"Сервер упал \u002F восстановился",[121,128,129],{},"Новый отзыв на маркетплейсе",[121,131,132],{},"Аномалия в продажах",[16,134,135],{},"Интегрируется с любой системой через webhook за 2–4 часа работы.",[61,137,139],{"id":138},"_5-внутренние-инструменты-для-команды","5. Внутренние инструменты для команды",[118,141,142,145,148,151],{},[121,143,144],{},"Отчёты по выручке за день\u002Fнеделю",[121,146,147],{},"Задачи сотрудникам",[121,149,150],{},"Голосование и опросы",[121,152,153],{},"База знаний с поиском",[16,155,156],{},"Особенно полезно для команд на удалёнке — всё в одном месте, не надо переключаться между 10 сервисами.",[61,158,160],{"id":159},"_6-расписание-и-запись","6. Расписание и запись",[16,162,163],{},"Клиент видит свободные слоты, выбирает время, получает подтверждение. Бот отправляет напоминание за день. Работает для: барберы, фитнес-тренеры, врачи, репетиторы.",[16,165,166,168],{},[37,167,83],{}," 30–60 минут администратора в день на обработку записей.",[61,170,172],{"id":171},"_7-telegram-mini-app","7. Telegram Mini App",[16,174,175],{},"Полноценное приложение внутри Telegram — с красивым UI, авторизацией, корзиной, оплатой. Пользователь открывает его одной кнопкой, без установки.",[54,177],{},[27,179,181],{"id":180},"сколько-стоит-автоматизация","Сколько стоит автоматизация",[183,184,185,201],"table",{},[186,187,188],"thead",{},[189,190,191,195,198],"tr",{},[192,193,194],"th",{},"Тип бота",[192,196,197],{},"Что включает",[192,199,200],{},"Цена",[202,203,204,216,227,238,249],"tbody",{},[189,205,206,210,213],{},[207,208,209],"td",{},"Простой FAQ",[207,211,212],{},"Команды, ответы на вопросы",[207,214,215],{},"$40–80",[189,217,218,221,224],{},[207,219,220],{},"Бот заявок",[207,222,223],{},"FSM-диалог, уведомление вам",[207,225,226],{},"$80–150",[189,228,229,232,235],{},[207,230,231],{},"Магазин с оплатой",[207,233,234],{},"Каталог, Stars\u002Fкрипто, автовыдача",[207,236,237],{},"$150–300",[189,239,240,243,246],{},[207,241,242],{},"Mini App",[207,244,245],{},"Веб-интерфейс, API, база данных",[207,247,248],{},"$300–700",[189,250,251,254,257],{},[207,252,253],{},"AI-помощник",[207,255,256],{},"GPT, RAG, история диалогов",[207,258,259],{},"$200–500",[54,261],{},[27,263,265],{"id":264},"когда-автоматизация-окупается","Когда автоматизация окупается",[16,267,268],{},"Простой расчёт. Допустим, менеджер тратит 2 часа в день на рутину: отвечает на одни и те же вопросы, вносит заявки вручную, формирует отчёты.",[69,270,273],{"className":271,"code":272,"language":74},[72],"Стоимость рабочего времени: $5\u002Fчас\n2 часа в день × 22 рабочих дня = 44 часа в месяц\n44 × $5 = $220 в месяц\n\nСтоимость бота: $150 (единовременно)\n→ Окупаемость: \u003C 1 месяц\n",[76,274,272],{"__ignoreMap":78},[16,276,277],{},"Это консервативный расчёт. На практике автоматизация даёт больше: меньше ошибок, работа 24\u002F7, масштабируемость без роста штата.",[54,279],{},[27,281,283],{"id":282},"как-начать","Как начать",[285,286,287,293,299,305],"ol",{},[121,288,289,292],{},[37,290,291],{},"Определите самый болезненный процесс"," — где больше всего ручной работы или потерянных клиентов",[121,294,295,298],{},[37,296,297],{},"Опишите задачу"," — что должен делать бот, кто им пользуется",[121,300,301,304],{},[37,302,303],{},"Начните с простого"," — MVP-бот за $50–100, который решает одну конкретную задачу",[121,306,307,310],{},[37,308,309],{},"Масштабируйте"," — добавляйте функции по мере роста",[54,312],{},[27,314,316],{"id":315},"вывод","Вывод",[16,318,319],{},"Telegram-автоматизация — один из лучших ROI в IT для малого бизнеса. Низкий порог входа, быстрый результат, понятный инструмент для клиентов.",[16,321,322,323,328],{},"Если хотите автоматизировать конкретный процесс — ",[324,325,327],"a",{"href":326},"\u002Fru#contact","расскажите о задаче",", разберём что и как.",{"title":78,"searchDepth":330,"depth":330,"links":331},2,[332,333,343,344,345,346],{"id":29,"depth":330,"text":30},{"id":58,"depth":330,"text":59,"children":334},[335,337,338,339,340,341,342],{"id":63,"depth":336,"text":64},3,{"id":87,"depth":336,"text":88},{"id":99,"depth":336,"text":100},{"id":112,"depth":336,"text":113},{"id":138,"depth":336,"text":139},{"id":159,"depth":336,"text":160},{"id":171,"depth":336,"text":172},{"id":180,"depth":330,"text":181},{"id":264,"depth":330,"text":265},{"id":282,"depth":330,"text":283},{"id":315,"depth":330,"text":316},"2025-01-10","Разбираю, какие бизнес-процессы стоит автоматизировать через Telegram в первую очередь, сколько это стоит и когда окупается. Реальные кейсы и цифры.","md",{},true,"\u002Fru\u002Fblog\u002Favtomatizaciya-biznesa-telegram","8 мин",{"title":6,"description":348},"avtomatizaciya-biznesa-telegram","ru\u002Fblog\u002Favtomatizaciya-biznesa-telegram",[358,359,360,361,362],"Автоматизация","Telegram","Бизнес","Python","Боты","CqbrbKN0S-WTR49_Vgks0TlGIhyQaLk5FEuhEp1PcbQ",{"id":365,"title":366,"body":367,"date":1107,"description":1108,"extension":349,"meta":1109,"navigation":351,"path":1110,"readTime":1111,"seo":1112,"slug":1113,"stem":1114,"tags":1115,"__hash__":1118},"blogRu\u002Fru\u002Fblog\u002Fchatgpt-dlya-biznesa.md","Внедрение ChatGPT в бизнес — практическое руководство 2024",{"type":8,"value":368,"toc":1088},[369,373,376,382,386,389,393,400,404,407,411,418,422,425,427,431,434,656,667,669,673,676,682,686,839,851,853,857,861,932,936,956,958,962,968,976,982,988,990,994,1046,1048,1050,1053,1070,1077,1084],[11,370,372],{"id":371},"внедрение-chatgpt-в-бизнес-как-это-работает-на-практике","Внедрение ChatGPT в бизнес — как это работает на практике",[16,374,375],{},"«Нам нужен ChatGPT» — одна из самых частых фраз от клиентов за последний год. Но за этим запросом обычно стоит что-то конкретное: автоматизировать поддержку, обрабатывать заявки, создать умного помощника. В этой статье разберу, как это реально делается — с примерами кода и реальными цифрами.",[16,377,378],{},[22,379],{"alt":380,"src":381},"Как AI встраивается в бизнес-процессы","\u002Fimages\u002Fblog\u002Fai-integration.svg",[27,383,385],{"id":384},"что-конкретно-можно-автоматизировать-с-помощью-ai","Что конкретно можно автоматизировать с помощью AI",[16,387,388],{},"Не всё подряд. Вот где AI действительно окупается:",[61,390,392],{"id":391},"_1-поддержка-клиентов","1. Поддержка клиентов",[16,394,395,396,399],{},"Бот отвечает на типичные вопросы 24\u002F7. По статистике, ",[37,397,398],{},"60–80% обращений в поддержку повторяются",". AI обрабатывает их мгновенно, сложные — передаёт оператору.",[61,401,403],{"id":402},"_2-обработка-заявок-и-квалификация-лидов","2. Обработка заявок и квалификация лидов",[16,405,406],{},"Бот задаёт уточняющие вопросы, собирает данные, оценивает потенциал клиента — и передаёт в CRM уже заполненную карточку.",[61,408,410],{"id":409},"_3-поиск-по-внутренним-документам","3. Поиск по внутренним документам",[16,412,413,414,417],{},"Сотрудник пишет вопрос на русском языке, AI ищет ответ в регламентах, договорах, инструкциях. Это называется ",[37,415,416],{},"RAG (Retrieval-Augmented Generation)",".",[61,419,421],{"id":420},"_4-генерация-и-обработка-текстов","4. Генерация и обработка текстов",[16,423,424],{},"Составление ответов на отзывы, описания товаров, краткое изложение встреч, перевод документов.",[54,426],{},[27,428,430],{"id":429},"telegram-бот-с-chatgpt-базовая-реализация","Telegram-бот с ChatGPT: базовая реализация",[16,432,433],{},"Самый быстрый способ дать сотрудникам или клиентам доступ к AI — Telegram-бот. Вот минимальная рабочая версия:",[69,435,439],{"className":436,"code":437,"language":438,"meta":78,"style":78},"language-python shiki shiki-themes github-light github-dark","import asyncio\nfrom aiogram import Bot, Dispatcher, types\nfrom aiogram.filters import CommandStart\nfrom openai import AsyncOpenAI\n\nbot = Bot(token=\"YOUR_BOT_TOKEN\")\ndp = Dispatcher()\nopenai = AsyncOpenAI(api_key=\"YOUR_OPENAI_KEY\")\n\nSYSTEM_PROMPT = \"\"\"Ты помощник компании [Название].\nОтвечай на вопросы о наших услугах, ценах и условиях работы.\nЕсли не знаешь ответа — предложи связаться с менеджером.\"\"\"\n\n@dp.message(CommandStart())\nasync def start(message: types.Message):\n    await message.answer(\"Привет! Чем могу помочь?\")\n\n@dp.message()\nasync def handle_message(message: types.Message):\n    # Показываем что думаем\n    thinking = await message.answer(\"⏳ Думаю...\")\n\n    response = await openai.chat.completions.create(\n        model=\"gpt-4o-mini\",  # дешевле, но умный\n        messages=[\n            {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n            {\"role\": \"user\",   \"content\": message.text},\n        ],\n        max_tokens=500,\n    )\n\n    await thinking.edit_text(response.choices[0].message.content)\n\nasync def main():\n    await dp.start_polling(bot)\n\nasyncio.run(main())\n","python",[76,440,441,449,454,459,465,471,477,483,489,494,500,506,512,517,523,529,535,540,546,552,558,564,569,575,581,587,593,599,605,611,617,622,628,633,639,645,650],{"__ignoreMap":78},[442,443,446],"span",{"class":444,"line":445},"line",1,[442,447,448],{},"import asyncio\n",[442,450,451],{"class":444,"line":330},[442,452,453],{},"from aiogram import Bot, Dispatcher, types\n",[442,455,456],{"class":444,"line":336},[442,457,458],{},"from aiogram.filters import CommandStart\n",[442,460,462],{"class":444,"line":461},4,[442,463,464],{},"from openai import AsyncOpenAI\n",[442,466,468],{"class":444,"line":467},5,[442,469,470],{"emptyLinePlaceholder":351},"\n",[442,472,474],{"class":444,"line":473},6,[442,475,476],{},"bot = Bot(token=\"YOUR_BOT_TOKEN\")\n",[442,478,480],{"class":444,"line":479},7,[442,481,482],{},"dp = Dispatcher()\n",[442,484,486],{"class":444,"line":485},8,[442,487,488],{},"openai = AsyncOpenAI(api_key=\"YOUR_OPENAI_KEY\")\n",[442,490,492],{"class":444,"line":491},9,[442,493,470],{"emptyLinePlaceholder":351},[442,495,497],{"class":444,"line":496},10,[442,498,499],{},"SYSTEM_PROMPT = \"\"\"Ты помощник компании [Название].\n",[442,501,503],{"class":444,"line":502},11,[442,504,505],{},"Отвечай на вопросы о наших услугах, ценах и условиях работы.\n",[442,507,509],{"class":444,"line":508},12,[442,510,511],{},"Если не знаешь ответа — предложи связаться с менеджером.\"\"\"\n",[442,513,515],{"class":444,"line":514},13,[442,516,470],{"emptyLinePlaceholder":351},[442,518,520],{"class":444,"line":519},14,[442,521,522],{},"@dp.message(CommandStart())\n",[442,524,526],{"class":444,"line":525},15,[442,527,528],{},"async def start(message: types.Message):\n",[442,530,532],{"class":444,"line":531},16,[442,533,534],{},"    await message.answer(\"Привет! Чем могу помочь?\")\n",[442,536,538],{"class":444,"line":537},17,[442,539,470],{"emptyLinePlaceholder":351},[442,541,543],{"class":444,"line":542},18,[442,544,545],{},"@dp.message()\n",[442,547,549],{"class":444,"line":548},19,[442,550,551],{},"async def handle_message(message: types.Message):\n",[442,553,555],{"class":444,"line":554},20,[442,556,557],{},"    # Показываем что думаем\n",[442,559,561],{"class":444,"line":560},21,[442,562,563],{},"    thinking = await message.answer(\"⏳ Думаю...\")\n",[442,565,567],{"class":444,"line":566},22,[442,568,470],{"emptyLinePlaceholder":351},[442,570,572],{"class":444,"line":571},23,[442,573,574],{},"    response = await openai.chat.completions.create(\n",[442,576,578],{"class":444,"line":577},24,[442,579,580],{},"        model=\"gpt-4o-mini\",  # дешевле, но умный\n",[442,582,584],{"class":444,"line":583},25,[442,585,586],{},"        messages=[\n",[442,588,590],{"class":444,"line":589},26,[442,591,592],{},"            {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",[442,594,596],{"class":444,"line":595},27,[442,597,598],{},"            {\"role\": \"user\",   \"content\": message.text},\n",[442,600,602],{"class":444,"line":601},28,[442,603,604],{},"        ],\n",[442,606,608],{"class":444,"line":607},29,[442,609,610],{},"        max_tokens=500,\n",[442,612,614],{"class":444,"line":613},30,[442,615,616],{},"    )\n",[442,618,620],{"class":444,"line":619},31,[442,621,470],{"emptyLinePlaceholder":351},[442,623,625],{"class":444,"line":624},32,[442,626,627],{},"    await thinking.edit_text(response.choices[0].message.content)\n",[442,629,631],{"class":444,"line":630},33,[442,632,470],{"emptyLinePlaceholder":351},[442,634,636],{"class":444,"line":635},34,[442,637,638],{},"async def main():\n",[442,640,642],{"class":444,"line":641},35,[442,643,644],{},"    await dp.start_polling(bot)\n",[442,646,648],{"class":444,"line":647},36,[442,649,470],{"emptyLinePlaceholder":351},[442,651,653],{"class":444,"line":652},37,[442,654,655],{},"asyncio.run(main())\n",[16,657,658,659,662,663,666],{},"Это рабочий код. Стоимость такого бота при 1000 сообщений в день — ",[37,660,661],{},"около $2–5 в месяц"," на токены (при использовании ",[76,664,665],{},"gpt-4o-mini",").",[54,668],{},[27,670,672],{"id":671},"rag-ai-который-знает-ваши-документы","RAG: AI, который знает ваши документы",[16,674,675],{},"Проблема обычного ChatGPT — он не знает специфику вашего бизнеса. RAG решает это: документы индексируются в векторную базу данных, при каждом запросе находится релевантный контекст и передаётся модели.",[69,677,680],{"className":678,"code":679,"language":74},[72],"Пользователь → Вопрос\n      ↓\nВекторный поиск по документам (Qdrant\u002FChroma)\n      ↓\nНайденные фрагменты + вопрос → GPT\n      ↓\nОтвет со ссылкой на источник\n",[76,681,679],{"__ignoreMap":78},[61,683,685],{"id":684},"пример-корпоративный-помощник-по-регламентам","Пример: корпоративный помощник по регламентам",[69,687,689],{"className":436,"code":688,"language":438,"meta":78,"style":78},"from qdrant_client import QdrantClient\nfrom openai import AsyncOpenAI\n\nclient = QdrantClient(\":memory:\")\nopenai = AsyncOpenAI()\n\nasync def answer_with_context(question: str) -> str:\n    # 1. Получаем embedding вопроса\n    embedding = await openai.embeddings.create(\n        model=\"text-embedding-3-small\",\n        input=question,\n    )\n\n    # 2. Ищем похожие документы\n    results = client.search(\n        collection_name=\"docs\",\n        query_vector=embedding.data[0].embedding,\n        limit=3,\n    )\n\n    # 3. Формируем контекст\n    context = \"\\n\\n\".join([r.payload[\"text\"] for r in results])\n\n    # 4. Спрашиваем GPT\n    response = await openai.chat.completions.create(\n        model=\"gpt-4o-mini\",\n        messages=[\n            {\"role\": \"system\", \"content\": f\"Контекст из документов:\\n{context}\"},\n            {\"role\": \"user\",   \"content\": question},\n        ],\n    )\n    return response.choices[0].message.content\n",[76,690,691,696,700,704,709,714,718,723,728,733,738,743,747,751,756,761,766,771,776,780,784,789,794,798,803,807,812,816,821,826,830,834],{"__ignoreMap":78},[442,692,693],{"class":444,"line":445},[442,694,695],{},"from qdrant_client import QdrantClient\n",[442,697,698],{"class":444,"line":330},[442,699,464],{},[442,701,702],{"class":444,"line":336},[442,703,470],{"emptyLinePlaceholder":351},[442,705,706],{"class":444,"line":461},[442,707,708],{},"client = QdrantClient(\":memory:\")\n",[442,710,711],{"class":444,"line":467},[442,712,713],{},"openai = AsyncOpenAI()\n",[442,715,716],{"class":444,"line":473},[442,717,470],{"emptyLinePlaceholder":351},[442,719,720],{"class":444,"line":479},[442,721,722],{},"async def answer_with_context(question: str) -> str:\n",[442,724,725],{"class":444,"line":485},[442,726,727],{},"    # 1. Получаем embedding вопроса\n",[442,729,730],{"class":444,"line":491},[442,731,732],{},"    embedding = await openai.embeddings.create(\n",[442,734,735],{"class":444,"line":496},[442,736,737],{},"        model=\"text-embedding-3-small\",\n",[442,739,740],{"class":444,"line":502},[442,741,742],{},"        input=question,\n",[442,744,745],{"class":444,"line":508},[442,746,616],{},[442,748,749],{"class":444,"line":514},[442,750,470],{"emptyLinePlaceholder":351},[442,752,753],{"class":444,"line":519},[442,754,755],{},"    # 2. Ищем похожие документы\n",[442,757,758],{"class":444,"line":525},[442,759,760],{},"    results = client.search(\n",[442,762,763],{"class":444,"line":531},[442,764,765],{},"        collection_name=\"docs\",\n",[442,767,768],{"class":444,"line":537},[442,769,770],{},"        query_vector=embedding.data[0].embedding,\n",[442,772,773],{"class":444,"line":542},[442,774,775],{},"        limit=3,\n",[442,777,778],{"class":444,"line":548},[442,779,616],{},[442,781,782],{"class":444,"line":554},[442,783,470],{"emptyLinePlaceholder":351},[442,785,786],{"class":444,"line":560},[442,787,788],{},"    # 3. Формируем контекст\n",[442,790,791],{"class":444,"line":566},[442,792,793],{},"    context = \"\\n\\n\".join([r.payload[\"text\"] for r in results])\n",[442,795,796],{"class":444,"line":571},[442,797,470],{"emptyLinePlaceholder":351},[442,799,800],{"class":444,"line":577},[442,801,802],{},"    # 4. Спрашиваем GPT\n",[442,804,805],{"class":444,"line":583},[442,806,574],{},[442,808,809],{"class":444,"line":589},[442,810,811],{},"        model=\"gpt-4o-mini\",\n",[442,813,814],{"class":444,"line":595},[442,815,586],{},[442,817,818],{"class":444,"line":601},[442,819,820],{},"            {\"role\": \"system\", \"content\": f\"Контекст из документов:\\n{context}\"},\n",[442,822,823],{"class":444,"line":607},[442,824,825],{},"            {\"role\": \"user\",   \"content\": question},\n",[442,827,828],{"class":444,"line":613},[442,829,604],{},[442,831,832],{"class":444,"line":619},[442,833,616],{},[442,835,836],{"class":444,"line":624},[442,837,838],{},"    return response.choices[0].message.content\n",[16,840,841,843,844,850],{},[37,842,108],{}," бот для учителей ",[324,845,849],{"href":846,"rel":847},"https:\u002F\u002Ft.me\u002FAINastaunikBot",[848],"nofollow","@AINastaunikBot"," — отвечает на вопросы по законодательству в сфере образования, находит нужные статьи из НПА за секунды.",[54,852],{},[27,854,856],{"id":855},"сколько-стоит-внедрение-ai","Сколько стоит внедрение AI",[61,858,860],{"id":859},"стоимость-токенов-ежемесячно","Стоимость токенов (ежемесячно)",[183,862,863,879],{},[186,864,865],{},[189,866,867,870,873,876],{},[192,868,869],{},"Сценарий",[192,871,872],{},"Модель",[192,874,875],{},"~Сообщений\u002Fдень",[192,877,878],{},"Стоимость\u002Fмес",[202,880,881,894,907,920],{},[189,882,883,886,888,891],{},[207,884,885],{},"Лёгкий FAQ-бот",[207,887,665],{},[207,889,890],{},"500",[207,892,893],{},"$1–3",[189,895,896,899,901,904],{},[207,897,898],{},"Средний помощник",[207,900,665],{},[207,902,903],{},"2000",[207,905,906],{},"$5–15",[189,908,909,912,915,917],{},[207,910,911],{},"RAG по документам",[207,913,914],{},"gpt-4o",[207,916,890],{},[207,918,919],{},"$10–30",[189,921,922,925,927,929],{},[207,923,924],{},"Тяжёлый агент",[207,926,914],{},[207,928,903],{},[207,930,931],{},"$50–150",[61,933,935],{"id":934},"стоимость-разработки","Стоимость разработки",[118,937,938,944,950],{},[121,939,940,941],{},"Простой Telegram-бот с GPT — ",[37,942,943],{},"от $80",[121,945,946,947],{},"RAG на ваших документах — ",[37,948,949],{},"от $200",[121,951,952,953],{},"Полноценный AI-помощник с историей, ролями, аналитикой — ",[37,954,955],{},"от $500",[54,957],{},[27,959,961],{"id":960},"типичные-ошибки-при-внедрении-ai","Типичные ошибки при внедрении AI",[16,963,964,967],{},[37,965,966],{},"1. Ожидать, что AI всё знает","\nGPT не знает ваш прайс-лист, продукты, политику. Нужен либо хороший system prompt, либо RAG.",[16,969,970,973,975],{},[37,971,972],{},"2. Использовать GPT-4 там, где хватит mini",[76,974,665],{}," в 15 раз дешевле, а для большинства задач — достаточно.",[16,977,978,981],{},[37,979,980],{},"3. Не ограничивать сферу ответов","\nБез ограничений бот может ответить на что угодно. System prompt должен чётко задавать роль и рамки.",[16,983,984,987],{},[37,985,986],{},"4. Игнорировать контекст диалога","\nПользователи пишут несколько сообщений. Храните историю диалога и передавайте её в API.",[54,989],{},[27,991,993],{"id":992},"какие-ai-модели-использовать-в-2024","Какие AI-модели использовать в 2024",[183,995,996,1006],{},[186,997,998],{},[189,999,1000,1003],{},[192,1001,1002],{},"Задача",[192,1004,1005],{},"Лучший выбор",[202,1007,1008,1015,1022,1030,1038],{},[189,1009,1010,1013],{},[207,1011,1012],{},"Массовый FAQ-бот",[207,1014,665],{},[189,1016,1017,1020],{},[207,1018,1019],{},"Сложный анализ, код",[207,1021,914],{},[189,1023,1024,1027],{},[207,1025,1026],{},"Длинные документы",[207,1028,1029],{},"Claude 3.5 Sonnet",[189,1031,1032,1035],{},[207,1033,1034],{},"Быстрые ответы",[207,1036,1037],{},"Gemini Flash",[189,1039,1040,1043],{},[207,1041,1042],{},"Работа с кириллицей",[207,1044,1045],{},"GPT или Claude (лучше всего)",[54,1047],{},[27,1049,316],{"id":315},[16,1051,1052],{},"Внедрение AI — это не «поставить ChatGPT». Это:",[285,1054,1055,1058,1061,1064,1067],{},[121,1056,1057],{},"Понять, какую задачу автоматизируем",[121,1059,1060],{},"Выбрать подходящую модель",[121,1062,1063],{},"Написать правильный system prompt",[121,1065,1066],{},"При необходимости — добавить RAG",[121,1068,1069],{},"Обернуть в удобный интерфейс (Telegram, сайт, API)",[16,1071,1072,1073,1076],{},"Большинство проектов окупается за ",[37,1074,1075],{},"1–3 месяца"," за счёт экономии рабочего времени.",[16,1078,1079,1080,1083],{},"Если хотите внедрить AI в ваш бизнес или продукт — ",[324,1081,1082],{"href":326},"напишите мне",", разберём задачу.",[1085,1086,1087],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":78,"searchDepth":330,"depth":330,"links":1089},[1090,1096,1097,1100,1104,1105,1106],{"id":384,"depth":330,"text":385,"children":1091},[1092,1093,1094,1095],{"id":391,"depth":336,"text":392},{"id":402,"depth":336,"text":403},{"id":409,"depth":336,"text":410},{"id":420,"depth":336,"text":421},{"id":429,"depth":330,"text":430},{"id":671,"depth":330,"text":672,"children":1098},[1099],{"id":684,"depth":336,"text":685},{"id":855,"depth":330,"text":856,"children":1101},[1102,1103],{"id":859,"depth":336,"text":860},{"id":934,"depth":336,"text":935},{"id":960,"depth":330,"text":961},{"id":992,"depth":330,"text":993},{"id":315,"depth":330,"text":316},"2024-12-20","Как реально внедрить ChatGPT и другие AI-модели в бизнес-процессы: Telegram-боты с GPT, автоматизация поддержки, RAG на своих данных. Конкретные примеры и стоимость.",{},"\u002Fru\u002Fblog\u002Fchatgpt-dlya-biznesa","11 мин",{"title":366,"description":1108},"chatgpt-dlya-biznesa","ru\u002Fblog\u002Fchatgpt-dlya-biznesa",[1116,1117,358,361,360],"AI","ChatGPT","crLk_ADlgFbFB4qcMErHzpmv0VurxEgz0YNUBsIaNkQ",{"id":1120,"title":1121,"body":1122,"date":1631,"description":1632,"extension":349,"meta":1633,"navigation":351,"path":1634,"readTime":1635,"seo":1636,"slug":1637,"stem":1638,"tags":1639,"__hash__":1642},"blogRu\u002Fru\u002Fblog\u002Ffastapi-vs-django-2024.md","FastAPI vs Django в 2024 году — что выбрать для вашего проекта",{"type":8,"value":1123,"toc":1621},[1124,1128,1135,1139,1145,1151,1157,1161,1168,1198,1201,1226,1232,1236,1327,1331,1356,1409,1413,1437,1509,1513,1519,1536,1543,1547,1550,1556,1559,1561,1610,1613,1619],[11,1125,1127],{"id":1126},"fastapi-vs-django-в-2024-году","FastAPI vs Django в 2024 году",[16,1129,1130,1131,1134],{},"Один из самых частых вопросов от клиентов: ",[37,1132,1133],{},"«Что использовать для бэкенда — FastAPI или Django?»"," Ответ зависит от задачи, и в этой статье я разберу оба фреймворка честно.",[27,1136,1138],{"id":1137},"коротко-о-каждом","Коротко о каждом",[16,1140,1141],{},[22,1142],{"alt":1143,"src":1144},"FastAPI vs Django — сравнение 2024","\u002Fimages\u002Fblog\u002Ffastapi-vs-django.svg",[16,1146,1147,1150],{},[37,1148,1149],{},"Django"," — «батарейки включены». Создан в 2005 году, проверен временем. ORM, admin-панель, auth, формы — всё из коробки.",[16,1152,1153,1156],{},[37,1154,1155],{},"FastAPI"," — современный async-фреймворк. Создан в 2018 году. Максимальная скорость разработки API, автодокументация, типизация.",[27,1158,1160],{"id":1159},"производительность","Производительность",[16,1162,1163,1164,1167],{},"FastAPI построен на ",[37,1165,1166],{},"Starlette + Pydantic",", полностью асинхронный:",[69,1169,1171],{"className":436,"code":1170,"language":438,"meta":78,"style":78},"# FastAPI — async endpoint\n@app.get(\"\u002Fusers\u002F{user_id}\")\nasync def get_user(user_id: int, db: AsyncSession = Depends(get_db)):\n    user = await db.get(User, user_id)\n    return user\n",[76,1172,1173,1178,1183,1188,1193],{"__ignoreMap":78},[442,1174,1175],{"class":444,"line":445},[442,1176,1177],{},"# FastAPI — async endpoint\n",[442,1179,1180],{"class":444,"line":330},[442,1181,1182],{},"@app.get(\"\u002Fusers\u002F{user_id}\")\n",[442,1184,1185],{"class":444,"line":336},[442,1186,1187],{},"async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):\n",[442,1189,1190],{"class":444,"line":461},[442,1191,1192],{},"    user = await db.get(User, user_id)\n",[442,1194,1195],{"class":444,"line":467},[442,1196,1197],{},"    return user\n",[16,1199,1200],{},"Django традиционно синхронный, но с Django 4.1+ появился нативный async:",[69,1202,1204],{"className":436,"code":1203,"language":438,"meta":78,"style":78},"# Django — async view\nasync def get_user(request, user_id):\n    user = await User.objects.aget(id=user_id)\n    return JsonResponse({\"name\": user.name})\n",[76,1205,1206,1211,1216,1221],{"__ignoreMap":78},[442,1207,1208],{"class":444,"line":445},[442,1209,1210],{},"# Django — async view\n",[442,1212,1213],{"class":444,"line":330},[442,1214,1215],{},"async def get_user(request, user_id):\n",[442,1217,1218],{"class":444,"line":336},[442,1219,1220],{},"    user = await User.objects.aget(id=user_id)\n",[442,1222,1223],{"class":444,"line":461},[442,1224,1225],{},"    return JsonResponse({\"name\": user.name})\n",[16,1227,1228,1231],{},[37,1229,1230],{},"По бенчмаркам:"," FastAPI обрабатывает ~50 000 req\u002Fs, Django — ~5 000 req\u002Fs на тех же условиях. Но для большинства проектов это не имеет значения.",[27,1233,1235],{"id":1234},"что-даёт-каждый-из-коробки","Что даёт каждый из коробки",[183,1237,1238,1249],{},[186,1239,1240],{},[189,1241,1242,1245,1247],{},[192,1243,1244],{},"Функциональность",[192,1246,1149],{},[192,1248,1155],{},[202,1250,1251,1262,1273,1283,1294,1305,1316],{},[189,1252,1253,1256,1259],{},[207,1254,1255],{},"ORM",[207,1257,1258],{},"✅ встроенный",[207,1260,1261],{},"❌ нужен SQLAlchemy",[189,1263,1264,1267,1270],{},[207,1265,1266],{},"Admin-панель",[207,1268,1269],{},"✅",[207,1271,1272],{},"❌ нужен сторонний",[189,1274,1275,1278,1280],{},[207,1276,1277],{},"Auth & сессии",[207,1279,1269],{},[207,1281,1282],{},"❌ нужен fastapi-users",[189,1284,1285,1288,1291],{},[207,1286,1287],{},"Swagger \u002F ReDoc",[207,1289,1290],{},"❌",[207,1292,1293],{},"✅ автоматически",[189,1295,1296,1299,1302],{},[207,1297,1298],{},"WebSockets",[207,1300,1301],{},"частично",[207,1303,1304],{},"✅ нативно",[189,1306,1307,1310,1313],{},[207,1308,1309],{},"Валидация",[207,1311,1312],{},"forms\u002Fserializers",[207,1314,1315],{},"✅ Pydantic",[189,1317,1318,1321,1324],{},[207,1319,1320],{},"Типизация",[207,1322,1323],{},"базовая",[207,1325,1326],{},"✅ отличная",[27,1328,1330],{"id":1329},"когда-выбирать-django","Когда выбирать Django",[118,1332,1333,1340,1347,1350],{},[121,1334,1335,1336,1339],{},"Нужна быстрая ",[37,1337,1338],{},"админка"," (модели → CRUD за 5 минут)",[121,1341,1342,1343,1346],{},"Стандартный ",[37,1344,1345],{},"веб-сайт"," с шаблонами",[121,1348,1349],{},"Команда уже знает Django",[121,1351,1352,1355],{},[37,1353,1354],{},"Монолит"," с авторизацией, профилями, контентом",[69,1357,1359],{"className":436,"code":1358,"language":438,"meta":78,"style":78},"# Django — 5 строк и у вас полная CRUD-админка\nfrom django.db import models\n\nclass Article(models.Model):\n    title   = models.CharField(max_length=200)\n    content = models.TextField()\n    created = models.DateTimeField(auto_now_add=True)\n\n    class Meta:\n        ordering = [\"-created\"]\n",[76,1360,1361,1366,1371,1375,1380,1385,1390,1395,1399,1404],{"__ignoreMap":78},[442,1362,1363],{"class":444,"line":445},[442,1364,1365],{},"# Django — 5 строк и у вас полная CRUD-админка\n",[442,1367,1368],{"class":444,"line":330},[442,1369,1370],{},"from django.db import models\n",[442,1372,1373],{"class":444,"line":336},[442,1374,470],{"emptyLinePlaceholder":351},[442,1376,1377],{"class":444,"line":461},[442,1378,1379],{},"class Article(models.Model):\n",[442,1381,1382],{"class":444,"line":467},[442,1383,1384],{},"    title   = models.CharField(max_length=200)\n",[442,1386,1387],{"class":444,"line":473},[442,1388,1389],{},"    content = models.TextField()\n",[442,1391,1392],{"class":444,"line":479},[442,1393,1394],{},"    created = models.DateTimeField(auto_now_add=True)\n",[442,1396,1397],{"class":444,"line":485},[442,1398,470],{"emptyLinePlaceholder":351},[442,1400,1401],{"class":444,"line":491},[442,1402,1403],{},"    class Meta:\n",[442,1405,1406],{"class":444,"line":496},[442,1407,1408],{},"        ordering = [\"-created\"]\n",[27,1410,1412],{"id":1411},"когда-выбирать-fastapi","Когда выбирать FastAPI",[118,1414,1415,1421,1424,1431,1434],{},[121,1416,1417,1418],{},"Чистый ",[37,1419,1420],{},"REST \u002F GraphQL API",[121,1422,1423],{},"Микросервисная архитектура",[121,1425,1426,1427,1430],{},"Нужна ",[37,1428,1429],{},"автодокументация"," из коробки",[121,1432,1433],{},"Высокие требования к производительности",[121,1435,1436],{},"AI\u002FML сервисы (идеальная интеграция с Python-экосистемой)",[69,1438,1440],{"className":436,"code":1439,"language":438,"meta":78,"style":78},"# FastAPI — типизация, валидация, документация автоматически\nfrom pydantic import BaseModel, EmailStr\n\nclass UserCreate(BaseModel):\n    email: EmailStr\n    name: str\n    age: int | None = None\n\n@app.post(\"\u002Fusers\", response_model=UserResponse, status_code=201)\nasync def create_user(payload: UserCreate, db: AsyncSession = Depends(get_db)):\n    user = User(**payload.model_dump())\n    db.add(user)\n    await db.commit()\n    return user\n",[76,1441,1442,1447,1452,1456,1461,1466,1471,1476,1480,1485,1490,1495,1500,1505],{"__ignoreMap":78},[442,1443,1444],{"class":444,"line":445},[442,1445,1446],{},"# FastAPI — типизация, валидация, документация автоматически\n",[442,1448,1449],{"class":444,"line":330},[442,1450,1451],{},"from pydantic import BaseModel, EmailStr\n",[442,1453,1454],{"class":444,"line":336},[442,1455,470],{"emptyLinePlaceholder":351},[442,1457,1458],{"class":444,"line":461},[442,1459,1460],{},"class UserCreate(BaseModel):\n",[442,1462,1463],{"class":444,"line":467},[442,1464,1465],{},"    email: EmailStr\n",[442,1467,1468],{"class":444,"line":473},[442,1469,1470],{},"    name: str\n",[442,1472,1473],{"class":444,"line":479},[442,1474,1475],{},"    age: int | None = None\n",[442,1477,1478],{"class":444,"line":485},[442,1479,470],{"emptyLinePlaceholder":351},[442,1481,1482],{"class":444,"line":491},[442,1483,1484],{},"@app.post(\"\u002Fusers\", response_model=UserResponse, status_code=201)\n",[442,1486,1487],{"class":444,"line":496},[442,1488,1489],{},"async def create_user(payload: UserCreate, db: AsyncSession = Depends(get_db)):\n",[442,1491,1492],{"class":444,"line":502},[442,1493,1494],{},"    user = User(**payload.model_dump())\n",[442,1496,1497],{"class":444,"line":508},[442,1498,1499],{},"    db.add(user)\n",[442,1501,1502],{"class":444,"line":514},[442,1503,1504],{},"    await db.commit()\n",[442,1506,1507],{"class":444,"line":519},[442,1508,1197],{},[27,1510,1512],{"id":1511},"мой-личный-выбор","Мой личный выбор",[16,1514,1515,1516,1518],{},"В 90% проектов я выбираю ",[37,1517,1155],{},":",[285,1520,1521,1524,1527,1530],{},[121,1522,1523],{},"Типизация через Pydantic избавляет от целого класса ошибок",[121,1525,1526],{},"Swagger\u002FReDoc — клиенты сразу видят API",[121,1528,1529],{},"Async — правильная архитектура под I\u002FO-нагрузки",[121,1531,1532,1533],{},"Легко тестировать с ",[76,1534,1535],{},"httpx",[16,1537,1538,1539,1542],{},"Django выбираю когда нужна быстрая ",[37,1540,1541],{},"admin-панель"," или CMS-логика.",[27,1544,1546],{"id":1545},"django-fastapi-вместе","Django + FastAPI вместе",[16,1548,1549],{},"Популярный паттерн — использовать оба:",[69,1551,1554],{"className":1552,"code":1553,"language":74},[72],"├── backend\u002F\n│   ├── api\u002F          # FastAPI — REST endpoints\n│   └── admin\u002F        # Django — внутренняя adminка\n",[76,1555,1553],{"__ignoreMap":78},[16,1557,1558],{},"Это даёт скорость FastAPI для клиентского API и удобство Django-admin для внутренних операций.",[27,1560,316],{"id":315},[183,1562,1563,1572],{},[186,1564,1565],{},[189,1566,1567,1569],{},[192,1568,1002],{},[192,1570,1571],{},"Выбор",[202,1573,1574,1581,1588,1596,1603],{},[189,1575,1576,1579],{},[207,1577,1578],{},"SaaS, микросервис, API",[207,1580,1155],{},[189,1582,1583,1586],{},[207,1584,1585],{},"CMS, корпоративный сайт",[207,1587,1149],{},[189,1589,1590,1593],{},[207,1591,1592],{},"Telegram-бот с adminкой",[207,1594,1595],{},"FastAPI + Django admin",[189,1597,1598,1601],{},[207,1599,1600],{},"ML\u002FAI сервис",[207,1602,1155],{},[189,1604,1605,1608],{},[207,1606,1607],{},"Быстрый MVP с авторизацией",[207,1609,1149],{},[16,1611,1612],{},"Оба фреймворка — отличные инструменты. Вопрос только в задаче.",[16,1614,1615,1616,417],{},"Если нужна консультация по выбору стека или разработка — ",[324,1617,1618],{"href":326},"свяжитесь со мной",[1085,1620,1087],{},{"title":78,"searchDepth":330,"depth":330,"links":1622},[1623,1624,1625,1626,1627,1628,1629,1630],{"id":1137,"depth":330,"text":1138},{"id":1159,"depth":330,"text":1160},{"id":1234,"depth":330,"text":1235},{"id":1329,"depth":330,"text":1330},{"id":1411,"depth":330,"text":1412},{"id":1511,"depth":330,"text":1512},{"id":1545,"depth":330,"text":1546},{"id":315,"depth":330,"text":316},"2024-12-03","Детальное сравнение FastAPI и Django: производительность, экосистема, подходящие сценарии. Помогаю выбрать правильный инструмент под вашу задачу.",{},"\u002Fru\u002Fblog\u002Ffastapi-vs-django-2024","9 мин",{"title":1121,"description":1632},"fastapi-vs-django-2024","ru\u002Fblog\u002Ffastapi-vs-django-2024",[361,1155,1149,1640,1641],"Backend","API","vMBJGYBNLqosQyLFiYovJHRR1QJU8nVw0814aS-2qMs",{"id":1644,"title":1645,"body":1646,"date":2295,"description":2296,"extension":349,"meta":2297,"navigation":351,"path":2298,"readTime":2299,"seo":2300,"slug":2301,"stem":2302,"tags":2303,"__hash__":2306},"blogRu\u002Fru\u002Fblog\u002Fflutter-vs-react-native.md","Flutter vs React Native в 2024 — что выбрать для мобильного приложения",{"type":8,"value":1647,"toc":2279},[1648,1652,1659,1661,1667,1673,1679,1681,1683,1690,1693,1735,1777,1783,1785,1789,1792,1806,1809,1823,1829,1831,1835,1838,1896,1902,1908,1910,1914,1920,1923,1934,1940,1942,1946,2011,2014,2016,2020,2025,2039,2044,2058,2060,2062,2065,2110,2112,2114,2120,2151,2154,2156,2160,2230,2232,2237,2248,2253,2264,2270,2277],[11,1649,1651],{"id":1650},"flutter-vs-react-native-что-выбрать-в-2024-году","Flutter vs React Native — что выбрать в 2024 году",[16,1653,1654,1655,1658],{},"Один из самых частых вопросов при заказе мобильного приложения: ",[37,1656,1657],{},"Flutter или React Native?"," Оба решают одну задачу — один код, два стора. Но делают это по-разному. Разберу честно, без фанатизма.",[27,1660,1138],{"id":1137},[16,1662,1663],{},[22,1664],{"alt":1665,"src":1666},"Flutter vs React Native — сравнение 2024","\u002Fimages\u002Fblog\u002Fflutter-vs-rn.svg",[16,1668,1669,1672],{},[37,1670,1671],{},"Flutter"," — фреймворк от Google, выпущен в 2018. Язык — Dart. Рисует UI сам, не использует нативные компоненты.",[16,1674,1675,1678],{},[37,1676,1677],{},"React Native"," — от Meta (Facebook), с 2015 года. Язык — JavaScript\u002FTypeScript. Маппит компоненты на нативные UI-элементы платформы.",[54,1680],{},[27,1682,1160],{"id":1159},[16,1684,1685,1686,1689],{},"Flutter работает на собственном движке рендеринга ",[37,1687,1688],{},"Skia\u002FImpeller"," — он рисует каждый пиксель сам. Это даёт стабильные 60\u002F120 fps без зависимости от платформы.",[16,1691,1692],{},"React Native общается с нативным слоем через JavaScript Bridge (или новую архитектуру JSI). Это добавляет накладные расходы на анимациях и сложных интерфейсах.",[69,1694,1698],{"className":1695,"code":1696,"language":1697,"meta":78,"style":78},"language-dart shiki shiki-themes github-light github-dark","\u002F\u002F Flutter — плавная анимация, нет JS bridge\nAnimatedContainer(\n  duration: Duration(milliseconds: 300),\n  curve: Curves.easeInOut,\n  width: isExpanded ? 300 : 100,\n  child: MyWidget(),\n)\n","dart",[76,1699,1700,1705,1710,1715,1720,1725,1730],{"__ignoreMap":78},[442,1701,1702],{"class":444,"line":445},[442,1703,1704],{},"\u002F\u002F Flutter — плавная анимация, нет JS bridge\n",[442,1706,1707],{"class":444,"line":330},[442,1708,1709],{},"AnimatedContainer(\n",[442,1711,1712],{"class":444,"line":336},[442,1713,1714],{},"  duration: Duration(milliseconds: 300),\n",[442,1716,1717],{"class":444,"line":461},[442,1718,1719],{},"  curve: Curves.easeInOut,\n",[442,1721,1722],{"class":444,"line":467},[442,1723,1724],{},"  width: isExpanded ? 300 : 100,\n",[442,1726,1727],{"class":444,"line":473},[442,1728,1729],{},"  child: MyWidget(),\n",[442,1731,1732],{"class":444,"line":479},[442,1733,1734],{},")\n",[69,1736,1740],{"className":1737,"code":1738,"language":1739,"meta":78,"style":78},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F React Native — через Animated API\nconst width = useRef(new Animated.Value(100)).current;\nAnimated.timing(width, {\n  toValue: isExpanded ? 300 : 100,\n  duration: 300,\n  useNativeDriver: false, \u002F\u002F layout анимации — без native driver\n}).start();\n","javascript",[76,1741,1742,1747,1752,1757,1762,1767,1772],{"__ignoreMap":78},[442,1743,1744],{"class":444,"line":445},[442,1745,1746],{},"\u002F\u002F React Native — через Animated API\n",[442,1748,1749],{"class":444,"line":330},[442,1750,1751],{},"const width = useRef(new Animated.Value(100)).current;\n",[442,1753,1754],{"class":444,"line":336},[442,1755,1756],{},"Animated.timing(width, {\n",[442,1758,1759],{"class":444,"line":461},[442,1760,1761],{},"  toValue: isExpanded ? 300 : 100,\n",[442,1763,1764],{"class":444,"line":467},[442,1765,1766],{},"  duration: 300,\n",[442,1768,1769],{"class":444,"line":473},[442,1770,1771],{},"  useNativeDriver: false, \u002F\u002F layout анимации — без native driver\n",[442,1773,1774],{"class":444,"line":479},[442,1775,1776],{},"}).start();\n",[16,1778,1779,1782],{},[37,1780,1781],{},"Победитель по производительности:"," Flutter, особенно на сложных анимациях.",[54,1784],{},[27,1786,1788],{"id":1787},"скорость-разработки","Скорость разработки",[61,1790,1677],{"id":1791},"react-native",[118,1793,1794,1797,1800,1803],{},[121,1795,1796],{},"Если команда знает React — порог входа минимальный",[121,1798,1799],{},"Огромная экосистема npm пакетов",[121,1801,1802],{},"Hot reload работает быстро",[121,1804,1805],{},"Проще найти разработчиков (JS девов больше)",[61,1807,1671],{"id":1808},"flutter",[118,1810,1811,1814,1817,1820],{},[121,1812,1813],{},"Dart учится за 1–2 недели если знаешь любой C-подобный язык",[121,1815,1816],{},"Богатая библиотека виджетов из коробки",[121,1818,1819],{},"Меньше зависимостей от сторонних пакетов",[121,1821,1822],{},"Hot reload тоже отличный",[16,1824,1825,1828],{},[37,1826,1827],{},"По факту:"," React Native быстрее для команды с JS-бэкграундом. Flutter быстрее когда нужен сложный кастомный UI.",[54,1830],{},[27,1832,1834],{"id":1833},"ui-и-дизайн","UI и дизайн",[16,1836,1837],{},"Это главное архитектурное различие:",[183,1839,1840,1850],{},[186,1841,1842],{},[189,1843,1844,1846,1848],{},[192,1845],{},[192,1847,1671],{},[192,1849,1677],{},[202,1851,1852,1863,1874,1885],{},[189,1853,1854,1857,1860],{},[207,1855,1856],{},"Рендеринг",[207,1858,1859],{},"Собственный движок",[207,1861,1862],{},"Нативные компоненты",[189,1864,1865,1868,1871],{},[207,1866,1867],{},"Выглядит",[207,1869,1870],{},"Одинаково на iOS и Android",[207,1872,1873],{},"Как родное приложение платформы",[189,1875,1876,1879,1882],{},[207,1877,1878],{},"Кастомизация",[207,1880,1881],{},"Полная",[207,1883,1884],{},"Ограничена нативными возможностями",[189,1886,1887,1890,1893],{},[207,1888,1889],{},"Анимации",[207,1891,1892],{},"Легко, любые",[207,1894,1895],{},"Сложнее, ограничения bridge",[16,1897,1898,1901],{},[37,1899,1900],{},"Когда Flutter лучше:"," уникальный дизайн, брендированные компоненты, игровые интерфейсы.",[16,1903,1904,1907],{},[37,1905,1906],{},"Когда React Native лучше:"," нужно, чтобы выглядело «по-нативному» (как системные настройки iOS).",[54,1909],{},[27,1911,1913],{"id":1912},"экосистема-и-пакеты","Экосистема и пакеты",[69,1915,1918],{"className":1916,"code":1917,"language":74},[72],"Flutter pub.dev:    ~40 000 пакетов\nReact Native npm:   ~1 000 000+ пакетов (весь npm)\n",[76,1919,1917],{"__ignoreMap":78},[16,1921,1922],{},"Звучит как победа RN, но на практике:",[118,1924,1925,1928,1931],{},[121,1926,1927],{},"Flutter-пакеты специально написаны для мобайла",[121,1929,1930],{},"В npm много заброшенного хлама",[121,1932,1933],{},"Flutter pub.dev имеет систему оценки качества пакетов",[16,1935,1936,1939],{},[37,1937,1938],{},"Вывод:"," у Flutter меньше пакетов, но они надёжнее.",[54,1941],{},[27,1943,1945],{"id":1944},"поддержка-платформ","Поддержка платформ",[183,1947,1948,1959],{},[186,1949,1950],{},[189,1951,1952,1955,1957],{},[192,1953,1954],{},"Платформа",[192,1956,1671],{},[192,1958,1677],{},[202,1960,1961,1970,1979,1990,2001],{},[189,1962,1963,1966,1968],{},[207,1964,1965],{},"iOS",[207,1967,1269],{},[207,1969,1269],{},[189,1971,1972,1975,1977],{},[207,1973,1974],{},"Android",[207,1976,1269],{},[207,1978,1269],{},[189,1980,1981,1984,1987],{},[207,1982,1983],{},"Web",[207,1985,1986],{},"✅ (beta)",[207,1988,1989],{},"✅ (через RN Web)",[189,1991,1992,1995,1998],{},[207,1993,1994],{},"Desktop",[207,1996,1997],{},"✅ (Windows\u002FMac\u002FLinux)",[207,1999,2000],{},"❌ ограниченно",[189,2002,2003,2006,2009],{},[207,2004,2005],{},"Telegram Mini App",[207,2007,2008],{},"✅ через WebView",[207,2010,2008],{},[16,2012,2013],{},"Flutter выигрывает по охвату платформ.",[54,2015],{},[27,2017,2019],{"id":2018},"реальные-примеры-больших-приложений","Реальные примеры больших приложений",[16,2021,2022],{},[37,2023,2024],{},"Flutter использует:",[118,2026,2027,2030,2033,2036],{},[121,2028,2029],{},"BMW App",[121,2031,2032],{},"eBay Motors",[121,2034,2035],{},"Google Pay (части)",[121,2037,2038],{},"Alibaba (Xianyu)",[16,2040,2041],{},[37,2042,2043],{},"React Native использует:",[118,2045,2046,2049,2052,2055],{},[121,2047,2048],{},"Facebook",[121,2050,2051],{},"Instagram (частично)",[121,2053,2054],{},"Airbnb (переехали обратно на нативный)",[121,2056,2057],{},"Discord",[54,2059],{},[27,2061,935],{"id":934},[16,2063,2064],{},"Стоимость примерно одинаковая — зависит от сложности, а не фреймворка.",[183,2066,2067,2078],{},[186,2068,2069],{},[189,2070,2071,2074,2076],{},[192,2072,2073],{},"Тип приложения",[192,2075,1671],{},[192,2077,1677],{},[202,2079,2080,2090,2100],{},[189,2081,2082,2085,2088],{},[207,2083,2084],{},"MVP \u002F простое",[207,2086,2087],{},"от $100",[207,2089,2087],{},[189,2091,2092,2095,2098],{},[207,2093,2094],{},"Среднее (авторизация, API, 10+ экранов)",[207,2096,2097],{},"от $300",[207,2099,2097],{},[189,2101,2102,2105,2108],{},[207,2103,2104],{},"Сложное (платежи, real-time, офлайн)",[207,2106,2107],{},"от $800",[207,2109,2107],{},[54,2111],{},[27,2113,1512],{"id":1511},[16,2115,2116,2117,2119],{},"Я использую ",[37,2118,1671],{}," в 90% проектов. Причины:",[285,2121,2122,2128,2134,2139,2145],{},[121,2123,2124,2127],{},[37,2125,2126],{},"Dart"," — строго типизированный, меньше ошибок",[121,2129,2130,2133],{},[37,2131,2132],{},"Виджеты"," — огромный выбор красивых UI-компонентов",[121,2135,2136,2138],{},[37,2137,1160],{}," — стабильная, предсказуемая",[121,2140,2141,2144],{},[37,2142,2143],{},"Один кодбаз"," — iOS, Android, и даже web если нужно",[121,2146,2147,2150],{},[37,2148,2149],{},"Flutter + FastAPI"," — отличная связка для backend-heavy приложений",[16,2152,2153],{},"React Native беру только когда клиент настаивает, или когда уже есть большая JS-кодовая база.",[54,2155],{},[27,2157,2159],{"id":2158},"итоговая-таблица","Итоговая таблица",[183,2161,2162,2173],{},[186,2163,2164],{},[189,2165,2166,2169,2171],{},[192,2167,2168],{},"Критерий",[192,2170,1671],{},[192,2172,1677],{},[202,2174,2175,2185,2193,2203,2212,2222],{},[189,2176,2177,2179,2182],{},[207,2178,1160],{},[207,2180,2181],{},"⭐⭐⭐⭐⭐",[207,2183,2184],{},"⭐⭐⭐⭐",[189,2186,2187,2189,2191],{},[207,2188,1788],{},[207,2190,2184],{},[207,2192,2184],{},[189,2194,2195,2198,2200],{},[207,2196,2197],{},"UI кастомизация",[207,2199,2181],{},[207,2201,2202],{},"⭐⭐⭐",[189,2204,2205,2208,2210],{},[207,2206,2207],{},"Экосистема",[207,2209,2184],{},[207,2211,2181],{},[189,2213,2214,2217,2219],{},[207,2215,2216],{},"Порог входа",[207,2218,2184],{},[207,2220,2221],{},"⭐⭐⭐⭐⭐ (если знаешь JS)",[189,2223,2224,2226,2228],{},[207,2225,1945],{},[207,2227,2181],{},[207,2229,2184],{},[27,2231,316],{"id":315},[16,2233,2234],{},[37,2235,2236],{},"Выбирай Flutter если:",[118,2238,2239,2242,2245],{},[121,2240,2241],{},"Нужен красивый кастомный дизайн",[121,2243,2244],{},"Команда не знает JavaScript",[121,2246,2247],{},"Хочешь покрыть iOS + Android + Web одним кодом",[16,2249,2250],{},[37,2251,2252],{},"Выбирай React Native если:",[118,2254,2255,2258,2261],{},[121,2256,2257],{},"Команда уже знает React",[121,2259,2260],{},"Нужен нативный look & feel платформы",[121,2262,2263],{},"Большая npm-экосистема критична",[16,2265,2266,2267,2269],{},"В большинстве случаев — ",[37,2268,1671],{},". Он моложе, активнее развивается и реже преподносит сюрпризы.",[16,2271,2272,2273,2276],{},"Нужно мобильное приложение? ",[324,2274,2275],{"href":326},"Обсудим"," — подберём правильный стек под вашу задачу.",[1085,2278,1087],{},{"title":78,"searchDepth":330,"depth":330,"links":2280},[2281,2282,2283,2287,2288,2289,2290,2291,2292,2293,2294],{"id":1137,"depth":330,"text":1138},{"id":1159,"depth":330,"text":1160},{"id":1787,"depth":330,"text":1788,"children":2284},[2285,2286],{"id":1791,"depth":336,"text":1677},{"id":1808,"depth":336,"text":1671},{"id":1833,"depth":330,"text":1834},{"id":1912,"depth":330,"text":1913},{"id":1944,"depth":330,"text":1945},{"id":2018,"depth":330,"text":2019},{"id":934,"depth":330,"text":935},{"id":1511,"depth":330,"text":1512},{"id":2158,"depth":330,"text":2159},{"id":315,"depth":330,"text":316},"2024-11-28","Честное сравнение Flutter и React Native: производительность, экосистема, скорость разработки, стоимость. Помогаю выбрать правильный фреймворк под вашу задачу.",{},"\u002Fru\u002Fblog\u002Fflutter-vs-react-native","10 мин",{"title":1645,"description":2296},"flutter-vs-react-native","ru\u002Fblog\u002Fflutter-vs-react-native",[1671,1677,2304,2126,2305],"Mobile","JavaScript","VYQmAsvGpvnAV-SFXBiJZImdLat3TCLkHkHm2SvbYGc",{"id":2308,"title":2309,"body":2310,"date":3104,"description":3105,"extension":349,"meta":3106,"navigation":351,"path":3107,"readTime":3108,"seo":3109,"slug":3110,"stem":3111,"tags":3112,"__hash__":3114},"blogRu\u002Fru\u002Fblog\u002Ftelegram-bot-python-2024.md","Как написать Telegram-бота на Python в 2024 году — полное руководство",{"type":8,"value":2311,"toc":3091},[2312,2316,2323,2329,2333,2363,2367,2370,2384,2388,2421,2424,2430,2434,2496,2500,2588,2592,2658,2662,2754,2758,2830,2834,2878,3015,3019,3072,3076,3083,3088],[11,2313,2315],{"id":2314},"как-написать-telegram-бота-на-python-в-2024-году","Как написать Telegram-бота на Python в 2024 году",[16,2317,2318,2319,2322],{},"Telegram-боты — один из самых быстрых способов автоматизировать бизнес-процессы или создать полноценный продукт. В этой статье я расскажу, как с нуля построить ",[37,2320,2321],{},"production-ready бота"," с базой данных, правильной архитектурой и деплоем.",[16,2324,2325],{},[22,2326],{"alt":2327,"src":2328},"Архитектура Telegram-бота на Aiogram 3","\u002Fimages\u002Fblog\u002Fbot-architecture.svg",[27,2330,2332],{"id":2331},"что-мы-построим","Что мы построим",[118,2334,2335,2342,2348,2354,2360],{},[121,2336,2337,2338,2341],{},"Бот на ",[37,2339,2340],{},"Aiogram 3"," (async, современный API)",[121,2343,2344,2347],{},[37,2345,2346],{},"PostgreSQL"," как хранилище данных",[121,2349,2350,2351],{},"Конфигурация через ",[76,2352,2353],{},".env",[121,2355,2356,2359],{},[37,2357,2358],{},"Docker"," для деплоя",[121,2361,2362],{},"FSM (конечный автомат состояний) для многошаговых сценариев",[27,2364,2366],{"id":2365},"почему-aiogram-3-а-не-python-telegram-bot","Почему Aiogram 3, а не python-telegram-bot",[16,2368,2369],{},"Aiogram 3 — де-факто стандарт для серьёзных ботов на Python:",[118,2371,2372,2375,2378,2381],{},[121,2373,2374],{},"Полностью асинхронный (asyncio)",[121,2376,2377],{},"Роутеры и мидлвары как в FastAPI",[121,2379,2380],{},"Удобный FSM для диалогов",[121,2382,2383],{},"Активная поддержка и хорошая документация",[27,2385,2387],{"id":2386},"установка-и-структура-проекта","Установка и структура проекта",[69,2389,2393],{"className":2390,"code":2391,"language":2392,"meta":78,"style":78},"language-bash shiki shiki-themes github-light github-dark","pip install aiogram==3.* sqlalchemy asyncpg python-dotenv\n","bash",[76,2394,2395],{"__ignoreMap":78},[442,2396,2397,2401,2405,2408,2412,2415,2418],{"class":444,"line":445},[442,2398,2400],{"class":2399},"sScJk","pip",[442,2402,2404],{"class":2403},"sZZnC"," install",[442,2406,2407],{"class":2403}," aiogram==3.",[442,2409,2411],{"class":2410},"sj4cs","*",[442,2413,2414],{"class":2403}," sqlalchemy",[442,2416,2417],{"class":2403}," asyncpg",[442,2419,2420],{"class":2403}," python-dotenv\n",[16,2422,2423],{},"Структура проекта:",[69,2425,2428],{"className":2426,"code":2427,"language":74},[72],"bot\u002F\n├── handlers\u002F\n│   ├── __init__.py\n│   ├── common.py      # \u002Fstart, \u002Fhelp\n│   └── user.py        # пользовательские сценарии\n├── middlewares\u002F\n│   └── database.py    # инжект сессии в хэндлеры\n├── models\u002F\n│   └── user.py        # SQLAlchemy модели\n├── keyboards\u002F\n│   └── reply.py\n├── config.py\n└── main.py\n",[76,2429,2427],{"__ignoreMap":78},[27,2431,2433],{"id":2432},"конфигурация","Конфигурация",[69,2435,2437],{"className":436,"code":2436,"language":438,"meta":78,"style":78},"# config.py\nfrom pydantic_settings import BaseSettings\n\nclass Settings(BaseSettings):\n    BOT_TOKEN: str\n    DATABASE_URL: str\n    ADMIN_ID: int\n\n    class Config:\n        env_file = \".env\"\n\nsettings = Settings()\n",[76,2438,2439,2444,2449,2453,2458,2463,2468,2473,2477,2482,2487,2491],{"__ignoreMap":78},[442,2440,2441],{"class":444,"line":445},[442,2442,2443],{},"# config.py\n",[442,2445,2446],{"class":444,"line":330},[442,2447,2448],{},"from pydantic_settings import BaseSettings\n",[442,2450,2451],{"class":444,"line":336},[442,2452,470],{"emptyLinePlaceholder":351},[442,2454,2455],{"class":444,"line":461},[442,2456,2457],{},"class Settings(BaseSettings):\n",[442,2459,2460],{"class":444,"line":467},[442,2461,2462],{},"    BOT_TOKEN: str\n",[442,2464,2465],{"class":444,"line":473},[442,2466,2467],{},"    DATABASE_URL: str\n",[442,2469,2470],{"class":444,"line":479},[442,2471,2472],{},"    ADMIN_ID: int\n",[442,2474,2475],{"class":444,"line":485},[442,2476,470],{"emptyLinePlaceholder":351},[442,2478,2479],{"class":444,"line":491},[442,2480,2481],{},"    class Config:\n",[442,2483,2484],{"class":444,"line":496},[442,2485,2486],{},"        env_file = \".env\"\n",[442,2488,2489],{"class":444,"line":502},[442,2490,470],{"emptyLinePlaceholder":351},[442,2492,2493],{"class":444,"line":508},[442,2494,2495],{},"settings = Settings()\n",[27,2497,2499],{"id":2498},"основной-файл","Основной файл",[69,2501,2503],{"className":436,"code":2502,"language":438,"meta":78,"style":78},"# main.py\nimport asyncio\nfrom aiogram import Bot, Dispatcher\nfrom aiogram.fsm.storage.memory import MemoryStorage\nfrom handlers import common, user\nfrom config import settings\n\nasync def main():\n    bot = Bot(token=settings.BOT_TOKEN)\n    dp = Dispatcher(storage=MemoryStorage())\n\n    dp.include_router(common.router)\n    dp.include_router(user.router)\n\n    await dp.start_polling(bot)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n",[76,2504,2505,2510,2514,2519,2524,2529,2534,2538,2542,2547,2552,2556,2561,2566,2570,2574,2578,2583],{"__ignoreMap":78},[442,2506,2507],{"class":444,"line":445},[442,2508,2509],{},"# main.py\n",[442,2511,2512],{"class":444,"line":330},[442,2513,448],{},[442,2515,2516],{"class":444,"line":336},[442,2517,2518],{},"from aiogram import Bot, Dispatcher\n",[442,2520,2521],{"class":444,"line":461},[442,2522,2523],{},"from aiogram.fsm.storage.memory import MemoryStorage\n",[442,2525,2526],{"class":444,"line":467},[442,2527,2528],{},"from handlers import common, user\n",[442,2530,2531],{"class":444,"line":473},[442,2532,2533],{},"from config import settings\n",[442,2535,2536],{"class":444,"line":479},[442,2537,470],{"emptyLinePlaceholder":351},[442,2539,2540],{"class":444,"line":485},[442,2541,638],{},[442,2543,2544],{"class":444,"line":491},[442,2545,2546],{},"    bot = Bot(token=settings.BOT_TOKEN)\n",[442,2548,2549],{"class":444,"line":496},[442,2550,2551],{},"    dp = Dispatcher(storage=MemoryStorage())\n",[442,2553,2554],{"class":444,"line":502},[442,2555,470],{"emptyLinePlaceholder":351},[442,2557,2558],{"class":444,"line":508},[442,2559,2560],{},"    dp.include_router(common.router)\n",[442,2562,2563],{"class":444,"line":514},[442,2564,2565],{},"    dp.include_router(user.router)\n",[442,2567,2568],{"class":444,"line":519},[442,2569,470],{"emptyLinePlaceholder":351},[442,2571,2572],{"class":444,"line":525},[442,2573,644],{},[442,2575,2576],{"class":444,"line":531},[442,2577,470],{"emptyLinePlaceholder":351},[442,2579,2580],{"class":444,"line":537},[442,2581,2582],{},"if __name__ == \"__main__\":\n",[442,2584,2585],{"class":444,"line":542},[442,2586,2587],{},"    asyncio.run(main())\n",[27,2589,2591],{"id":2590},"хэндлер-start","Хэндлер \u002Fstart",[69,2593,2595],{"className":436,"code":2594,"language":438,"meta":78,"style":78},"# handlers\u002Fcommon.py\nfrom aiogram import Router\nfrom aiogram.filters import CommandStart\nfrom aiogram.types import Message\n\nrouter = Router()\n\n@router.message(CommandStart())\nasync def cmd_start(message: Message):\n    await message.answer(\n        f\"Привет, {message.from_user.first_name}! 👋\\n\\n\"\n        \"Я помогу тебе автоматизировать твои задачи.\"\n    )\n",[76,2596,2597,2602,2607,2611,2616,2620,2625,2629,2634,2639,2644,2649,2654],{"__ignoreMap":78},[442,2598,2599],{"class":444,"line":445},[442,2600,2601],{},"# handlers\u002Fcommon.py\n",[442,2603,2604],{"class":444,"line":330},[442,2605,2606],{},"from aiogram import Router\n",[442,2608,2609],{"class":444,"line":336},[442,2610,458],{},[442,2612,2613],{"class":444,"line":461},[442,2614,2615],{},"from aiogram.types import Message\n",[442,2617,2618],{"class":444,"line":467},[442,2619,470],{"emptyLinePlaceholder":351},[442,2621,2622],{"class":444,"line":473},[442,2623,2624],{},"router = Router()\n",[442,2626,2627],{"class":444,"line":479},[442,2628,470],{"emptyLinePlaceholder":351},[442,2630,2631],{"class":444,"line":485},[442,2632,2633],{},"@router.message(CommandStart())\n",[442,2635,2636],{"class":444,"line":491},[442,2637,2638],{},"async def cmd_start(message: Message):\n",[442,2640,2641],{"class":444,"line":496},[442,2642,2643],{},"    await message.answer(\n",[442,2645,2646],{"class":444,"line":502},[442,2647,2648],{},"        f\"Привет, {message.from_user.first_name}! 👋\\n\\n\"\n",[442,2650,2651],{"class":444,"line":508},[442,2652,2653],{},"        \"Я помогу тебе автоматизировать твои задачи.\"\n",[442,2655,2656],{"class":444,"line":514},[442,2657,616],{},[27,2659,2661],{"id":2660},"fsm-многошаговые-диалоги","FSM — многошаговые диалоги",[69,2663,2665],{"className":436,"code":2664,"language":438,"meta":78,"style":78},"from aiogram.fsm.context import FSMContext\nfrom aiogram.fsm.state import State, StatesGroup\n\nclass OrderForm(StatesGroup):\n    waiting_name    = State()\n    waiting_phone   = State()\n    waiting_comment = State()\n\n@router.message(Command(\"order\"))\nasync def start_order(message: Message, state: FSMContext):\n    await state.set_state(OrderForm.waiting_name)\n    await message.answer(\"Как вас зовут?\")\n\n@router.message(OrderForm.waiting_name)\nasync def got_name(message: Message, state: FSMContext):\n    await state.update_data(name=message.text)\n    await state.set_state(OrderForm.waiting_phone)\n    await message.answer(\"Укажите номер телефона:\")\n",[76,2666,2667,2672,2677,2681,2686,2691,2696,2701,2705,2710,2715,2720,2725,2729,2734,2739,2744,2749],{"__ignoreMap":78},[442,2668,2669],{"class":444,"line":445},[442,2670,2671],{},"from aiogram.fsm.context import FSMContext\n",[442,2673,2674],{"class":444,"line":330},[442,2675,2676],{},"from aiogram.fsm.state import State, StatesGroup\n",[442,2678,2679],{"class":444,"line":336},[442,2680,470],{"emptyLinePlaceholder":351},[442,2682,2683],{"class":444,"line":461},[442,2684,2685],{},"class OrderForm(StatesGroup):\n",[442,2687,2688],{"class":444,"line":467},[442,2689,2690],{},"    waiting_name    = State()\n",[442,2692,2693],{"class":444,"line":473},[442,2694,2695],{},"    waiting_phone   = State()\n",[442,2697,2698],{"class":444,"line":479},[442,2699,2700],{},"    waiting_comment = State()\n",[442,2702,2703],{"class":444,"line":485},[442,2704,470],{"emptyLinePlaceholder":351},[442,2706,2707],{"class":444,"line":491},[442,2708,2709],{},"@router.message(Command(\"order\"))\n",[442,2711,2712],{"class":444,"line":496},[442,2713,2714],{},"async def start_order(message: Message, state: FSMContext):\n",[442,2716,2717],{"class":444,"line":502},[442,2718,2719],{},"    await state.set_state(OrderForm.waiting_name)\n",[442,2721,2722],{"class":444,"line":508},[442,2723,2724],{},"    await message.answer(\"Как вас зовут?\")\n",[442,2726,2727],{"class":444,"line":514},[442,2728,470],{"emptyLinePlaceholder":351},[442,2730,2731],{"class":444,"line":519},[442,2732,2733],{},"@router.message(OrderForm.waiting_name)\n",[442,2735,2736],{"class":444,"line":525},[442,2737,2738],{},"async def got_name(message: Message, state: FSMContext):\n",[442,2740,2741],{"class":444,"line":531},[442,2742,2743],{},"    await state.update_data(name=message.text)\n",[442,2745,2746],{"class":444,"line":537},[442,2747,2748],{},"    await state.set_state(OrderForm.waiting_phone)\n",[442,2750,2751],{"class":444,"line":542},[442,2752,2753],{},"    await message.answer(\"Укажите номер телефона:\")\n",[27,2755,2757],{"id":2756},"работа-с-базой-данных","Работа с базой данных",[69,2759,2761],{"className":436,"code":2760,"language":438,"meta":78,"style":78},"# models\u002Fuser.py\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\nfrom sqlalchemy import BigInteger, String, DateTime, func\n\nclass Base(DeclarativeBase):\n    pass\n\nclass User(Base):\n    __tablename__ = \"users\"\n\n    id:         Mapped[int]    = mapped_column(BigInteger, primary_key=True)\n    username:   Mapped[str | None] = mapped_column(String(64))\n    first_name: Mapped[str]    = mapped_column(String(128))\n    created_at: Mapped[DateTime] = mapped_column(server_default=func.now())\n",[76,2762,2763,2768,2773,2778,2782,2787,2792,2796,2801,2806,2810,2815,2820,2825],{"__ignoreMap":78},[442,2764,2765],{"class":444,"line":445},[442,2766,2767],{},"# models\u002Fuser.py\n",[442,2769,2770],{"class":444,"line":330},[442,2771,2772],{},"from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\n",[442,2774,2775],{"class":444,"line":336},[442,2776,2777],{},"from sqlalchemy import BigInteger, String, DateTime, func\n",[442,2779,2780],{"class":444,"line":461},[442,2781,470],{"emptyLinePlaceholder":351},[442,2783,2784],{"class":444,"line":467},[442,2785,2786],{},"class Base(DeclarativeBase):\n",[442,2788,2789],{"class":444,"line":473},[442,2790,2791],{},"    pass\n",[442,2793,2794],{"class":444,"line":479},[442,2795,470],{"emptyLinePlaceholder":351},[442,2797,2798],{"class":444,"line":485},[442,2799,2800],{},"class User(Base):\n",[442,2802,2803],{"class":444,"line":491},[442,2804,2805],{},"    __tablename__ = \"users\"\n",[442,2807,2808],{"class":444,"line":496},[442,2809,470],{"emptyLinePlaceholder":351},[442,2811,2812],{"class":444,"line":502},[442,2813,2814],{},"    id:         Mapped[int]    = mapped_column(BigInteger, primary_key=True)\n",[442,2816,2817],{"class":444,"line":508},[442,2818,2819],{},"    username:   Mapped[str | None] = mapped_column(String(64))\n",[442,2821,2822],{"class":444,"line":514},[442,2823,2824],{},"    first_name: Mapped[str]    = mapped_column(String(128))\n",[442,2826,2827],{"class":444,"line":519},[442,2828,2829],{},"    created_at: Mapped[DateTime] = mapped_column(server_default=func.now())\n",[27,2831,2833],{"id":2832},"dockerfile","Dockerfile",[69,2835,2838],{"className":2836,"code":2837,"language":2832,"meta":78,"style":78},"language-dockerfile shiki shiki-themes github-light github-dark","FROM python:3.12-slim\n\nWORKDIR \u002Fapp\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\nCMD [\"python\", \"main.py\"]\n",[76,2839,2840,2845,2849,2854,2859,2864,2868,2873],{"__ignoreMap":78},[442,2841,2842],{"class":444,"line":445},[442,2843,2844],{},"FROM python:3.12-slim\n",[442,2846,2847],{"class":444,"line":330},[442,2848,470],{"emptyLinePlaceholder":351},[442,2850,2851],{"class":444,"line":336},[442,2852,2853],{},"WORKDIR \u002Fapp\n",[442,2855,2856],{"class":444,"line":461},[442,2857,2858],{},"COPY requirements.txt .\n",[442,2860,2861],{"class":444,"line":467},[442,2862,2863],{},"RUN pip install --no-cache-dir -r requirements.txt\n",[442,2865,2866],{"class":444,"line":473},[442,2867,470],{"emptyLinePlaceholder":351},[442,2869,2870],{"class":444,"line":479},[442,2871,2872],{},"COPY . .\n",[442,2874,2875],{"class":444,"line":485},[442,2876,2877],{},"CMD [\"python\", \"main.py\"]\n",[69,2879,2883],{"className":2880,"code":2881,"language":2882,"meta":78,"style":78},"language-yaml shiki shiki-themes github-light github-dark","# docker-compose.yml\nservices:\n  bot:\n    build: .\n    env_file: .env\n    depends_on: [db]\n    restart: unless-stopped\n\n  db:\n    image: postgres:16-alpine\n    env_file: .env\n    volumes:\n      - pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n\nvolumes:\n  pgdata:\n","yaml",[76,2884,2885,2891,2901,2908,2919,2929,2943,2953,2957,2964,2974,2982,2989,2997,3001,3008],{"__ignoreMap":78},[442,2886,2887],{"class":444,"line":445},[442,2888,2890],{"class":2889},"sJ8bj","# docker-compose.yml\n",[442,2892,2893,2897],{"class":444,"line":330},[442,2894,2896],{"class":2895},"s9eBZ","services",[442,2898,2900],{"class":2899},"sVt8B",":\n",[442,2902,2903,2906],{"class":444,"line":336},[442,2904,2905],{"class":2895},"  bot",[442,2907,2900],{"class":2899},[442,2909,2910,2913,2916],{"class":444,"line":461},[442,2911,2912],{"class":2895},"    build",[442,2914,2915],{"class":2899},": ",[442,2917,2918],{"class":2410},".\n",[442,2920,2921,2924,2926],{"class":444,"line":467},[442,2922,2923],{"class":2895},"    env_file",[442,2925,2915],{"class":2899},[442,2927,2928],{"class":2403},".env\n",[442,2930,2931,2934,2937,2940],{"class":444,"line":473},[442,2932,2933],{"class":2895},"    depends_on",[442,2935,2936],{"class":2899},": [",[442,2938,2939],{"class":2403},"db",[442,2941,2942],{"class":2899},"]\n",[442,2944,2945,2948,2950],{"class":444,"line":479},[442,2946,2947],{"class":2895},"    restart",[442,2949,2915],{"class":2899},[442,2951,2952],{"class":2403},"unless-stopped\n",[442,2954,2955],{"class":444,"line":485},[442,2956,470],{"emptyLinePlaceholder":351},[442,2958,2959,2962],{"class":444,"line":491},[442,2960,2961],{"class":2895},"  db",[442,2963,2900],{"class":2899},[442,2965,2966,2969,2971],{"class":444,"line":496},[442,2967,2968],{"class":2895},"    image",[442,2970,2915],{"class":2899},[442,2972,2973],{"class":2403},"postgres:16-alpine\n",[442,2975,2976,2978,2980],{"class":444,"line":502},[442,2977,2923],{"class":2895},[442,2979,2915],{"class":2899},[442,2981,2928],{"class":2403},[442,2983,2984,2987],{"class":444,"line":508},[442,2985,2986],{"class":2895},"    volumes",[442,2988,2900],{"class":2899},[442,2990,2991,2994],{"class":444,"line":514},[442,2992,2993],{"class":2899},"      - ",[442,2995,2996],{"class":2403},"pgdata:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n",[442,2998,2999],{"class":444,"line":519},[442,3000,470],{"emptyLinePlaceholder":351},[442,3002,3003,3006],{"class":444,"line":525},[442,3004,3005],{"class":2895},"volumes",[442,3007,2900],{"class":2899},[442,3009,3010,3013],{"class":444,"line":531},[442,3011,3012],{"class":2895},"  pgdata",[442,3014,2900],{"class":2899},[27,3016,3018],{"id":3017},"деплой-на-vps","Деплой на VPS",[69,3020,3022],{"className":2390,"code":3021,"language":2392,"meta":78,"style":78},"git clone your-repo && cd bot\ncp .env.example .env  # заполнить токены\ndocker compose up -d\n",[76,3023,3024,3044,3058],{"__ignoreMap":78},[442,3025,3026,3029,3032,3035,3038,3041],{"class":444,"line":445},[442,3027,3028],{"class":2399},"git",[442,3030,3031],{"class":2403}," clone",[442,3033,3034],{"class":2403}," your-repo",[442,3036,3037],{"class":2899}," && ",[442,3039,3040],{"class":2410},"cd",[442,3042,3043],{"class":2403}," bot\n",[442,3045,3046,3049,3052,3055],{"class":444,"line":330},[442,3047,3048],{"class":2399},"cp",[442,3050,3051],{"class":2403}," .env.example",[442,3053,3054],{"class":2403}," .env",[442,3056,3057],{"class":2889},"  # заполнить токены\n",[442,3059,3060,3063,3066,3069],{"class":444,"line":336},[442,3061,3062],{"class":2399},"docker",[442,3064,3065],{"class":2403}," compose",[442,3067,3068],{"class":2403}," up",[442,3070,3071],{"class":2410}," -d\n",[27,3073,3075],{"id":3074},"итог","Итог",[16,3077,3078,3079,3082],{},"Правильно выстроенный Telegram-бот — это не просто скрипт с ",[76,3080,3081],{},"if '\u002Fstart'",". Это полноценное приложение с роутерами, мидлварами, базой данных и CI\u002FCD. Aiogram 3 даёт для этого все инструменты.",[16,3084,3085,3086,417],{},"Если нужна помощь с разработкой бота — ",[324,3087,1082],{"href":326},[1085,3089,3090],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":78,"searchDepth":330,"depth":330,"links":3092},[3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103],{"id":2331,"depth":330,"text":2332},{"id":2365,"depth":330,"text":2366},{"id":2386,"depth":330,"text":2387},{"id":2432,"depth":330,"text":2433},{"id":2498,"depth":330,"text":2499},{"id":2590,"depth":330,"text":2591},{"id":2660,"depth":330,"text":2661},{"id":2756,"depth":330,"text":2757},{"id":2832,"depth":330,"text":2833},{"id":3017,"depth":330,"text":3018},{"id":3074,"depth":330,"text":3075},"2024-11-15","Пошаговое руководство по созданию production-ready Telegram-бота с использованием Aiogram 3, PostgreSQL и деплоем на VPS. От нуля до рабочего продукта.",{},"\u002Fru\u002Fblog\u002Ftelegram-bot-python-2024","12 мин",{"title":2309,"description":3105},"telegram-bot-python-2024","ru\u002Fblog\u002Ftelegram-bot-python-2024",[361,359,3113,2346,2358],"Aiogram","lBwm20X1P9p9zLFZ2WkJnAaiGTUTd70JkBt9MXVYfVQ",1781783025978]