У меня есть небольшой пет-проект по созданию нейропсихолога - канала в Телеграмм, публикующего посты по психологии семейных взаимоотношений и саморазвитию человека. Особенностью этого канала является то, что посты для этого канала, как и план выхода постов, составляет нейронная сеть самостоятельно, без вмешательства человека - мною был задан только вектор постов, а дальше уже дело техники. На первом этапе был сформирован CSV-файл с постами до конца лета 2025-го года. В дальнейшем буду по мере возможности развивать функционал так, чтобы посты создавались без прослойки из CSV, а сразу, в одном месте, через API нейросети, добавлю еще какой-то полезный функционал...

Данный пост показывает простейший пример бота, который заполняет базу из CSV-файла и публикует их по расписанию.

Введение

В этой статье я расскажу, как мы создали систему для автоматической публикации постов в Telegram-канал по расписанию. Решение включает:

  • Docker-контейнер с PostgreSQL базой данных
  • Python-бота для отправки сообщений
  • Систему загрузки контента из CSV-файлов
  • Поддержку Markdown-разметки в сообщениях

1. Архитектура решения

Наша система состоит из трех основных компонентов:

1.1 База данных (PostgreSQL)

Хранит все посты с их расписанием и статусом отправки.

CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    post_date TIMESTAMP WITH TIME ZONE NOT NULL,
    message TEXT NOT NULL,
    is_sent BOOLEAN DEFAULT FALSE,
    sent_at TIMESTAMP WITH TIME ZONE
);

1.2 Telegram-бот

Проверяет базу данных каждые 10 минут и отправляет посты, время публикации которых наступило.

1.3 Админка (Adminer)

Веб-интерфейс для просмотра и управления базой данных.

2. Настройка окружения

2.1 Установка Docker

Для работы системы требуется Docker и Docker Compose.

# Для Ubuntu/Debian
sudo apt update
sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker

2.2 Структура проекта

Создайте следующую структуру файлов:

telegram-post-bot/
├── docker-compose.yml
├── Dockerfile
├── .env
├── init.sql
├── requirements.txt
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── config.py
│   ├── database.py
│   └── async_utils.py
└── data/
    └── posts.csv

3. Конфигурационные файлы

3.1 docker-compose.yml

version: '3.8'

services:
  db:
    image: postgres:16
    env_file: .env
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  adminer:
    image: adminer:latest
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy

  bot:
    build: .
    env_file: .env
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

volumes:
  postgres_data:

3.2 Dockerfile

FROM python:3.11

WORKDIR /app

RUN apt-get update && apt-get install -y tzdata && \
    ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "-m", "app.main"]

3.3 requirements.txt

python-telegram-bot==20.3
psycopg2-binary==2.9.9
python-dotenv==1.0.0
pandas==2.0.3
python-dateutil==2.8.2

4. Основной код бота

4.1 Отправка сообщений (async_utils.py)

import asyncio
import re
from telegram import Bot
from telegram.constants import ParseMode
import logging

logger = logging.getLogger(__name__)

def escape_markdown(text):
    escape_chars = r'\_*[]()~`>#+-=|{}.!'
    return re.sub(f'([{re.escape(escape_chars)}])', r'\\\1', text)

async def async_send_message(bot_token, chat_id, text):
    bot = Bot(token=bot_token)
    try:
        await bot.send_message(
            chat_id=chat_id,
            text=escape_markdown(text),
            parse_mode=ParseMode.MARKDOWN_V2,
            disable_web_page_preview=True
        )
        return True
    except Exception as e:
        logger.error(f"Telegram API error: {str(e)}")
        return False

def sync_send_message(bot_token, chat_id, text):
    return asyncio.run(async_send_message(bot_token, chat_id, text))

или вариант кода для отправки в формате "html":

async def async_send_message(bot_token, chat_id, text):
    bot = Bot(token=bot_token)
    try:
        # Преобразование Markdown-подобной разметки в HTML
        html_text = text
        html_text = re.sub(r'\*(.*?)\*', r'\1', html_text)  # *жирный* → жирный
        html_text = re.sub(r'_(.*?)_', r'\1', html_text)    # _курсив_ → курсив
        html_text = html_text.replace('\n', '
') # Переносы строк await bot.send_message( chat_id=chat_id, text=html_text, parse_mode="HTML", disable_web_page_preview=True ) return True except Exception as e: logger.error(f"Telegram API error: {str(e)}") return False

4.2 Работа с базой данных (database.py)

import psycopg2
from config import config

def get_connection():
    return psycopg2.connect(config.DATABASE_URL)

def get_unsent_post():
    with get_connection() as conn:
        with conn.cursor() as cursor:
            cursor.execute("""
                SELECT id, message FROM posts 
                WHERE is_sent = FALSE AND post_date <= NOW() 
                ORDER BY post_date ASC 
                LIMIT 1
            """)
            return cursor.fetchone()

def mark_post_as_sent(post_id):
    with get_connection() as conn:
        with conn.cursor() as cursor:
            cursor.execute("""
                UPDATE posts 
                SET is_sent = TRUE, sent_at = NOW() 
                WHERE id = %s
            """, (post_id,))
            conn.commit()

5. Запуск системы

5.1 Сборка и запуск

# Сборка образов
docker compose build

# Запуск сервисов
docker compose up -d

# Просмотр логов бота
docker compose logs -f bot

5.2 Импорт постов из CSV

Пример CSV-файла (data/posts.csv):

date,message
"2025-06-24 09:00:00","*Почему мы чувствуем одиночество среди людей?*
Социальные связи поверхностны? Попробуйте:

✓ Искренне интересоваться
✓ Найти 1-2 «своих» человека
✓ Не бояться быть уязвимым

_Как вы справляетесь с одиночеством?_"

Команда для импорта:

docker compose exec bot python -m app.main --import-csv /app/data/posts.csv

6. Особенности работы

Форматирование сообщений

Бот поддерживает MarkdownV2 разметку:

  • *жирный текст* - жирное начертание
  • _курсив_ - курсивное начертание
  • `моноширинный` - моноширинный шрифт
  • [текст](URL) - ссылки

Важные моменты

  • Бот должен быть администратором канала
  • Для приватных каналов используйте chat_id вместо @username
  • Специальные символы в Markdown должны быть экранированы

Результаты

После настройки вы получите:

  • Автоматическую публикацию постов по расписанию
  • Поддержку форматированного текста
  • Веб-интерфейс для управления базой данных
  • Масштабируемое решение в Docker-контейнерах

7. Возможные улучшения

  1. Добавление веб-интерфейса для управления постами
  2. Интеграция с Google Sheets для редактирования расписания
  3. Отправка уведомлений об ошибках в Telegram
  4. Поддержка медиа-вложений (фото, видео)

P.S. Имейте ввиду, что данная задача не оптимизирована по процессам и может быть подкорректирована. Это пример полезного функционала, общее направление действий.

Количество показов: 50
24.06.2025


Реклама: ООО «КЛАУДПЭЙМЕНТС». ИНН 7708806062. ERID: CQH36pWzJqCRJ4UXeNjXpDqc5rqRHP2xLyH2ojpuzzBdYG
Реклама: ИП Попович А.И. ИНН: 231537677964. ERID: CQH36pWzJqCRJ4UXZAPx4DUtAuR68f7j7SEtAw8y5oHN14

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...

Сопровождение сайта

Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение - мы подберем подходящий вам бюджет на сопровождение

Работы по сайту

Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.