Найти тему

Напоминалка в Телеграмм при помощи BASH-скриптов в Linux

Оглавление

Когда-то на канале выходил пост, в котором мы знакомились с BASH-скриптами и тем, как они могут упростить жизнь пользователя Linux. Тогда, напомню, писали скрипт очистки папки от ненужных файлов (в моем случае, это были картинки).

Сегодня же создадим напоминалку, в которую вы можете вносить какие-то важные дела, и в нужное время она будет слать уведомление в Телеграмм.

Реализация будет такой, чтобы при необходимости вы могли изменить созданные скрипты (их будет два) под свои нужды и настроить, исходя из потребностей.

СКАЧАТЬ ИСХОДНИКИ

Что нам понадобится?

Так как мы будем взаимодействовать с Телеграммом через API, то определенно точно нужен будет создать бота, через которого будет происходить отправка сообщений.

Помимо бота и текстового редактора для написания кода еще задействуем Cron, но так как эта утилита установлена во всех дистрибутивах Linux «из коробки», то дополнительно что-то ставить не придется.

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

Регистрируем бота в Телеграмм, получаем токен и chatID

Чтобы создать нового бота обратимся к BotFather, который позволяет управлять ботами в мессенджере. В поиске найдем его и выполнив ряд нехитрых нажатий, получим готово бота и токен для подключения к нему.

Полученный токен не нужно никому передавать, так как обладая им, любой злоумышленник сможет получить возможность для управления вашим ботом. Точно по этой же причине не нужно указывать токен в любых файлах программ, которые вы планируете добавлять, например, в репозитории Github. Ниже я покажу как можно в BASH-скриптах использовать данные, не вставляя их в скрипт напрямую.

Созданный бот будет отправлять сообщения в наш аккаунт. Чтобы отправка сработала нам понадобится так называемый chatID - уникальный идентификатор, который принадлежит чату с конкретным пользователем. Для этого в поиске находим getmyid_bot и нажав кнопку «Запустить», в ответ он выдаст ID пользователя и чата с ним. Насколько я понимаю, chatID пользователя совпадает с его userID, по крайней мере у меня это был одинаковый набор цифр.

Узнаем свой chatID
Узнаем свой chatID

Полученные данные сохраняем где-нибудь, чтобы впоследствии использовать в скрипте.

Логика работы скриптов

Будет два скрипта: один отвечает за взаимодействие с пользователем (назовем его «фронтенд-скрипт»), другой будет после наступления нужной даты отправлять уведомление с напоминанием в Телеграмм (это будет «бэкенд-скрипт»).

После запуска фронтенд-скрипт запросит у пользователя дату и время, а также информацию о том, что нужно напомнить. Далее он передаст сообщение и команду на его отправку в бэкенд-скрипт и добавит задачу на запуск бэкенд-скрипта в Crontab на указанные дату и время.

Создаем фронтенд-скрипт

В домашней директории я создал папку bash-reminder, в котором будут находиться оба скрипта. Cкорей всего, закину этот мини-проект на Github и поделюсь ссылкой в конце заметки.

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

СКАЧАТЬ ИСХОДНИКИ

-4

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

Следующими строками я определяю некоторые переменные: BACKEND (относительный путь до скрипта backend) и FPATH (абсолютный путь до скрипта backend). Эти переменные нам понадобятся дальше. Командой source я подключаю внешний файл ENV.txt, в котором хранятся токен бота и идентификатор чата, полученные в начале статьи. Они заданы также, как задаются переменные в BASH: ИМЯ_ПЕРЕМЕННОЙ=значение (обратите внимание, что не должно быть пробелов до и после знака равенства).

Файл ENV.txt
Файл ENV.txt
Файл с переменными окружения я не буду выкладывать в репозитории, поэтому прежде чем попробовать скрипт, вам придется создать собственного бота и узнать персональный chatID, которые позже разместите под нужными именами в созданном файле ENV.txt. Таким образом можно прятать нужные данные (токены, пароли и пр.) не используя их напрямую в том коде, который куда-то выкладываете.

Следующими строками я проверяю существование скрипта backend и очищаю его при помощи команды echo и перенаправления вывода в скрипт. Про ввод/вывод и их перенаправление писал в отдельной статье на канале, прикреплю ссылку на нее ниже.

После, той же командой echo, я помещаю в backend обязательную для BASH конструкцию. Последними строками, начиная с блока if и заканчивая последней командой echo мы, говоря проще, начинаем формировать backend-скрипт. Очистка и наполнение позволяют использовать напоминалку больше одного раза.

-6

Выше вы видите большой фрагмент кода, при выполнении которого у пользователя будут запрашиваться необходимые данные: день, месяц, время и текст для напоминания. Я не буду описывать каждый блок, просто покажу на примере даты, что происходит (в блоке для запроса времени суть точно такая же).

