Skip to content
konkerePublic

About

Селфхостед Telegram-бот напоминаний с кнопочным интерфейсом. Разовые и периодические напоминания, работа в группах с тегами участников, allowlist, авточистка чата.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Tickd

Селфхостед Telegram-бот напоминаний. Разовые и периодические напоминания создаются кнопками (без запоминания синтаксиса команд), работает в личке и в группах, умеет тегать выбранных участников чата, ограничивает доступ через allowlist и по желанию подчищает служебный мусор в чате.

Всё состояние живёт в одном файле SQLite. При перезапуске бот восстанавливает запланированные задачи из БД, так что напоминания не теряются.


Что умеет

  • Разовые напоминания — «напомни 31.12 в 18:00».
  • Периодические напоминания:
    • каждый день в заданное время;
    • по выбранным дням недели (Пн/Ср/Пт и т.п.);
    • каждые N дней с датой старта;
    • каждое N-е число месяца (в т.ч. «последний день месяца»; если в месяце нет 29/30/31-го — сработает в последний день);
    • каждый год в заданную дату — для дней рождения и памятных дат (29.02 в невисокосные годы срабатывает 28.02).
  • Догон после простоя: если бот был выключен в момент срабатывания (рестарт, пересоздание контейнера), при старте он дошлёт пропущенные напоминания с пометкой — в пределах окна CATCHUP_WINDOW_HOURS.
  • Кнопочный визард — весь процесс создания идёт через инлайн-кнопки, с возможностью в любой момент ввести дату/время/число вручную сообщением.
  • Работа в группах — при срабатывании бот тегает адресатов. Кому напоминать, выбирается из участников чата (всех сразу или конкретных людей). В личке адресат всегда сам пользователь.
  • Список и редактирование — /list показывает активные напоминания, у каждого кнопки «Изменить» (время / текст / адресаты) и «Удалить» (с подтверждением). Разовые и «каждые N дней» можно сдвигать на ±N дней без пересоздания: у разовых двигается дата, у периодических — вся сетка, с якорем на ближайшее срабатывание (после «+7» следующее придёт на 7 дней позже, дальше каждые N дней от него).
  • Форматирование текста — жирный, курсив, ссылки из вашего сообщения сохраняются и приходят в напоминании.
  • Контроль доступа — админы задаются в .env, остальным доступ выдаётся через allowlist (командами или reply’ем на сообщение человека).
  • Авточистка чата (опционально) — удаляет системные сообщения и служебную переписку с ботом, оставляя сами сработавшие напоминания и обычные сообщения людей.
  • Устойчивость — источник правды это SQLite; после рестарта/пересборки задачи планируются заново из БД.

Как пользоваться

Команды

Команда Кто может Что делает
/remind allowlist Запустить визард создания напоминания
/list allowlist Показать активные напоминания (с кнопками изменить/удалить)
/del <id> allowlist Удалить напоминание по номеру
/whoami allowlist Показать свой ID и роль
/start, /help все Краткая справка
/cancel — Прервать создание/редактирование
/allow <id> [пометка] админ Дать доступ (можно reply’ем на сообщение)
/disallow <id> админ Забрать доступ
/allowlist админ Кто имеет доступ
/cleanup on|off админ Включить/выключить авточистку чата

Меню команд (по желанию)

Чтобы команды показывались в списке по кнопке «☰ Меню» рядом с полем ввода и подсказывались при наборе /, добавьте их через @BotFather: команда /setcommands, затем выбрать бота и прислать список в формате команда - описание (без слэша, по одной на строку).

Удобный набор для обычного пользователя:

remind - создать напоминание
list - мои напоминания
del - удалить напоминание по id
whoami - мой ID и роль
help - справка

Админские команды в общее меню добавлять не обязательно — они и так работают. Если хочется, можно добавить и их, но учтите, что меню одно на всех и остальные пользователи их тоже увидят (толку от них без прав админа не будет):

allow - выдать доступ
disallow - забрать доступ
allowlist - список доступа
cleanup - авточистка чата on/off

Набор — дело вкуса: можно вписать все команды, только основные или вообще пропустить этот шаг, бот работает и без меню.

Создание напоминания

Наберите /remind и дальше идите по кнопкам:

  1. Тип — разовое или периодическое.
  2. Когда:
    • разовое → день (Сегодня / Завтра / +N / своя дата) и время;
    • периодическое → частота (каждый день / по дням недели / каждые N дней / каждое число месяца / каждый год), затем при необходимости дни недели, дату старта, число месяца или дату года, и время.
  3. Текст — пришлите сообщением (форматирование сохраняется).
  4. Кому (только в группах) — выберите одного, нескольких или всех.

На шагах с датой/временем/числом можно нажать «своё» и ввести значение вручную: дата — ДД.ММ или ДД.ММ.ГГГГ (понимает и свободные формы вроде «3 июля», «завтра»), время — ЧЧ:ММ. Если год не указан и дата уже прошла, берётся следующий год.

Визард сам отменяется после 10 минут бездействия, черновик при этом удаляется.

