У всех нас есть список дел, дат или регулярных платежей. Можно по старинке забивать их в календарь телефона, но у него есть три жирных минуса:
- Он пассивен: если вы пропустили пуш-уведомление — вы забыли о деле.
- Рутина: ежемесячные задачи (интернет, страховка, ЖКХ) нужно каждый раз переставлять вручную.
- Нет контекста: сложно получить краткую сводку «на завтра» в удобном текстовом виде.
Я решил эту проблему через связку Google Таблиц и Telegram. Теперь система сама напоминает о важных датах заранее, автоматически переносит регулярные платежи на новый месяц и присылает мне вечерний план действий. Это решение для тех, кто хочет один раз настроить систему и больше не держать лишнее в голове.
Не забудьте подписаться на канал!
Почему это удобнее обычного календаря? (Ценность решения)
- Многоступенчатые уведомления: Бот не просто пишет «сегодня надо сделать». Он предупредит вас за неделю, за 3 дня и за сутки. Вы точно успеете подготовиться или найти деньги на платеж.
- Автоматизация переноса: Забудьте о ручном изменении дат. Если задача помечена как «Месяц», бот сам поменяет 01.05 на 01.06.
- Вечерний «брифинг»: Каждый вечер после 20:00 вы получаете список дел на завтра. Это помогает разгрузить мозг перед сном.
Шаг 1. Создаем бота и узнаем свой ID
Чтобы таблица могла вам писать, нужно получить «адрес» и «ключ».
- Регистрируем бота: В поиске Telegram находим @BotFather. Пишем /newbot, даем имя. Сохраняем выданный API Token.
- Узнаем свой ID: Пишем боту @userinfobot. Он выдаст ваш числовой ID.
Шаг 2. Готовим таблицу
Создаем Google Таблицу. Лист называем строго Calendar.
Заполняем шапку:
- Колонка B: Дата (01.01.2024).
- Колонка C: Описание (что сделать).
- Колонка D: Повторение (Однократно, Месяц или Год).
- Колонка E: Время (10:00).
Шаг 3. Загружаем код
Идем в Расширения -> Apps Script. Удаляем всё и вставляем этот скрипт.
В начале впишите свои Token и ID которые получили на шаге 1.
// --- БЛОК НАСТРОЕК ---
const TELEGRAM_TOKEN = "ВАШ_ТОКЕН_ЗДЕСЬ";
const MY_CHAT_ID = "ВАШ_ID_ЗДЕСЬ";
/**
* 1. Автоматическое обновление дат (Месяц/Год).
* Запускать триггером раз в день ночью (с 00:00 до 02:00).
*/
function updateRecurringEvents() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
const data = sheet.getDataRange().getValues();
const today = new Date();
const isFirstOfMonth = today.getDate() === 1;
const isFirstOfYear = isFirstOfMonth && (today.getMonth() === 0);
for (let i = 1; i < data.length; i++) {
const repeat = data[i][3];
const eventDate = new Date(data[i][1]);
if (!data[i][1]) continue;
if (repeat === "Месяц" && isFirstOfMonth) {
let newDate = new Date(eventDate);
newDate.setMonth(newDate.getMonth() + 1);
sheet.getRange(i + 1, 2).setValue(newDate);
}
if (repeat === "Год" && isFirstOfYear) {
let newDate = new Date(eventDate);
newDate.setFullYear(newDate.getFullYear() + 1);
sheet.getRange(i + 1, 2).setValue(newDate);
}
}
}
/**
* 2. Рассылка напоминаний (Утро).
* Запускать триггером раз в день утром (с 08:00 до 09:00).
*/
function sendReminders() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
// getDisplayValues гарантирует, что время и даты будут как в таблице
const displayData = sheet.getDataRange().getDisplayValues();
const data = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
for (let i = 1; i < data.length; i++) {
const dateValue = data[i][1];
const desc = displayData[i][2];
const repeat = displayData[i][3];
const timeStr = displayData[i][4]; // Берем время строкой "08:00"
if (!dateValue || !desc) continue;
const eventDate = new Date(dateValue);
eventDate.setHours(0, 0, 0, 0);
const diffDays = Math.round((eventDate - today) / (1000 * 60 * 60 * 24));
const isYearly = repeat === "Год" && [30, 14, 7, 3, 1, 0].includes(diffDays);
const isRegular = (repeat === "Месяц" || repeat === "Однократно") && [7, 3, 1, 0].includes(diffDays);
if (isYearly || isRegular) {
let timeStatus = diffDays === 0 ? "СЕГОДНЯ" : "через " + diffDays + " дн.";
let label = repeat === "Год" ? "📅 ГОДОВОЕ" : "🔔 УВЕДОМЛЕНИЕ";
let msgTime = timeStr ? " в " + timeStr : "";
sendMsg(`<b>${label}</b>\nСрок: ${timeStatus}${msgTime}\nЧто: ${desc}`);
}
}
}
/**
* 3. Вечерний отчет на завтра (Вечер).
* Запускать триггером раз в день вечером (с 20:00 до 21:00).
*/
function sendTomorrowEventsSummary() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Calendar");
const displayData = sheet.getDataRange().getDisplayValues();
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
// Формат dd.MM.yyyy должен совпадать с тем, как даты отображаются в твоей таблице
const tomorrowStr = Utilities.formatDate(tomorrow, "GMT+3", "dd.MM.yyyy");
let message = `📝 <b>ПЛАНЫ НА ЗАВТРА:</b>\n\n`;
let hasEvents = false;
for (let i = 1; i < displayData.length; i++) {
const eventDateStr = displayData[i][1];
if (eventDateStr === tomorrowStr) {
hasEvents = true;
const desc = displayData[i][2];
const repeat = displayData[i][3];
const timeStr = displayData[i][4];
// Выводим время, тип задачи в скобках и описание
message += `🕒 ${timeStr || "--:--"} | [${repeat}] ${desc}\n`;
}
}
if (hasEvents) {
sendMsg(message);
}
}
/**
* Вспомогательная функция отправки сообщения
*/
function sendMsg(text) {
const url = `https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`;
try {
UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify({
chat_id: MY_CHAT_ID,
text: text,
parse_mode: "HTML"
})
});
} catch (e) {
Logger.log("Ошибка: " + e.message);
}
}
после внесения кода - нужно нажать сохранить, и выбрать функцию sendTomorrowEventsSummary, потом нажать выполнить и дать все разрешения на запуск скрипта в своей учетной записи
Шаг 4. Настраиваем триггеры
Чтобы всё работало без вашего участия, нужно настроить автоматический запуск функций. В меню слева нажмите на иконку часов (Триггеры) и добавьте три задания:
- updateRecurringEvents — раз в день, ночью (1:00).
- sendReminders — раз в день, утром (9:00).
- sendTomorrowEventsSummary — раз в день, вечером (20:00).
Шаг 5. Заполняем таблицу
В колонку B вносим дату события, в колонку C содержание
В поле "Повторение" колонка D - вносим частоту событий ровно как указано "Однократно", "Год" или "Месяц" (при этом можно в таблице это оформить в виде выпадающего меню -чтобы не писать каждый раз вручную, либо один раз написать и копировать на новые ячейки нужный вариант)
И в колонку E время, на которое запланировано событие.
Как это работает (Логика системы):
- Точное время: Скрипт не вычисляет время математически, а просто копирует текст из ячейки таблицы. Написали «08:00» — придет «08:00». Это исключает ошибки часовых поясов.
- Умные уведомления: О годовых делах (страховки, налоги) бот начинает «жужжать» за месяц, а о ежемесячных — за неделю.
- Автопилот: Скрипт сам заходит в таблицу ночью каждого 1-го числа. Если он видит задачу «Месяц», он просто переставляет дату на +1 вперед. Вам не нужно открывать таблицу годами, если список задач не меняется.
Итог
Вы получили систему, которая работает на вас 24/7. Она не забудет про страховку, напомнит про оплату интернета и сама подготовит вас к завтрашнему дню.