Командой echo я вывожу в консоль сообщение с запросом даты и указываю какой формат должен быть у вводимого текста (DD - день, MM - месяц), далее при помощи команды read BASH-скрипт получает введенные данные и сохраняет их в переменных DD и MM (ключ -r как-раз таки говорит команде read, что вводиться будут несколько переменных). Далее происходит валидация введенных данных, так как, согласитесь, можно ввести и что-то неправильное (например, 20-ый месяц) или не ввести вообще ничего. Я сравниваю введенные данные с привычными для BASH и других языков программирования форматом даты. Так как мне нужны только месяц и день, то я вручную задал в строке для сравнения текущий год (то есть, запланировать что-то на год вперед не получится). Результат сравнения я «спрятал» в нулевом устройстве (про него тоже был пост на канале) и потом описал условие: если результат сравнения не равен 0 (то есть, введенные пользователем числа не подходят под формат даты), то появится сообщение об ошибке и скрипт прекратит работу. В обратном случае (когда введенные данные валидны) я присваиваю пользовательские данные о дате и месяце переменным DAY и MONTH.

С блоком времени абсолютно такая же история, только введенные пользователем часы и минуты присваиваются переменным HOUR и MINUTES. Эти четыре переменные нужны будут для того, чтобы создать расписание при помощи Cron.

Последними командами echo и read я запрашиваю у пользователя то, что ему нужно напомнить. Ключ -e в команде read позволяет редактировать вводимый текст (перемещать курсор в терминале и удалять символы) на случай, если пользователь где-то ошибется.

-7

В следующем куске скрипта при помощи echo я передаю в backend-скрипт строку для отправки сообщения через бота при помощи утилиты curl (про нее кратко, но по делу, мы говорили ранее). Обратите внимание на переменные BOT_TOKEN и CHAT_ID, которые я указываю в качестве аргументов при передаче сообщения - значения этих переменных подхватываются из файла ENV.txt, который подключил в самом начале скрипта.Также обращаю внимание на то, что практически везде используется перенаправление ввода при помощи символов >>, что позволяет добавлять строки в конец файла скрипта backend, тогда как символ > нужен для перезаписывания файла и используется только лишь в самом начале.

Предпоследняя команда echo добавляет в скрипт backend команду sleep, которая ставит выполнение скрипта на паузу (20 секунд, как у меня, например) перед выполнением следующей команды. Последним echo я добавляю команду на очистку Cron для текущего пользователя. При этом помните, что подобное действие можно совершать лишь в том случае, если у вас не настроены через Cron какие-то другие задачи. У меня таких нет, потому я просто очищаю Cron через 20 секунд после отправки сообщения с напоминанием.

-8

На последнем участке скрипта я во-первых, создаю переменную cronjob, куда помещаю задание на запуск скрипта backend, используя все те переменные, про которые говорили раньше - минуты, часы, день, месяц и полный путь до backend-скрипта. Затем передаю строку с заданием в файл foocron и указываю утилите crontab, что нужная для автоматизации задача находится в этом файле. После удаляю файл foocron и вывожу пользователю сообщение о том, что напоминание добавлено.

Итоговый скрипт выглядит так, как показано на нижнем скриншоте.

-9

Демонстрация работы скрипта

Теперь осталось проверить то, как работает созданный скрипт и действительно ли он отправляет сообщения в Телеграмме с напоминаниями. Вначале сделаем оба скрипта исполняемыми при помощи следующих команд:

sudo chmod +x frontend.sh

sudo chmod +x backend.sh

В моей оболочке ZSH исполняемые файлы подсвечиваются зеленым цветом, как на скриншоте ниже.

Далее я хочу добавить алиас для удобного использования скрипта. Для этого открываю конфигурационный файл своей оболочки и добавляю запуск скрипта frontend.sh по команде remind. Про то, что такое алиасы и как их настраивать также ранее рассказывал на канале. Отмечу, что добавление в алиасы не обязательно, просто мне так кажется удобнее.

Добавляю алиас для запуска напоминалки
Добавляю алиас для запуска напоминалки

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

Теперь дожидаюсь указанного времени и получаю от бота напоминание.

Готовый результат
Готовый результат

Сразу хочу сказать про одну особенность запуска: оказалось, что на Fedora 38 нет установленного Cron, хотя я искренне полагал, что эта программка идет «из коробки» у всех дистрибутивов. Потому вначале пришлось доставить пакет cronie.

Подведем итог

Материал получился не маленьким, но надеюсь, что понятным. Постарался как можно подробнее изложить суть каждой строчки в скрипте. Ниже прикреплю ссылку на Github-репозиторий, откуда вы сможете скачать оба скрипта и попробовать настроить такую напоминалку самостоятельно. В случае возникновения проблем с работой скриптов пишите в комментариях, либо на электронную почту, либо в Телеграмм.

СКАЧАТЬ ИСХОДНИКИ СКРИПТОВ

Думаю, что такой подробный и полезный материал заслужил, как минимум, лайка и подписки, если вас еще нет среди подписчиков и читателей канала!