Напоминания от бота

В прошлой статье мы научили бота выводить список покупок через кнопки телеграма. В этой статье научим его напоминать нам о покупках.

Когда в программе появляется таймер, он блокирует поток выполнения и бот замолчит до конца таймера. Такое нам не надо, поэтому нужно сделать отдельный поток для таймера, чтобы он не мешал общению с ботом.

В стандартной библиотеке пайтона есть библиотека для работы с потоками — threading. В ней есть класс Timer, его будем использовать для таймера. Для работы таймера нужно два аргумента: время таймера в секундах и функция для вызова по окончанию таймера.
Импортируем в файл list_control.py библиотеку для работы со временем и потоками:

from datetime import datetime, date, time
from threading import Timer

Функция для вычисления разницы

Назовём функцию get_time_delta. На вход она получает обязательный аргумент время и необязательный аргумент дату. Так получается из-за разных напоминаний, вот пример: во фразе «напомни через две минуты» бот найдёт только время, а во фразе «напомни завтра в два часа дня» дату и время.

От сервера ДФ дата и время приходит в текстовом формате, их нужно перевести в формат даты или времени.
Потом нам нужно собрать дату и время в один формат — datetime и вычислить текущий datetime, чтобы получить время для таймера в секундах.
Проверку даты мы вынесли в отдельную функцию, чтобы не дублировать код.
Получилась вот такая функция

def get_time_delta(time_notify, date_notify=None):
    def calculating_date():
        if date_notify is None:
            return date.today()
        return date.fromisoformat(date_notify)

    # Переводим время в формат времени
    parsed_time_notify = time.fromisoformat(time_notify)
    # Переводим дату в формат даты
    parsed_date_notify = calculating_date()
    # Собираем дату и время в формат даты и времени
    parsed_datetime = datetime.combine(parsed_date_notify, parsed_time_notify)
    datetime_now = datetime.now()
    delta = parsed_datetime - datetime_now
    # Получаем разницу во времени в секундах
    delta_seconds = delta.seconds

    return delta_seconds

Ставим таймер

Назовём функцию set_notify, она будет принимать три аргумента: разницу времени, объект бота и айди чата.
В функции set_notify сделаем ещё одну, она будет отправлять пользователю напоминание о списке и прикреплять его к напоминанию.

def notify():
        shop_list = list_from_file()
        markup = create_buttons(shop_list)
        bot.send_message(chat_id, 'Ты просил напомнить про покупки.\rВот список',
                         reply_markup=markup)
        # Удаляем таймер
        timer.cancel()

Теперь создаём таймер и запускаем его. В итоге файл list_control.py выглядит вот так

Прикручиваем к главному файлу

Интент с напоминанием о списке активирует такой action: create_list.shop_list.notify.
Добавляем в главный файл такие блоки

# Создаем напоминание
    elif action == 'create_list.shop_list.notify':
        # Если бот не смог распарсить время
        if not parameters['time']:
            bot.send_message(chat_id, 'Не могу прочитать время')

        # Если напоминание поставлено без даты
        if not parameters['date']:
            bot.send_message(chat_id, 'Напомню в {}'.format(parameters['time']))
            time_delta = list_control.get_time_delta(parameters['time'])
            list_control.set_notify(time_delta, bot, chat_id)

        # Если напоминание поставлено с датой и временем
        else:
            bot.send_message(chat_id, 'Напомню {} в {}'.format(parameters['date'],
                                                               parameters['time']))
            time_delta = list_control.get_time_delta(parameters['time'], parameters['date'])
            list_control.set_notify(time_delta, bot, chat_id)

Файл bot.py выглядит теперь вот так

Теперь у вас есть бот для помощи с покупками на ИИ. Рабочий код лежит в нашем репозитории на гитлабе, можно скачать, поставить свои токены и пользоваться. Если что-то не работает, пишите @cmp_sci.

На этом с ботами в телеграме закончим. Это была серия статей для знакомства с ИИ и телеграм ботами, позже мы вернёмся к боту и сделаем его лучше.

В следующей статье расскажем про парадигмы языков программирования.

Поделиться
Отправить
Популярное