Files
site-plata-upravleniya-rf/backup/240700/blog/03-bot-support/index.html
2024-07-24 17:12:33 +03:00

267 lines
48 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"> <head><!-- Global Metadata --><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/svg+xml" href="/favicon/favicon.ico"><meta name="generator" content="Astro v4.7.1"><link rel="preload" href="/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin><link rel="preload" href="/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin><!-- Canonical URL --><link rel="canonical" href="https://astro-sphere-demo.vercel.app/blog/03-bot-support/"><!-- Primary Meta Tags --><title>Хватит терять заявки пользователей | Плата Управления РФ</title><meta name="title" content="Хватит терять заявки пользователей | Плата Управления РФ"><meta name="description" content="Пора сделать бота для принятия заявок от пользователей всем IT отделом."><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:url" content="https://astro-sphere-demo.vercel.app/blog/03-bot-support/"><meta property="og:title" content="Хватит терять заявки пользователей | Плата Управления РФ"><meta property="og:description" content="Пора сделать бота для принятия заявок от пользователей всем IT отделом."><meta property="og:image" content="https://astro-sphere-demo.vercel.app/img04.jpg"><!-- Twitter --><meta property="twitter:card" content="summary_large_image"><meta property="twitter:url" content="https://astro-sphere-demo.vercel.app/blog/03-bot-support/"><meta property="twitter:title" content="Хватит терять заявки пользователей | Плата Управления РФ"><meta property="twitter:description" content="Пора сделать бота для принятия заявок от пользователей всем IT отделом."><meta property="twitter:image" content="https://astro-sphere-demo.vercel.app/img04.jpg"><!-- Sitemap --><link rel="sitemap" href="/sitemap-index.xml"><!-- RSS Feed --><link rel="alternate" type="application/rss+xml" title="Хватит терять заявки пользователей | Плата Управления РФ" href="https://astro-sphere-demo.vercel.app/rss.xml"><!-- Global Scripts --><script src="/js/theme.js"></script><script src="/js/scroll.js"></script><script src="/js/animate.js"></script><!-- <ViewTransitions /> --><link rel="stylesheet" href="/_astro/_slug_.0h5GVtX4.css"><script type="module" src="/_astro/hoisted.BGfjo5mV.js"></script></head> <body> <header id="header" class="fixed top-0 w-full h-16 z-50 " data-astro-cid-3ef6ksr2> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="relative h-full w-full" data-astro-cid-3ef6ksr2> <div class="absolute left-0 top-1/2 -translate-y-1/2 flex gap-1 font-semibold" data-astro-cid-3ef6ksr2> <a href="/" class="flex gap-1 text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out" data-astro-cid-3ef6ksr2> <svg class="size-6 fill-current" data-astro-cid-3ef6ksr2> <use href="/static/logo.svg" data-astro-cid-3ef6ksr2></use> </svg> <div data-astro-cid-3ef6ksr2> Плата Управления РФ </div> </a> </div> <div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" data-astro-cid-3ef6ksr2> <nav class="hidden md:flex items-center justify-center text-sm gap-1" data-astro-cid-3ef6ksr2> <a href="/" class="h-8 rounded-full px-3 text-current flex items-center justify-center transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/20 hover:text-black dark:hover:text-white" data-astro-cid-3ef6ksr2> Главная </a><a href="/work" class="h-8 rounded-full px-3 text-current flex items-center justify-center transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/20 hover:text-black dark:hover:text-white" data-astro-cid-3ef6ksr2> Работа </a><a href="/blog" class="h-8 rounded-full px-3 flex items-center justify-center transition-colors duration-300 ease-in-out bg-black dark:bg-white text-white dark:text-black" data-astro-cid-3ef6ksr2> Блог </a><a href="/projects" class="h-8 rounded-full px-3 text-current flex items-center justify-center transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/20 hover:text-black dark:hover:text-white" data-astro-cid-3ef6ksr2> Проекты </a> </nav> </div> <div class="buttons absolute right-0 top-1/2 -translate-y-1/2 flex gap-1" data-astro-cid-3ef6ksr2> <a href="/search" aria-label="Search blog posts and projects on Плата Управления РФ" class="hidden md:flex size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-3ef6ksr2> <svg class="size-full" data-astro-cid-3ef6ksr2> <use href="/ui.svg#search" data-astro-cid-3ef6ksr2></use> </svg> </a> <a href="/rss.xml" target="_blank" aria-label="Rss feed for Плата Управления РФ" class="hidden md:flex size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-3ef6ksr2> <svg class="size-full" data-astro-cid-3ef6ksr2> <use href="/ui.svg#rss" data-astro-cid-3ef6ksr2></use> </svg> </a> <button id="header-theme-button" aria-label="Toggle light and dark theme" class="hidden md:flex size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-3ef6ksr2> <svg class="size-full block dark:hidden" data-astro-cid-3ef6ksr2> <use href="/ui.svg#sun" data-astro-cid-3ef6ksr2></use> </svg> <svg class="size-full hidden dark:block" data-astro-cid-3ef6ksr2> <use href="/ui.svg#moon" data-astro-cid-3ef6ksr2></use> </svg> </button> <button id="header-drawer-button" aria-label="Toggle drawer open and closed" class="flex md:hidden size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-3ef6ksr2> <svg id="drawer-open" class="size-full" data-astro-cid-3ef6ksr2> <use href="/ui.svg#menu" data-astro-cid-3ef6ksr2></use> </svg> <svg id="drawer-close" class="size-full" data-astro-cid-3ef6ksr2> <use href="/ui.svg#x" data-astro-cid-3ef6ksr2></use> </svg> </button> </div> </div> </div> </header> <script>
function toggleDrawer() {
const drawer = document.getElementById("drawer")
const drawerButton = document.getElementById("header-drawer-button")
drawer?.classList.toggle("open")
drawerButton?.classList.toggle("open")
}
function initializeDrawerButton() {
const drawerButton = document.getElementById("header-drawer-button")
drawerButton?.addEventListener("click", toggleDrawer)
}
document.addEventListener("astro:after-swap", initializeDrawerButton)
initializeDrawerButton()
</script> <div id="drawer" class="fixed inset-0 h-0 z-40 overflow-hidden flex flex-col items-center justify-center md:hidden bg-neutral-100 dark:bg-neutral-900 transition-[height] duration-300 ease-in-out" data-astro-cid-hxtyo74s> <nav class="flex flex-col items-center space-y-2" data-astro-cid-hxtyo74s> <a href="/" class="flex items-center justify-center px-3 py-1 rounded-full text-current hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/20 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> Главная </a><a href="/work" class="flex items-center justify-center px-3 py-1 rounded-full text-current hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/20 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> Работа </a><a href="/blog" class="flex items-center justify-center px-3 py-1 rounded-full hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/20 transition-colors duration-300 ease-in-out pointer-events-none bg-black dark:bg-white text-white dark:text-black" data-astro-cid-hxtyo74s> Блог </a><a href="/projects" class="flex items-center justify-center px-3 py-1 rounded-full text-current hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/20 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> Проекты </a> </nav> <div class="flex gap-1 mt-5" data-astro-cid-hxtyo74s> <a href="/search" aria-label="Search blog posts and projects on Плата Управления РФ" class="size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> <svg class="size-full" data-astro-cid-hxtyo74s> <use href="/ui.svg#search" data-astro-cid-hxtyo74s></use> </svg> </a> <a href="/rss.xml" target="_blank" aria-label="Rss feed for Плата Управления РФ" class="size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> <svg class="size-full" data-astro-cid-hxtyo74s> <use href="/ui.svg#rss" data-astro-cid-hxtyo74s></use> </svg> </a> <button id="drawer-theme-button" aria-label="Toggle light and dark theme" class="size-9 rounded-full p-2 items-center justify-center bg-transparent hover:bg-black/5 dark:hover:bg-white/20 stroke-current hover:stroke-black hover:dark:stroke-white border border-black/10 dark:border-white/25 transition-colors duration-300 ease-in-out" data-astro-cid-hxtyo74s> <svg class="block dark:hidden size-full" data-astro-cid-hxtyo74s> <use href="/ui.svg#sun" data-astro-cid-hxtyo74s></use> </svg> <svg class="hidden dark:block size-full" data-astro-cid-hxtyo74s> <use href="/ui.svg#moon" data-astro-cid-hxtyo74s></use> </svg> </button> </div> </div> <main> <div class="pt-36 pb-5"> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="animate"> <div> <a href="/blog" class="group w-fit p-1.5 gap-1.5 text-sm flex items-center border rounded hover:bg-black/5 hover:dark:bg-white/10 border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="stroke-current group-hover:stroke-black group-hover:dark:stroke-white"> <line x1="19" y1="12" x2="5" y2="12" class="scale-x-0 group-hover:scale-x-100 translate-x-3 group-hover:translate-x-0 transition-all duration-300 ease-in-out"></line> <polyline points="12 19 5 12 12 5" class="translate-x-1 group-hover:translate-x-0 transition-all duration-300 ease-in-out"></polyline> </svg> <div class="w-full group-hover:text-black group-hover:dark:text-white transition-colors duration-300 ease-in-out">
Вернуться в blog </div> </a> <div class="flex flex-wrap text-sm uppercase mt-12 gap-3 opacity-75"> <div class="flex items-center gap-2"> <svg class="size-5 stroke-current"> <use href="/ui.svg#calendar"></use> </svg> 12 июн. 2024 г. </div> <div class="flex items-center gap-2"> <svg class="size-5 stroke-current"> <use href="/ui.svg#book-open"></use> </svg> 6 min read </div> </div> <h1 class="text-3xl font-semibold text-black dark:text-white mt-2"> Хватит терять заявки пользователей </h1> <div class="mt-1"> Пора сделать бота для принятия заявок от пользователей всем IT отделом. </div> </div> </div> </div> </div> <div class="flex-1 py-5"> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="animate"> <div> <article> <h1 id="бот-техподдержки-пользователя">Бот техподдержки пользователя</h1>
<p><a href="https://git.fipi.pro/Plata_Upravleniya_RF/Support-BOT">https://git.fipi.pro/Plata_Upravleniya_RF/Support-BOT</a></p>
<p>Пользователи пишут свои вопросы боту компании, бот пересылает эти сообщения в чат поддержки, сотрудники поддержки отвечают на эти сообщения через reply. Основной плюс - анонимизация сотрудников поддержки.</p>
<p>Бот работает в режиме webhook, но может работать и в режиме polling.</p>
<p>Для обхода запрета на пересылку сообщений у пользователя, бот копирует содержимое и уже затем отправляет его в чат поддержки.</p>
<p>По умолчанию бот отправляет сообщения в один чат поддержки с id, указанным в переменных окружения .env.</p>
<h2 id="бот-умеет">Бот умеет</h2>
<ul>
<li>Пересылать сообщения, документы, аудио и видео от пользователя в группу к администраторам и обратно</li>
<li>Выдавать информацию о пользователе из Telegram</li>
<li>Выдавать месячный отчет и отчет за указанный интервал дат по количеству обращений и общему числу сообщений и ответов</li>
<li>Банить и разбанивать пользователей</li>
</ul>
<h2 id="типы-контента-которые-может-пересылать-бот">Типы контента, которые может пересылать бот</h2>
<ul>
<li>Текстовые сообщения</li>
<li>Фотографии</li>
<li>Группы фотографий (пересылаются по одной)</li>
<li>Видео</li>
<li>Аудиозаписи</li>
<li>Файлы</li>
</ul>
<h2 id="разворачивание-образа-на-личном-или-vps-сервере">Разворачивание образа на личном или vps сервере</h2>
<h3 id="настройка-nignx">Настройка Nignx</h3>
<p>Предполагается, что у вас есть готовый настроенный VPS сервер с установленным nginx.</p>
<ol>
<li>Перейти в каталог nginx <code>sites-available</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#79B8FF">cd</span><span style="color:#9ECBFF"> /etc/nginx/sites-available/</span></span>
<span class="line"></span></code></pre>
<ol start="2">
<li>Создайте файл с именем вашего домена:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">nano</span><span style="color:#9ECBFF"> domain.example.com</span></span>
<span class="line"></span></code></pre>
<ol start="3">
<li>Внутри файла напишите:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">server</span><span style="color:#9ECBFF"> {</span></span>
<span class="line"><span style="color:#B392F0"> listen</span><span style="color:#79B8FF"> 80</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0"> server_name</span><span style="color:#9ECBFF"> domain.example.com</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0"> location</span><span style="color:#9ECBFF"> /telegram/</span><span style="color:#9ECBFF"> {</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> Host</span><span style="color:#E1E4E8"> $http_host;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Real-IP</span><span style="color:#E1E4E8"> $remote_addr;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Forwarded-For</span><span style="color:#E1E4E8"> $proxy_add_x_forwarded_for;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_set_header</span><span style="color:#9ECBFF"> X-Forwarded-Proto</span><span style="color:#E1E4E8"> $scheme;</span></span>
<span class="line"><span style="color:#B392F0"> proxy_pass</span><span style="color:#9ECBFF"> http://127.0.0.1:7772</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"></span></code></pre>
<p><code>server_name</code> - ваш домен с подключенным SSL сертификатом (например, Lets Encrypt). Вместо <code>/telegram/</code> можно написать любой путь, на который должны приниматься данные. Этот же путь нужно указать в <code>.env</code> файле.</p>
<ol start="4">
<li>Создайте символическую ссылку в каталоге <code>sites-enabled</code></li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> ln</span><span style="color:#79B8FF"> -s</span><span style="color:#9ECBFF"> /etc/nginx/sites-available/domain.example.com</span><span style="color:#9ECBFF"> /etc/nginx/sites-enabled/</span></span>
<span class="line"></span></code></pre>
<ol start="5">
<li>Проверьте конфигурацию nginx на ошибки:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> nginx</span><span style="color:#79B8FF"> -t</span></span>
<span class="line"></span></code></pre>
<ol start="6">
<li>Перезапустить службу nginx:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> systemctl</span><span style="color:#9ECBFF"> restart</span><span style="color:#9ECBFF"> nginx</span></span>
<span class="line"></span></code></pre>
<ol start="7">
<li>Установить certbot:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> apt</span><span style="color:#9ECBFF"> install</span><span style="color:#79B8FF"> -y</span><span style="color:#9ECBFF"> certbot</span><span style="color:#9ECBFF"> python3-certbot-nginx</span></span>
<span class="line"></span></code></pre>
<ol start="8">
<li>Установите HTTPS соединение, выпустив SSL сертификат с помощью certbot для вашего домена:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> certbot</span><span style="color:#79B8FF"> --nginx</span><span style="color:#E1E4E8"> </span></span>
<span class="line"></span></code></pre>
<ol start="9">
<li>Добавить автоматическое обновление сертификата:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> certbot</span><span style="color:#9ECBFF"> renew</span><span style="color:#79B8FF"> --dry-run</span></span>
<span class="line"></span></code></pre>
<p>Можно на всякий случай еще раз перезапустить nginx.</p>
<h3 id="запуск-бота">Запуск бота</h3>
<ol>
<li>Создайте бота через BotFather (см. ниже), добавьте бота в группу с сотрудниками поддержки, дайте боту права администратора, узнайте id группы (см. ниже).</li>
<li>Скопируйте этот репозиторий на сервер любым удобным способом.</li>
<li>Создайте .env файл в корне со следующим содержанием:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#E1E4E8">TELEGRAM_TOKEN</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">телеграм_токен_вашего_бота</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#E1E4E8">GROUP_ID</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">id_группы_или_супергруппы_в_телеграме</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#E1E4E8">WEBHOOK_DOMAIN</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">domain.example.com</span></span>
<span class="line"><span style="color:#E1E4E8">WEBHOOK_PATH</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">/telegram/</span></span>
<span class="line"><span style="color:#E1E4E8">APP_HOST</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">0.0.0.0</span></span>
<span class="line"><span style="color:#E1E4E8">APP_PORT</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">7772</span></span>
<span class="line"><span style="color:#E1E4E8">DATABASE_URL</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">postgresql+asyncpg://</span><span style="color:#F97583">&#x3C;</span><span style="color:#9ECBFF">postgres_user</span><span style="color:#F97583">></span><span style="color:#9ECBFF">:</span><span style="color:#F97583">&#x3C;</span><span style="color:#9ECBFF">postgres_password</span><span style="color:#F97583">></span><span style="color:#9ECBFF">@</span><span style="color:#F97583">&#x3C;</span><span style="color:#9ECBFF">postgres_container_name</span><span style="color:#F97583">></span><span style="color:#9ECBFF">:5432/support_bot_db</span></span>
<span class="line"><span style="color:#E1E4E8">DB_HOST</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">имя_контейнера_с_БД</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#E1E4E8">DB_PORT</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">5432</span></span>
<span class="line"><span style="color:#E1E4E8">POSTGRES_USER</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">postgres_user</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#E1E4E8">POSTGRES_PASSWORD</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">postgres_password</span><span style="color:#F97583">></span></span>
<span class="line"><span style="color:#E1E4E8">START_MESSAGE</span><span style="color:#F97583">=&#x3C;</span><span style="color:#9ECBFF">Приветственное</span><span style="color:#B392F0"> сообщение</span><span style="color:#9ECBFF"> бота,</span><span style="color:#9ECBFF"> когда</span><span style="color:#9ECBFF"> клиент</span><span style="color:#9ECBFF"> нажимает</span><span style="color:#9ECBFF"> кнопку</span><span style="color:#9ECBFF"> star</span><span style="color:#E1E4E8">t</span><span style="color:#F97583">></span></span>
<span class="line"></span></code></pre>
<p>В качестве теста логин пользователя БД, пароль и название БД можно указать postgres. Только для теста, не для продакшена!</p>
<ol start="4">
<li>Запустить сборку docker-образа и его запуск из файла <code>docker-compose</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> docker-compose</span><span style="color:#9ECBFF"> up</span><span style="color:#79B8FF"> -d</span><span style="color:#79B8FF"> --build</span></span>
<span class="line"></span></code></pre>
<p>Ключ <code>-d</code> для того чтобы контейнер запустился в фоне.</p>
<ol start="5">
<li>Зайдите в контейнер с базой данных, создайте базу данных, выдайте права на нее пользователю (в данном случае postgres):</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">docker</span><span style="color:#9ECBFF"> exec</span><span style="color:#79B8FF"> -it</span><span style="color:#9ECBFF"> support-bot-db</span><span style="color:#9ECBFF"> psql</span><span style="color:#79B8FF"> -U</span><span style="color:#9ECBFF"> postgres</span></span>
<span class="line"><span style="color:#B392F0">\l</span><span style="color:#6A737D"> #убеждаемся, что базы данных нет</span></span>
<span class="line"><span style="color:#B392F0">create</span><span style="color:#9ECBFF"> database</span><span style="color:#9ECBFF"> support_bot_db</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0">grant</span><span style="color:#9ECBFF"> all</span><span style="color:#9ECBFF"> privileges</span><span style="color:#9ECBFF"> on</span><span style="color:#9ECBFF"> database</span><span style="color:#9ECBFF"> support_bot_db</span><span style="color:#9ECBFF"> to</span><span style="color:#9ECBFF"> postgres</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0">\q</span><span style="color:#6A737D"> #выходим из psql</span></span>
<span class="line"></span></code></pre>
<ol start="6">
<li>Применить миграции:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">docker</span><span style="color:#9ECBFF"> exec</span><span style="color:#79B8FF"> -it</span><span style="color:#9ECBFF"> support-bot</span><span style="color:#9ECBFF"> alembic</span><span style="color:#9ECBFF"> upgrade</span><span style="color:#9ECBFF"> head</span></span>
<span class="line"></span></code></pre>
<h3 id="где-что-брать">Где что брать</h3>
<ol>
<li><code>WEBHOOK_DOMAIN</code> - домен с подключенным ssl сертификатом</li>
<li><code>WEBHOOK_PATH</code> - URL путь после домена. В данном случае <code>WEBHOOK_DOMAIN</code> + <code>WEBHOOK_PATH</code> будет <code>domain.example.com/telegram/</code>.</li>
<li>Token получаем при создании бота через BotFather <a href="https://t.me/BotFather">BotFather</a>.</li>
<li>Свой личный id или id группы можно узнать через бота <a href="https://t.me/myidbot">myidbot</a>. Узнать свой id - написать боту в личку, узнать id группы - добавить бота в чат группы (например группы поддержки), затем ввести команду <code>/getgroupid</code>.</li>
<li><code>APP_HOST</code> - IP, на котором будет работать приложение (по умолчанию на хосте <code>127.0.0.1</code>, <code>localhost</code> или можно указать <code>0.0.0.0</code>).</li>
<li><code>APP_PORT</code> - порт, который приложение будет использовать. Порт должен быть уникальным и не дублировать порты других приложений, работающих на сервере или в Docker.</li>
</ol>
<h2 id="запуск-в-режиме-polling-на-локальном-компьютере">Запуск в режиме polling (на локальном компьютере)</h2>
<ol>
<li>Скопируйте репозиторий на локальный компьютер.</li>
<li>Создайте файл <code>.env</code> (см. выше).</li>
<li>В файле <code>.env</code> удалить (закомментировать) <code>WEBHOOK_DOMAIN</code>. Пропишите свои переменные окружения. Так же пропишите переменные окружения в файле <code>docker-compose-postgres-localhost.yaml</code></li>
<li>Установить виртуальное окружение, активировать его,
установить зависимости из <code>requirements.txt</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">python</span><span style="color:#79B8FF"> -m</span><span style="color:#9ECBFF"> venv</span><span style="color:#9ECBFF"> venv</span></span>
<span class="line"><span style="color:#B392F0">pip</span><span style="color:#9ECBFF"> install</span><span style="color:#79B8FF"> -r</span><span style="color:#9ECBFF"> requirements.txt</span></span>
<span class="line"></span></code></pre>
<ol start="5">
<li>В докере запустить контейнер с базой данных из файла <code>docker-compose-postgres-localhost.yaml</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">docker-compose</span><span style="color:#79B8FF"> -f</span><span style="color:#9ECBFF"> docker-compose-postgres-localhost</span><span style="color:#9ECBFF"> up</span><span style="color:#79B8FF"> -d</span></span>
<span class="line"></span></code></pre>
<ol start="6">
<li>Применить миграцию.</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">alembic</span><span style="color:#9ECBFF"> upgrade</span><span style="color:#9ECBFF"> head</span></span>
<span class="line"></span></code></pre>
<ol start="7">
<li>Если alembic ругается, что базы данных не существует, создайте ее вручную и выйдите из psql. Затем попробуйте выполнить миграцию повторно:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">docker</span><span style="color:#9ECBFF"> exec</span><span style="color:#79B8FF"> -it</span><span style="color:#9ECBFF"> postgres</span><span style="color:#9ECBFF"> psql</span><span style="color:#79B8FF"> -U</span><span style="color:#9ECBFF"> postgres</span></span>
<span class="line"><span style="color:#6A737D"># далее в psql</span></span>
<span class="line"><span style="color:#B392F0">create</span><span style="color:#9ECBFF"> database</span><span style="color:#9ECBFF"> support_bot_db</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#B392F0">grant</span><span style="color:#9ECBFF"> all</span><span style="color:#9ECBFF"> privileges</span><span style="color:#9ECBFF"> on</span><span style="color:#9ECBFF"> database</span><span style="color:#9ECBFF"> support_bot_db</span><span style="color:#9ECBFF"> to</span><span style="color:#9ECBFF"> postgres</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span></code></pre>
<ol start="8">
<li>Запустить <code>main.py</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">python</span><span style="color:#9ECBFF"> main.py</span></span>
<span class="line"></span></code></pre>
<p>Для запуска необходим python 3.9 или выше.</p>
<h2 id="команды-бота">Команды бота</h2>
<p>В <strong>чате поддержки</strong> доступны следующие команды:</p>
<p><code>/info</code> - Команда вводится через reply на вопрос пользователя и выдает информацию о нем (имя, фамилия, id, никнейм, а также количество сообщений от пользователя и ответов пользователю. Последние два берутся из созданной базы данных).</p>
<p><code>/report</code> - Отчет по количеству клиентов за месяц, сообщений от них и количество ответов администраторов.</p>
<p><code>/report 01.01.2020 15.06.2024</code> - Отчет за выбранный период. Две любые даты через пробел, по шаблону.</p>
<p><code>/ban</code> - Команда вводится через reply на вопрос пользователя. Банит пользователя. Сообщения от него будут игнорироваться ботом.
<code>/unban</code> - Команда вводится через reply на вопрос пользователя. Разбанивает пользователя.</p>
<p><code>/banlist</code> - Список забаненных пользователей. Выводит список пользователей в формате <code>id - имя_фамилия</code>.</p>
<p><code>/registeradmin</code> - Регистрирует нового администратора в чате поддержки. Также администратор регистрируется автоматически, если ответит на сообщение клиента через reply. Это сделано на случай, если забыли зарегистрировать администратора, а он уже отвечает на сообщения.</p>
<p><code>/deleteadmin</code> - Удаляет права администратора у пользователя в чате поддержки. После удаления прав администратора нужно вручную удалить пользователя из группы Telegram.</p>
<h2 id="автозапуск-бота">Автозапуск бота</h2>
<ol>
<li>Создание службы:
Создайте файл службы для вашего бота, например <code>my_bot.service</code>:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> nano</span><span style="color:#9ECBFF"> /etc/systemd/system/my_bot.service</span></span>
<span class="line"></span></code></pre>
<ol start="2">
<li>Редактирование службы:
Внесите следующие настройки в файл службы:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#E1E4E8">[Unit]</span></span>
<span class="line"><span style="color:#E1E4E8">Description</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">My</span><span style="color:#B392F0"> Python</span><span style="color:#9ECBFF"> Telegram</span><span style="color:#9ECBFF"> Bot</span></span>
<span class="line"><span style="color:#E1E4E8">After</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">network.target</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">[Service]</span></span>
<span class="line"><span style="color:#E1E4E8">User</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">your_username</span></span>
<span class="line"><span style="color:#E1E4E8">Group</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">your_groupname</span></span>
<span class="line"><span style="color:#E1E4E8">WorkingDirectory</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">/path/to/your/bot</span></span>
<span class="line"><span style="color:#E1E4E8">ExecStart</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">/path/to/your/python</span><span style="color:#B392F0"> /path/to/your/bot/main.py</span></span>
<span class="line"><span style="color:#E1E4E8">Restart</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">always</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">[Install]</span></span>
<span class="line"><span style="color:#E1E4E8">WantedBy</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">multi-user.target</span></span>
<span class="line"></span></code></pre>
<p>Замените <code>your_username</code>, <code>your_groupname</code>, <code>/path/to/your/bot</code>, и <code>/path/to/your/python</code> на соответствующие значения для вашей среды. Убедитесь, что <code>ExecStart</code> указывает на правильный путь к вашему скрипту Python бота.</p>
<ol start="3">
<li>Перезагрузка systemd:
После того как вы сохранили изменения, перезагрузите systemd для применения новой службы:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> systemctl</span><span style="color:#9ECBFF"> daemon-reload</span></span>
<span class="line"></span></code></pre>
<ol start="4">
<li>Управление службой:
Теперь вы можете управлять вашим ботом как службой. Например, чтобы запустить его и настроить автозапуск при загрузке системы, выполните следующие команды:</li>
</ol>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> systemctl</span><span style="color:#9ECBFF"> start</span><span style="color:#9ECBFF"> my_bot</span></span>
<span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> systemctl</span><span style="color:#9ECBFF"> enable</span><span style="color:#9ECBFF"> my_bot</span></span>
<span class="line"></span></code></pre>
<p>Чтобы проверить статус вашей службы, выполните:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="sh"><code><span class="line"><span style="color:#B392F0">sudo</span><span style="color:#9ECBFF"> systemctl</span><span style="color:#9ECBFF"> status</span><span style="color:#9ECBFF"> my_bot</span></span>
<span class="line"></span></code></pre> </article> <div class="grid grid-cols-1 sm:grid-cols-2 gap-4"> <a href="/blog/04-office-2021" class="group p-4 gap-3 flex items-center border rounded-lg hover:bg-black/5 hover:dark:bg-white/10 border-black/15 dark:border-white/20 blend"> <div class="order-2 w-full h-full group-hover:text-black group-hover:dark:text-white blend"> <div class="flex flex-wrap gap-2"> <div class="text-sm uppercase">
Prev
</div> </div> <div class="font-semibold mt-3 text-black dark:text-white"> Установливаем последний Microsoft Office с официального сайта. </div> </div> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="order-1 stroke-current group-hover:stroke-black group-hover:dark:stroke-white rotate-180"> <line x1="5" y1="12" x2="19" y2="12" class="scale-x-0 group-hover:scale-x-100 translate-x-4 group-hover:translate-x-1 transition-all duration-300 ease-in-out"></line> <polyline points="12 5 19 12 12 19" class="translate-x-0 group-hover:translate-x-1 transition-all duration-300 ease-in-out"></polyline> </svg> </a> <a href="/blog/05-zabbix-api" class="group p-4 gap-3 flex items-center border rounded-lg hover:bg-black/5 hover:dark:bg-white/10 border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out"> <div class="w-full h-full text-right group-hover:text-black group-hover:dark:text-white blend"> <div class="text-sm uppercase">
Next
</div> <div class="font-semibold mt-3 text-black dark:text-white"> Групповые политики GPO для Zabbix Agent с использованием магии API </div> </div> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="stroke-current group-hover:stroke-black group-hover:dark:stroke-white"> <line x1="5" y1="12" x2="19" y2="12" class="scale-x-0 group-hover:scale-x-100 translate-x-4 group-hover:translate-x-1 transition-all duration-300 ease-in-out"></line> <polyline points="12 5 19 12 12 19" class="translate-x-0 group-hover:translate-x-1 transition-all duration-300 ease-in-out"></polyline> </svg> </a> </div> </div> </div> </div> </div> </main> <footer class="relative bg-white dark:bg-black"> <div class="animate"> <section class="py-5"> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="flex items-center justify-center sm:justify-end"> <button id="back-to-top" aria-label="Back to top of page" class="group flex w-fit p-1.5 gap-1.5 text-sm items-center border rounded hover:bg-black/5 hover:dark:bg-white/10 border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="stroke-current group-hover:stroke-black group-hover:dark:stroke-white rotate-90"> <line x1="19" y1="12" x2="5" y2="12" class="scale-x-0 group-hover:scale-x-100 translate-x-3 group-hover:translate-x-0 transition-all duration-300 ease-in-out"></line> <polyline points="12 19 5 12 12 5" class="translate-x-1 group-hover:translate-x-0 transition-all duration-300 ease-in-out"></polyline> </svg> <div class="w-full group-hover:text-black group-hover:dark:text-white transition-colors duration-300 ease-in-out">
В начало
</div> </button> </div> </div> </section> <section class=" py-5 overflow-hidden whitespace-nowrap border-t border-black/10 dark:border-white/25"> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-3"> <div class="flex flex-col items-center sm:items-start"> <a href="/" class="flex gap-1 w-fit font-semibold text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out"> <svg class="size-6 fill-current"> <use href="/brand.svg#brand"></use> </svg> Плата Управления РФ </a> </div> <div class="flex gap-2 justify-center sm:justify-end items-center"> <span class="relative flex h-3 w-3"> <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-300"></span> <span class="relative inline-flex rounded-full h-3 w-3 bg-green-500"></span> </span>
Все системы в норме
</div> </div> </div> </section> <section class=" py-5 overflow-hidden whitespace-nowrap border-t border-black/10 dark:border-white/25"> <div class="w-full h-full mx-auto px-5 max-w-screen-md"> <div class="h-full grid grid-cols-1 sm:grid-cols-2 gap-3"> <div class="order-2 sm:order-1 flex flex-col items-center justify-center sm:items-start"> <div class="legal"> <a href="/legal/terms" class="text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out">
Условия использования
</a> |
<a href="/legal/privacy" class="text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out">
Конфиденциальности
</a> </div> <div class="text-sm mt-2">
&copy; 2024 | @iTKeyS
</div> </div> <div class="order-1 sm:order-2 flex justify-center sm:justify-end"> <div class="flex flex-wrap gap-1 items-center justify-center"> <a href="mailto:krasilnikoff.tihon@gmail.com" target="_blank" aria-label="Плата Управления РФ on Email" class="group size-10 rounded-full p-2 items-center justify-center hover:bg-black/5 dark:hover:bg-white/20 blend"> <svg class="size-full fill-current group-hover:fill-black group-hover:dark:fill-white blend"> <use href="/social.svg#email"></use> </svg> </a><a href="https://git.fipi.pro/Plata_Upravleniya_RF" target="_blank" aria-label="Плата Управления РФ on Github" class="group size-10 rounded-full p-2 items-center justify-center hover:bg-black/5 dark:hover:bg-white/20 blend"> <svg class="size-full fill-current group-hover:fill-black group-hover:dark:fill-white blend"> <use href="/social.svg#github"></use> </svg> </a><a href="https://www.youtube.com/@plata_upravleniya_rf" target="_blank" aria-label="Плата Управления РФ on YouTube" class="group size-10 rounded-full p-2 items-center justify-center hover:bg-black/5 dark:hover:bg-white/20 blend"> <svg class="size-full fill-current group-hover:fill-black group-hover:dark:fill-white blend"> <use href="/social.svg#youtube"></use> </svg> </a><a href="https://t.me/plata_upravleniya_rf" target="_blank" aria-label="Плата Управления РФ on Telegram" class="group size-10 rounded-full p-2 items-center justify-center hover:bg-black/5 dark:hover:bg-white/20 blend"> <svg class="size-full fill-current group-hover:fill-black group-hover:dark:fill-white blend"> <use href="/social.svg#telegram"></use> </svg> </a><a href="https://t.me/plata_upravleniya_rf_bot" target="_blank" aria-label="Плата Управления РФ on Telegram BOT" class="group size-10 rounded-full p-2 items-center justify-center hover:bg-black/5 dark:hover:bg-white/20 blend"> <svg class="size-full fill-current group-hover:fill-black group-hover:dark:fill-white blend"> <use href="/social.svg#telegram"></use> </svg> </a> </div> </div> </div> </div> </section> </div> </footer> <script>
function goBackToTop(event) {
event.preventDefault()
window.scrollTo({
top: 0,
behavior: "smooth"
})
}
function inintializeBackToTop() {
const backToTop = document.getElementById("back-to-top")
backToTop?.addEventListener("click", goBackToTop)
}
document.addEventListener("astro:after-swap", inintializeBackToTop)
inintializeBackToTop()
</script> </body></html>