Важно: бот должен «увидеть» человека

Из-за ограничений Telegram есть пара моментов с первым контактом:

  • В личке. Бот не может написать пользователю первым — человек должен сам начать диалог с ботом (нажать Start / отправить любое сообщение). В этом боте напоминания в личке и так приходят тому, кто их создал, а создать их можно только написав боту, так что активация происходит сама собой.
  • В группе. Чтобы человек появился в списке «кому напоминать», бот должен его хотя бы раз «увидеть». Просто молчаливого присутствия в группе недостаточно. Надёжные способы отметиться: выполнить /start, /whoami или /remind. Если у бота не отключён режим приватности (Privacy Mode в @BotFather, включён по умолчанию), обычные сообщения участников он не получает и в список они не попадут — тогда человеку нужно либо выполнить одну из команд выше, либо ответить реплаем на сообщение бота / упомянуть его. Как вариант — отключить Privacy Mode у @BotFather, чтобы бот видел всех пишущих в группе.

Доступ

Изначально пользоваться ботом могут только админы из ADMIN_IDS. Чтобы пустить остальных, админ добавляет их в allowlist: /allow 123456789 Вася или ответом /allow на сообщение нужного человека. Свой ID можно узнать командой /whoami.


Настройка

Скопируйте пример окружения и заполните своими значениями:

cp .env.example .env

Переменные:

Переменная Обяз. По умолчанию Описание
BOT_TOKEN да — Токен от @BotFather
ADMIN_IDS желательно пусто ID админов через запятую. Только они правят allowlist — впишите хотя бы свой ID, иначе управлять доступом будет некому
TZ нет Europe/Moscow Таймзона по умолчанию (имя из tz database)
DB_PATH нет reminders.db Путь к файлу БД (в docker-compose переопределяется на /data/reminders.db)
CLEANUP нет off Авточистка по умолчанию (on/off). Переключается в каждом чате командой /cleanup
CATCHUP_WINDOW_HOURS нет 24 Догон после простоя: досылать пропущенные напоминания не старше этого окна (часов), с пометкой. 0 — отключить. Разовые, пропущенные за пределами окна, деактивируются

Запуск

Нужен Python 3.12+.

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env             # и заполнить BOT_TOKEN, ADMIN_IDS
python bot.py

Файл БД (reminders.db) создастся автоматически рядом с ботом.


Docker

docker compose (рекомендуется)

cp .env.example .env             # заполнить BOT_TOKEN, ADMIN_IDS
docker compose up -d --build
docker compose logs -f           # смотреть логи
docker compose down              # остановить

БД хранится в ./data на хосте (том смонтирован в /data внутри контейнера), поэтому переживает пересборку образа. Путь к БД в compose уже переопределён на /data/reminders.db.

Голый Docker

docker build -t tickd .
docker run -d --name tickd \
  --env-file .env \
  -e DB_PATH=/data/reminders.db \
  -v "$(pwd)/data:/data" \
  --restart unless-stopped \
  tickd

Авточистка

Когда включена (/cleanup on), бот удаляет:

  • системные сообщения (кто вошёл/вышел, смена фото/темы и т.п.) — примерно через 30 секунд;
  • служебную переписку с ботом (команды, подтверждения, списки, шаги визарда) — примерно через 5 минут.

Сработавшие напоминания и обычные сообщения людей не трогаются.

Настройка своя для каждого чата и хранится в БД. Чтобы бот мог удалять чужие сообщения в группе, дайте ему право «Удаление сообщений» в настройках группы.


Как устроено

Проект разбит на небольшие модули:

Модуль Ответственность
bot.py Точка входа: сборка приложения, регистрация хендлеров, обработка ошибок
config.py Переменные окружения, константы, логирование
db.py Подключение к SQLite, схема, миграции, учёт участников
drafts.py CRUD напоминаний и черновиков
access.py Allowlist и декораторы доступа (restricted, admin_only)
cleanup.py Авточистка и служебная отправка сообщений
keyboards.py Инлайн-клавиатуры и UI-хелперы
formatting.py Отображение напоминаний
scheduler.py Планирование и срабатывание задач (JobQueue)
commands.py Простые команды, allowlist, фоновые хендлеры
wizard.py Визард создания (ConversationHandler)
edit.py Удаление и редактирование из /list

Хранилище — SQLite. При старте restore_jobs перечитывает активные напоминания и заново ставит их в планировщик, поэтому перезапуск бота ничего не теряет. Кроме того, при каждом планировании в БД записывается расчётное время следующего срабатывания (next_run_at): если при старте оно оказалось в прошлом — значит, срабатывание пришлось на простой, и бот дошлёт его с пометкой «пропущено во время простоя» (свежее окна CATCHUP_WINDOW_HOURS; протухшие разовые деактивируются).

Стек: python-telegram-bot 21.6 (с job-queue), dateparser, python-dotenv.

About

Селфхостед Telegram-бот напоминаний с кнопочным интерфейсом. Разовые и периодические напоминания, работа в группах с тегами участников, allowlist, авточистка чата.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages