KOTOFF.NET
ГлавнаяКаталогСтатьиИнструментыМагазинО проекте
Войти

Telegram-бот-напоминатель на PHP: команды, расписание и отправка по cron

Статьи / PHP

08.11.2026 · kenny · 2 просмотров

Содержание
    Иллюстрация к статье
    Иллюстрация к статье

    Что соберём

    Бот принимает команды в личном чате:

    /remind 2026-11-07 19:30 Забрать посылку
    /list
    /cancel 3

    Webhook сохраняет задачу в JSON-файл вне публичной папки сайта. Планировщик хостинга запускает PHP-скрипт раз в минуту; worker выбирает просроченные напоминания и отправляет их через Telegram Bot API.

    Это самостоятельный учебный проект для небольшого бота. Он не использует сторонние PHP-пакеты, но требует PHP 8.1+, cURL, HTTPS и возможности запускать cron/планировщик. Для крупного сервиса JSON-хранилище следует заменить базой данных и очередью задач.

    Архитектура

    Пользователь Telegram
            │ команда /remind
            ▼
    HTTPS webhook ── проверка секрета ── ReminderBot
                                          │
                                          ▼
                                   JSON-хранилище
                                          ▲
                                          │ due tasks
    Планировщик ── PHP worker ───────────┘
            │
            └── Telegram Bot API: sendMessage

    Здесь два отдельных процесса. Webhook принимает команду и быстро сохраняет её. CLI-worker запускается по расписанию и отправляет наступившие задачи. Так не приходится держать постоянно работающий PHP-процесс на обычном виртуальном хостинге.

    1. Создаём бота и готовим PHP-хостинг

    Создайте тестового бота через @BotFather и сохраните выданный токен в защищённой настройке хостинга. Для PHP нужны cURL и права записи на каталог данных. Веб-сервер должен направлять запросы только в public/, а JSON-файл храниться вне document root.

    Пример структуры:

    telegram-reminder-bot/
    ├── bin/
    │   ├── send-due-reminders.php
    │   └── set-webhook.php
    ├── public/
    │   └── webhook.php
    ├── src/
    │   ├── JsonReminderStore.php
    │   ├── ReminderBot.php
    │   ├── ReminderStore.php
    │   ├── TelegramApi.php
    │   └── TelegramClient.php
    ├── tests/run.php
    └── var/                 # вне публичной папки, создаётся при первом запуске

    Переменные окружения:

    • TELEGRAM_BOT_TOKEN — секретный токен;
    • TELEGRAM_WEBHOOK_SECRET — случайный секрет для проверки входящих POST;
    • TELEGRAM_WEBHOOK_URL — HTTPS-адрес public/webhook.php;
    • BOT_TIMEZONE — часовой пояс расписания, по умолчанию Europe/Moscow;
    • REMINDER_DATA_FILE — необязательный полный путь к приватному JSON-файлу.

    Секрет для webhook можно получить локально:

    php -r "echo bin2hex(random_bytes(32)), PHP_EOL;"

    На сервере настройте document root на public/. Каталог с данными вынесите за пределы публичной директории и предоставьте права записи пользователю PHP/cron. Токен не помещайте в исходный код или архив с проектом.

    2. Формат и часовой пояс

    Команда использует строго определённый формат:

    /remind ГГГГ-ММ-ДД ЧЧ:ММ текст напоминания

    Например:

    /remind 2026-11-07 19:30 Забрать посылку

    Время интерпретируется в BOT_TIMEZONE. Бот переводит его в UTC для хранения; worker также сравнивает время в UTC. Так расписание не зависит от того, в каком часовом поясе настроен сервер.

    При разборе даты проверяются ошибки календаря и обратное форматирование: дата вроде 31 февраля не должна молча превращаться в март. Бот также отклоняет время менее чем через минуту от текущего. Длина текста ограничена 500 символами, а на один чат можно создать не более 100 активных напоминаний.

    3. Храним задачи в JSON с блокировкой

    JsonReminderStore реализует интерфейс ReminderStore. У напоминания хранятся:

    {
      "id": 3,
      "chat_id": "123456789",
      "run_at": "2026-11-07T16:30:00Z",
      "text": "Забрать посылку",
      "status": "pending",
      "attempts": 0,
      "next_attempt_at": "2026-11-07T16:30:00Z"
    }

    Перед изменением данных приложение блокирует отдельный lock-файл через flock(). После изменения оно записывает временный файл и заменяет основной атомарным rename(). Это не даёт двум одновременным webhook-запросам одновременно перезаписать весь файл и потерять запись.

    Бот разрешает /list и /cancel ID только для владельца задачи: сравнивается chat_id из входящего сообщения. Дополнительно бот работает только в личном чате, не в группах. JSON-файл должен находиться вне web root, поскольку в нём хранятся тексты личных напоминаний.

    4. Обрабатываем команды

    ReminderBot получает зависимости через конструктор: Telegram-клиент, хранилище и часовой пояс. Это позволяет отдельно тестировать команды без сети.

    Основной сценарий /remind:

    1. Проверить структуру команды и длину текста.
    2. Разобрать дату во временной зоне бота.
    3. Отклонить несуществующую дату или слишком близкое время.
    4. Преобразовать значение в UTC.
    5. Сохранить напоминание и вернуть его ID.

    /list показывает до 20 ближайших активных задач. /cancel ID отменяет только активную задачу текущего чата. Если ID неизвестен или принадлежит другому пользователю, бот отвечает, что активное напоминание не найдено.

    В проекте текст отправляется как обычный текст Telegram без HTML/Markdown-разметки. Поэтому пользовательский текст не интерпретируется как форматирующая разметка.

    5. Регистрируем webhook

    После загрузки файлов задайте переменные окружения в панели хостинга и запустите из корня проекта:

    php bin/set-webhook.php

    URL должен открываться по HTTPS с действительным сертификатом. Скрипт проверяет URL и формат секрета, после чего регистрирует webhook с разрешённым типом обновлений message.

    Endpoint проверяет заголовок X-Telegram-Bot-Api-Secret-Token через hash_equals(), принимает только POST и ограничивает размер JSON до 1 МБ. Ошибки не раскрывают пользователю внутренние сведения сервера. Если обработка не удалась, сервер возвращает 500, чтобы Telegram мог повторить доставку.

    6. Настраиваем отправку по расписанию

    Worker — это отдельный CLI-скрипт:

    php bin/send-due-reminders.php

    Добавьте команду в планировщик хостинга с периодом одна минута. На Linux запись crontab может выглядеть так:

    * * * * * /usr/bin/php /home/account/telegram-reminder-bot/bin/send-due-reminders.php

    Путь к PHP и каталогу проекта замените на реальные значения сервера. Worker использует lock-файл, чтобы два запуска не обрабатывали один набор задач одновременно. Он выбирает до 20 напоминаний за один запуск.

    Если Telegram API временно недоступен, попытки повторяются с задержками 2, 4, 8, 16 и 32 минуты. После пятой ошибки задача получает статус failed; причина записывается в серверный error log без токена и текста напоминания. Проверяйте журналы после первого запуска планировщика.

    7. Тестируем без настоящего Telegram

    Запустите:

    php tests/run.php

    Тесты создают временное JSON-хранилище, подставляют фальшивый Telegram API и проверяют:

    • создание будущего напоминания;
    • сохранение и чтение списка;
    • изоляцию задач между чатами;
    • запрет отмены чужого напоминания;
    • отмену своей задачи.

    После теста временные файлы удаляются. Для живой проверки отправьте тестовому боту /help, добавьте напоминание на 2–3 минуты вперёд и проверьте, что планировщик запускается. Не используйте для проверки важные личные данные.

    8. Ограничения и переход к промышленному варианту

    Файловое хранилище подходит для учебного проекта и небольшого личного бота. При высокой нагрузке, нескольких серверах или росте числа записей используйте MySQL/PostgreSQL с транзакциями и отдельную очередь задач. Так проще управлять резервными копиями, сроками хранения и конкурентной обработкой.

    Есть важное ограничение доставки: если Telegram принял сообщение, а PHP-процесс завершился до отметки sent, при следующей попытке пользователь может получить дубликат. Внешний Bot API не предоставляет транзакцию, которая одновременно отправляет сообщение и фиксирует локальное состояние. Для напоминаний дубликат обычно допустим; для платежей и других критичных операций нужна отдельная архитектура с очередью/outbox и идемпотентной обработкой.

    Входящие webhook-обновления тоже могут доставляться повторно при сбое ответа. Этот учебный проект не хранит обработанные update_id, поэтому не подключайте к нему операции, для которых повтор команды опасен. Для следующей версии добавьте таблицу обработанных обновлений с уникальным индексом и транзакцию создания напоминания.

    Частые проблемы

    Бот подтверждает задачу, но не присылает напоминание. Проверьте cron, путь к PHP CLI, REMINDER_DATA_FILE и права на каталог. Запустите worker вручную и проверьте серверный error log.

    Команда с датой отклоняется. Проверьте точный формат и время: /remind 2026-11-07 19:30 Текст. Время уже прошло или наступит менее чем через минуту — бот его не примет.

    Время отличается на несколько часов. Посмотрите значение BOT_TIMEZONE; по умолчанию это Europe/Moscow. Убедитесь, что планировщик и PHP используют тот же релиз файлов и окружение.

    Нет доступа к JSON-файлу. Укажите путь вне document root, доступный пользователю PHP и cron. Не решайте проблему выдачей прав на запись всем пользователям сервера.

    Итог

    Получился законченный небольшой сервис: webhook, команды создания/просмотра/отмены, проверка ввода, файловое хранилище, worker по cron, повторные попытки и тесты. Архив исходников содержит готовую структуру проекта; в боевую среду его следует переносить только после настройки HTTPS, приватного каталога данных и тестового напоминания.


    Скачать исходный код: архив проекта

    • kenny
    • 08.11.2026
    • 2
    • 0
    Movie

    Нет комментариев. Не желаешь оставить первый комментарий?

    Перед публикацией, советую ознакомится с правилами!

    {login}

    Оставить комментарий

    Заказывай!
    Разработка ботов на заказ, любой сложности, обращаться:
     VK KOTOFF.net - Сообщество, в личные сообщения или по контактам указанным там 
     mail: [email protected]

    Рекламный блок
    • Новости
    • Блог
    • Игры
    • Обновления
    • Программы
    • Статьи
      • PHP
      • Python
      • JS
    • Дизайн
      • PSD исходники
    • DLE
      • Шаблоны
      • Модули
      • Хаки
    • Магазин
      • Скрипты
    Комментарии
    Cкрипт добавление возможных друзей Вконтакте, законная накрутка друзей без блокировок!
    var counter = 100; var timer = 10000; (async () => {     for (var i = 0; i < counter; i++) {
    Система комментариев на PHP
    qweqweqweqweqweqweqewqe
    Cкрипт добавление возможных друзей Вконтакте, законная накрутка друзей без блокировок!
    новый надо скрип , есть ? 
    Создаем бота VK на библиотеке SimpleVK 3.x [Часть 1]
    Как при нажатии на инлайн-кнопку под сообщением удалить или обновить это сообщение?
    Система комментариев на PHP
    Круто! Всё работает!
    Все комментарии..
    Полный список последних комментариев
    Лучшие новости
    Создаём Telegram-бота на PHP 8: webhook, меню и inline-кнопки

    Создаём Telegram-бота на

    Вчера, 12:00
    Telegram-бот-напоминатель на PHP: команды, расписание и отправка по cron

    Telegram-бот-напоминатель

    Сегодня, 12:00
    Всего публикаций: 113
    Добавлено за сутки: +1
    Записей в блоге: 1
    Добавлено за сутки: +0
    Комментариев: 930
    Добавлено за сутки: +1
    Пользователей: 4114
    Добавлено за сутки: +0
    Полная статистика..
    Подробная статистика сайта
    Loading...

    Нашли ошибку?
    Вы можете сообщить об этом администрации.
    Выделив текст нажмите CTRL+Enter

    KOTOFF.NET

    Технологии, знания и готовые решения.

    РазделыСтатьиИнструментыСкрипты
    ИнформацияО проектеКонтактыПравила
    © KOTOFF.NET
    Быстрый вход

    Используйте социальные сети для быстрой регистрации и авторизации.

    Google
    ВКонтакте
    Яндекс
    Mail.ru
    Создать аккаунт / Регистрация
    Авторизация

    Я забыл свой пароль