Пишем телеграм-бота. Часть 1: Серверная часть или данные в Google таблицах.

Так как моя «профессиональная» жизнь связана с миром экономики, финансов, МСФО и бухучета, в свое время я написал скрипт, который шлет в почту напоминания вида «через неделю срок подачи декларации по налогу на прибыль».

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

В серии записей «Пишем телеграм-бота» я рассмотрю как сделать аналогичную напоминалку, но через функционал телеграма.

Бот будет уметь следующее:

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

В этом посте я напишу и протестирую «серверную» часть, где будет храниться информация по необходимым данным.

Даты и названия в гугл-таблицах

Стандартно создаю в гугл-таблицах пустую таблицу и из публичных источников беру информацию о сроках предоставления налоговых деклараций:

dates and tax declarations

Тут пока все просто — столбец А формат «Дата», столбец B — текст

С табличной частью закончили. Единственное уточнение: в таких разработках я обрезаю лишние столбцы и/или строки там, где это можно. Все дело в быстродействии таблиц: чем короче таблица, тем быстрее она обрабатывается на стороне гугла.

Скрипт №1 — получение всего массива данных

Для тех, кто читает этот блог ничего нового в скрипте ниже не будет 🙂

// Google sheet
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsDb = ss.getSheetByName("DB")

// Получение всего массива с датами и данными
function getAllData() {

  const dbArr = wsDb.getDataRange().getValues()
  const dbArrWithDates = dbArr.map( row => [row[0].toLocaleString().split(',')[0], row[1]])
 
  return dbArrWithDates;
}

Так как на листе «DB» только 2 столбца и хранятся только данные по дате и содержанию, можно получать массив через getDataRange: const dbArr = wsDb.getDataRange().getValues()

Сложность может вызвать следующая строчка:

const dbArrWithDates = dbArr.map( row => [row[0].toLocaleString().split(',')[0], row[1]])

если с map все понятно то с .toLocaleString().split(',')[0] может быть немного сложнее. Все дело в том, что дата в массиве — это объект (если посмотреть на него через typeof(row[0]))

и для простоты как сравнения, так и далее вывода в удобной и читаемой форме такую дату проще конвертировать в текстовый вид, а потом сплитить — метод split() разбивает строку на массив строк путём разделения строки указанной подстрокой, что в моем случае — запятая. В итоговом массиве нужен первый ([0]) элемент массива, представляющий из себя дату. Для сведения — второй ([1]) элемент массива это время.

Итоговый массив будет следующим:

Скрипт №2 — Дата для сравнения с датами массива

// Parameters
const LESSDAYS = 14 // За сколько дней ДО - предупреждать

// Получение даты для сравнения с датами в массиве
function getLessDays(){

  const today = new Date()
  today.setDate(today.getDate() + LESSDAYS)
  const resultDays = today.toLocaleString().split(',')[0]
  
  return resultDays;
}

Тут так же все просто:

  1. Получаю сегодняшнюю дату — const today = new Date()
  2. Прибавляю к ней количество дней LESSDAYS. Это необходимо для дальнейшего сравнения: если новая дата равна дате из основного массива — today.setDate(today.getDate() + LESSDAYS)
  3. Уже известный сплит — const resultDays = today.toLocaleString().split(',')[0] который возвращает новую дату в текстовом виде

Скрипт №3 — Фильтрация

// фильтрация общего массива на основании сравнения дат
function filteredDaysArr(){

  const fullArr = getAllData()
  const compareDays = getLessDays()

  const filteredArr = fullArr.filter(row => row[0] == compareDays)
  return filteredArr
}

Здесь я получаю результаты двух скриптов выше и фильтрую.

На выходе получаю отфильтрованный массив, который и буду отдавать телеграм-боту.

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

У этой записи 2 комментариев

  1. Максим

    Здравствуйте, подскажите, пожалуйста, почему при выводе массива в телеграмм, дата становится на 1 день меньше?

    К примеру дата: 11.02.2022, в телеграмм и в консоль, скрипт выводит 10.02.2022.

    1. Добрый день.
      Попробуйте потестировать даты независимо от скрипта
      например
      function testDates(){
      const today = new Date()
      console.log(today)
      today.setDate(today.getDate() + 14)
      console.log(today)
      }

      только что попробовал протестировать
      Информация Wed Feb 16 2022 11:21:29 GMT+0300 (Moscow Standard Time)
      вернул через 2 недели (+14 выше)
      Информация Wed Mar 02 2022 11:21:29 GMT+0300 (Moscow Standard Time)
      Вроде похоже, всё работает.

      Еще как вариант — посмотреть к какому элементу массива обращаетесь. У меня идет обращение к первому, который [0]

Добавить комментарий