Умное добавление музыкальных групп в Google Таблицы через VK API, Tampermonkey и Telegram бота

Как организовать хранилище музыкальных групп в Google Таблицах с поддержкой с разных программ?

Дано: Аккаунты в Google, VK, Telegram.
Задача: Создать хранилище музыкальных групп с возможностью удобного пополнения.
Инструменты: Google Apps Script (GAS), VK API, Tampermonkey, Telegram Bot API.

Создание Google Таблицы

Создаём новую Google Таблицу.
Делаем закреплённый заголовок (потом все циклы перебора ячеек из-за этого будут начинаться не с 0, а с 1).
В принципе наш шаблон готов.
Единственное, я не сделал привязку к колонкам через имена (не хотел использовать циклы), так что на протяжении всего скрипта буду обращаться к жёстко зашитому номеру колонки.

Жмём «Инструменты — Редактор скриптов».

Создаём 2 скрипта: Код.gs и Бот.gs.

Код.gs

access_token = '1111111111' // VK token ss = SpreadsheetApp.getActiveSpreadsheet() // Таблица sheet = ss.getSheets()[getNumSheet('Группы')] // Лист data = sheet.getDataRange().getValues() // Все ячейки numRows = sheet.getLastRow()+1 // Последняя строка faveTag = 'муз.группы' // Тег закладок в ВК  // Принимаем входящие get запросы function doGet(e) { try {     var link = e.parameters['link']     /*       A - Название       B - English       C - Ссылка       D - Город       E - Жанр       F - Описание       G - Примечание     */     var n = searchExists(link)     if (n != false) return ContentService.createTextOutput('Группа '+n+' уже есть!')     // Запрос в API VK https://vk.com/dev/groups.getById     var html = UrlFetchApp.fetch('https://api.vk.com/method/groups.getById.json?group_id='+link+'&fields=city,description&access_token='+access_token+'&v=5.107')     // Парсим в json первый элемент response     var json = JSON.parse(html).response[0]     addInTableFromArray(json, link)     sort()     return ContentService.createTextOutput('Добавлено')   } catch (e) {      return ContentService.createTextOutput('Ошибка из гуглотаблиц doGet! '+e)   } }  // Поиск стиля/жанра группы из описания по регулярке function searchGenre(txt) {   var t = txt.match(/(?:(?:стил[ь|я|ю|ем|е]|genre|жанр[а|у|ом|е]?)[\s:-]+){1}([a-zа-я\/-]+)/i)   if(txt != '' && t) return t[1] }  // Поиск русских букв в названии function isRus(txt) {   return txt.search(/[^A-Za-z0-9\/.:_]+/i) }  // Сортировка function sort(){   // Диапазон сортируемых ячеек от левой верхней до правой нижней   var tableRange = "A2:G"+numRows   var editedCell = sheet.getActiveCell()   var range = sheet.getRange(tableRange)   // Порядок сортировки по номеру столбца. Начинается не с 0, а с 1   range.sort([{      column : 4,     ascending: true   },{     column: 1,     ascending: true   },{     column: 2,     ascending: true   }]) }  // Поиск существующих групп function searchExists(t) {   for (var i = 1; i < data.length; i++) {     if (t == data[i][2] || 'club'+t == data[i][2]){       return data[i][0]+data[i][1]     }   }   return false }  // Подтягивание данных массово если их нет function addInfo(isBot = false) {   var arr = []   var j = 0   var part = 1000 // Кол-во символов, на которое будет делиться блок текста. Из-за ограничений в адресной строке и UrlFetchApp.fetch   arr[j] = new Array()   for (var i = 1; i < data.length; i++) {     var txt = data[i][2].replace('https://vk.com/','').replace('vk.com/','').replace('^club','')     if (txt != '' && data[i][0] == '' && data[i][1] == '' && data[i][3] == '' && data[i][4] == '' && data[i][5] == '' && data[i][6] == ''){       arr[j].push(txt)       if (arr[j].toString().length > part){         j++         arr[j] = new Array()       }     }   }   if (arr[0].length == 0){     if (isBot) return false     else{       SpreadsheetApp.getUi().alert('Нет групп, которые нужно дополнить')       return false     }   }   // Цикл по ссылкам   for (var t = 0; t < Math.ceil(arr.toString().length/part); t++) {     var html = UrlFetchApp.fetch('https://api.vk.com/method/groups.getById.json?group_ids='+arr[t].toString()+'&fields=city,description&access_token='+access_token+'&v=5.107')     var json = JSON.parse(html).response     if(json){       for (var i = 0; i < json.length; i++) {         var id = json[i].id         var link = json[i].screen_name         var name = json[i].name         var description = (json[i].description)?json[i].description:''         var city = (json[i].city)?json[i].city.title:''         var rus = (isRus(name) != -1)?"A":"B"             // Скрипт можно попробовать заменить на двумерный массив к arr         for (var j = 1; j < data.length; j++) {           var nameCell = data[j][2].replace('https://vk.com/','').replace('vk.com/','').replace('^club','')           if (nameCell == link || nameCell == id){             var num = j+1             break           }         }         sheet.getRange(rus+num).setValue(name.replace('=',''))         sheet.getRange("C"+num).setValue('=HYPERLINK("https://vk.com/'+link+'";"'+link+'")')         sheet.getRange("D"+num).setValue(city)         sheet.getRange("E"+num).setValue(searchGenre(description))         sheet.getRange("F"+num).setValue(description)       }     }   }   sort()   return true }  // Втянуть группы из закладок ВК function getVkFave(isBot = false) {   var idTag   var getTags = UrlFetchApp.fetch('https://api.vk.com/method/fave.getTags.json?access_token='+access_token+'&v=5.107')   var res = JSON.parse(getTags).response   var iTag = res.items   for (var i = 0; i < iTag.length; i++) {     if (iTag[i].name == faveTag) idTag = iTag[i].id   }      // Предупреждение   if (!isBot){     var ui = SpreadsheetApp.getUi()     var resp = ui.alert('После втягивания закладок с тегом "'+faveTag+'" они будут удалены из ВК. Продолжаем?', ui.ButtonSet.YES_NO)   }   var inside = function (){     var getPages = UrlFetchApp.fetch('https://api.vk.com/method/fave.getPages.json?tag_id='+idTag+'&fields=city,description&access_token='+access_token+'&v=5.107')     var iPage = JSON.parse(getPages).response.items     // Цикл по каждой закладке. Добавление в таблицу, удаление с ВК     for (var j = 0; j < iPage.length; j++) {       var gr = iPage[j].group       addInTableFromArray(gr)       numRows++         UrlFetchApp.fetch('https://api.vk.com/method/fave.removePage?group_id='+gr.id+'&access_token='+access_token+'&v=5.107')         Utilities.sleep(1000) // костыль     }     sort()   }   if (isBot) { // Костыль, потому что бот стопарится на ui     inside()   }else if(resp == ui.Button.YES) {     inside()   } }  // Добавление строки в таблицу function addInTableFromArray(arr, linkIn) {   if (linkIn){     var link = linkIn   }else{     var link = arr.screen_name     if (searchExists(link) != false) return false   }   var name = arr.name // Название   var description = (arr.description)?arr.description:'' //Описание   var city = (arr.city)?arr.city.title:'' // Город   // Если в тексте нет русских букв, значит пишем название в колонку "English"   var rus = (isRus(name) != -1)?"A":"B"   // Добавление строки в таблицу   sheet.getRange(rus+numRows).setValue(name.replace('=',''))   sheet.getRange("C"+numRows).setValue('=HYPERLINK("https://vk.com/'+link+'";"'+link+'")')   sheet.getRange("D"+numRows).setValue(city)   sheet.getRange("E"+numRows).setValue(searchGenre(description))   sheet.getRange("F"+numRows).setValue(description) } // Актуализировать ссылки. Единоразово. function checkActualLink(){   for (var i = 1; i < data.length; i++) {     try {       var num = i+1       UrlFetchApp.fetch("https://vk.com/"+data[i][2])       sheet.getRange('C'+num).setBackgroundColor('')     }catch(err) {       var num = i+1       sheet.getRange('C'+num).setBackgroundColor('red')     }   } } // Статус URL в строке. Запуск добавлением кода в ячейку function getStatusUrl(url){    var options = {      'muteHttpExceptions': true,      'followRedirects': false    }    var response = UrlFetchApp.fetch(url.trim(), options)    return response.getResponseCode() } //Поиск номера листа по имени function getNumSheet(nameList){   var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(nameList)   if (s != null) {     return s.getIndex()-1   }else{     return false   } } //Удалить спецсимволы function escapeHtml(text) {   return text       .replace(/&/g, "")       .replace(/</g, "")       .replace(/>/g, ""); } // Меню function onOpen() {   SpreadsheetApp.getUi()   .createMenu('Меню специальное')   .addItem('Сортировка', 'sort')   .addItem('Втянуть закладки из ВК', 'getVkFave')   .addItem('Дозаполнить пустые', 'addInfo')   .addToUi(); }  // Краткий вызов логирования function ll(t){   return Logger.log(t) } 

Бот.gs

var botApi = 'https://api.telegram.org/bot1123123:AAA/' // Токен Telegram бота  /* Команды:  /start - Начало работы бота  /sort - Сортировка  /getvkfave - Втянуть закладки из ВК   /addinfo - Дозаполнить пустые  /getall - Получить все группы */ function doPost(e){   var inp = JSON.parse(e.postData.contents)   // Логи   var sheet2 = ss.getSheets()[getNumSheet('Логи')]   sheet2.getRange('A1').setValue(inp)      var inpTxt = inp.message.text   var chatId = inp.message.chat.id      var link = inpTxt.replace('https://vk.com/','').replace('vk.com/','').replace('^club','')   // Команды бота   // start   if (inpTxt == '/start' || inpTxt == 'В начало'){     sendText(chatId, 'Бот заносит группы из ВК в Google таблицу.\n'+                     '/start - Начало работы бота\n'+                     '/sort - Сортировка\n'+                     '/getvkfave - Втянуть закладки из ВК\n'+                     '/addinfo - Дозаполнить пустые\n'+                     '/getall - Получить все группы')     return true   }   // sort   if (inpTxt == '/sort' || inpTxt == 'Сортировка'){     sort()     sendText(chatId, 'Отсортировано')     return true   }   // getvkfave   if (inpTxt == '/getvkfave' || inpTxt == 'Втянуть закладки из ВК'){     getVkFave(true)     sendText(chatId, 'Втянуто')     return true   }   // addinfo   if (inpTxt == '/addinfo' || inpTxt == 'Дозаполнить пустые'){     if (addInfo(true)) sendText(chatId, 'Дозаполнено')     else sendText(chatId, 'Нет групп, которые нужно дополнить')     return true   }   // getall   if (inpTxt == '/getall' || inpTxt == 'Получить все группы'){     var arr = [[],[],[],[],[],[],[],[],[],[],['В начало']] // TODO доделать     var repeat = ''     var n = 0     var j = 0     for (var i = 1; i < data.length; i++) {       if (j == 4){ // Количество на одной строке         n++         j = 0       }       if (repeat != data[i][3]){         arr[n][j] = data[i][3]         if (data[i][3] == '') arr[n][j] = '---'         j++       }       repeat = data[i][3]     }     var key = JSON.stringify({keyboard:                                arr,                               resize_keyboard:true,                               one_time_keyboard:true                             });     sendText(chatId, 'Выберите город', key)     return true   }      // Город   if (isRus(link) != -1) {     var name = (inpTxt == '---')?'Не заполнен':inpTxt     for (var j = 1; j < data.length; j++) {       if (data[j][3] == inpTxt || inpTxt == '---') {         var str = 'Город '+name+'\n\n'         for (var i = 1; i < data.length; i++) {           if ((data[j][3] == data[i][3]) || (data[i][3] == '' && inpTxt == '---')) {             if (str.length >= 4000) { // Ограничение на кол-во символов в сообщении Telegram бота               sendText(chatId, str)               str = ''             }             str = str + '<a href="https://vk.com/' + data[i][2] + '">' + escapeHtml(data[i][0] + data[i][1]) + '</a> \n'           }         }         if (str != '') sendText(chatId, str)         return true       }     }     sendText(chatId, inpTxt + ' - это не муз.группа и не команда бота')     return true   }   // Проверка на валидность   if (getStatusUrl('https://vk.com/'+link) != 200 && getStatusUrl('https://vk.com/club'+link) != 200){     sendText(chatId, inpTxt+' - битая ссылка')     return true   }      var name = searchExists(link)   if (name != false){     sendText(chatId, 'Группа '+name+' уже есть')     return true   }else{     var html = UrlFetchApp.fetch('https://api.vk.com/method/groups.getById.json?group_id='+link+'&fields=city,description&access_token='+access_token+'&v=5.103')     var json = JSON.parse(html).response[0]     addInTableFromArray(json, link)     sort()     sendText(chatId, 'Группа '+json.name+' добавлена')     return true   } } //Отправить сообшение боту function sendText(chatId, text, key = ''){   var payload = {     'method': 'sendMessage',     'chat_id': String(chatId),     'text': text,     'parse_mode': 'HTML',     'reply_markup': key,     'disable_web_page_preview': true,     'one_time_keyboard':true   }        var data = {     "method": "post",     "payload": payload   }   // для дебага комментируем UrlFetchApp.fetch и вставляем ll(text)   UrlFetchApp.fetch(botApi, data) } 

Подробнее разберём ниже.

Жмём "Опубликовать — Развернуть, как веб приложение".

Теперь у нас есть ссылка вида script.google.com/macros/s/AAA/exec, подставив к которой параметр «link», мы сможем занести группу ВК в Google Таблицу.

Юзерскрипты в браузере

Первый и основной способ занесения данных!

Открываем браузер Google Chrome или Mozilla Firefox и ставим плагин юзерскриптов Tampermonkey.
Ссылки для Хрома, для Мозиллы

Изначально пользовался Greasemonkey, но пришлось перейти на Tampermonkey из-за кроссбраузерности.
У кого возникнут вопросы, почему параметры юзерскрипта начинаются с префикса GM_, а не TM_ — идея не моя, идём в документацию.

Вставляем скрипт vkGroupToGS, нажав на первую вкладку с плюсиком.

vkGroupToGS

// ==UserScript== // @name         vkGroupToGS // @namespace    https://vk.com/* // @version      0.1 // @author       You // @match        https://vk.com/* // @grant        GM_xmlhttpRequest // ==/UserScript==     var url_first = 'https://script.google.com/macros/s/AAA/exec'     var url_short = document.location.href.replace("https://vk.com/", "")     var d = document.createElement('div')     var head = document.querySelector('.left_menu_nav_wrap')     d.setAttribute('id', 'send_group')     d.style.display = 'inline-block'     d.style.position = 'relative'     d.style.fontSize = '50pt'     d.style.cursor = 'pointer'     d.innerHTML = '+'     head.parentNode.appendChild(d)     d.onclick = function() {     setTimeout(function() {         GM_xmlhttpRequest({             method: 'GET',             url: url_first + '?link=' + url_short,             headers: {                 'Accept': 'application/atom+xml,application/xml,text/xml'             },             onload: function(x) {                 console.log(x.responseText)                 if (/Ошибка/.test(x.responseText)) document.querySelector('#send_group').style.color = 'red'                 else document.querySelector('#send_group').style.color = 'green'             }         })     }, 0) }; 

«Файл — Сохранить».

Как видим, наш скрипт рисует плюсик (на что хватило фантазии) в левом блоке left_menu_nav_wrap.

По нажатию на плюсик выполняется GM_xmlhttpRequest из vkGroupToGS в наш скрипт Код.gs по ссылке Google Таблицы, приложенной выше (url_first).

Tampermonkey запросит у нас связать эти 2 скрипта правами, жмём либо "Всегда разрешать" либо "Всегда разрешать домену" для "script.google.com". Повторить при надобности для "script.googleusercontent.com".

Как только запрос успешно улетит, придёт колбэк из GM_xmlhttpRequest и окрасит нашу кнопку в зелёный цвет при удачном добавлении либо в красный если вернулась ошибка.

Плюс Tampermonkey — облачное хранение скриптов в Google (раньше не было) при наличии их плодовитости и своего воображения.

Вернёмся к Google Таблице.
Перед тем, как начать разбирать наш Код.gs я хочу поделиться документацией для разработки в ВК — vk.com/dev

Токен ВК

Получение ключа доступа
Выполнение запросов к API ВКонтакте

Пока научился только одним способом добывать токен — через самописные приложения.

Заходим сюда.
Платформа — "Standalone-приложение".
После создания всё, что нам надо — это ID приложения (ныне семизначный), пусть будет 1234567.
Но нам нужен токен.
Очень хорошо про токен написано в Знакомстве с API ВКонтакте.
Если не хотим читать, просто открываем ссылку, вставляя в client_id свой ID приложения.

Нас редиректит на страничку с надписью:

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

И это верно, будьте очень аккуратны с токеном!

Токен копируем из адресной строки после access_token.

Сразу поделюсь, что с этим токеном можно запросы вида vk.com/dev/groups.search?params%5Bq%5D=%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0&params%5Btype%5D=page&params%5Bcountry_id%5D=1&params%5Bcity_id%5D=1&params%5Bfuture%5D=0&params%5Bmarket%5D=0&params%5Boffset%5D=0&params%5Bcount%5D=10&params%5Bv%5D=5.107

можно спокойно преобразовывать в ссылки api.vk.com/method/groups.search?q=%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B0&type=page&country_id=1&city_id=1&future=0&market=0&offset=0&count=10&access_token=1111111111111&v=5.107 и получать информацию в любом приложении.

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

Конечно с определёнными ограничениями, допустим не больше 999 сущностей в ответе или 20 запросов в секунду и т.п.

Также кому-нибудь будет интересно поиграться с хранимками — в нашем приложении вкладка "Хранимые процедуры".
Там есть свои правила вытягивания информации, очень удобно для последовательных запросов, чтоб не делать множество циклов у себя в коде.

Следим за версиями!
С их изменениями может меняться функциональность методов. Ныне прикладываю примеры для версии 5.107.

Итак, токен у нас есть, переходим к…
Код.gs

doGet(e) — Принимаем входящие get запросы от бота, ВК и просто с браузера.
Входные параметры парсятся, как e.parameters[‘ВХОДНОЙ_ПАРАМЕТР’]
Прилетает ссылка, проверяем, есть ли в таблице. Если нет, запрашиваем подробную информацию через groups.getById, парсим, добавляем.
! Внимание! Скрипт простой, так что будет проглатывать все прилетающие ссылки, так что будьте аккуратны даже введя 123 при проверке скрипта.
searchGenre — умный поиск стиля/жанра группы, из-за которого я и поставил метку «регулярные выражения» в статье.
Возможны улучшения.
Пока работает только на поиск последующей цепочки слов через слеш или дефис после слов "стиль или жанр или genre".
isRus — простая регулярка, исключающая русские буквы.
sort — сортировка. Поставил по умолчанию — 1. город, 2. название.
searchExists — простой поиск существующих групп через цикл.
addInfo — сделал скрипт для себя, оставил здесь, как бонус. Нужен если у вас есть список ссылок, но нет по ним данных.
Вставляем список в колонку «Ссылка», жмём "Дозаполнить пустые" в главном меню и остальные колонки дозаполняются из ВК.
Из-за ограничений на количество символов в UrlFetchApp.fetch и в количестве ссылок, помещаемый в адресную строку пришлось сделать цикл по 1000 символов.
getVkFave — ещё один бонус, возникший в голове во время написания статьи и которым я сам стал пользоваться.
Суть — заходим с телефона в приложение ВК, натыкаемся на группу, которую хотим сохранить, сохраняем её в закладках с заранее добавленной меткой "муз.группы" (глобальная переменная faveTag).
Как они накопятся, заходим в нашу Google Таблицу, вызываем меню, жмём "Втянуть закладки из ВК".
Скрипт с токеном лезет в api.vk.com/method/fave.getTags, парсит, добавляет в таблицу, предварительно предупредив об удалении из ВК (тут аккуратней с тестированием, всё удаляется подчистую с закладок с этим тегом).
getStatusUrl и checkActualLink — эксперимент, вылившийся в 2 скрипта.
Суть — проверять валидность и доступ до ссылок.
Потому что за годы накопления музыкальных групп я столкнулся с тем, что паблики удаляют либо переименовывают.
Кто будет пользоваться моей удобняшкой, советую некое TODO, которое будет не просто удалять невалидные ссылки, но и проверять через groups.search по названию наличие в ВК.
checkActualLink — единоразово проверяет валидность, окрашивая в красный невалидные.

  • Минус — низкая скорость.
  • Плюс — выполнять можно, когда захочется.

getStatusUrl — вызывается в ячейке через скрипт

=getStatusUrl(CONCAT("https://vk.com/";C2))

Основу взял отсюда.

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

Далее идут удобняшки для гуглоскриптов:
addInTableFromArray — Добавление строки в таблицу. Либо с цикла либо единоразово.
getNumSheet — Поиск номера листа по имени. Честно, не нашёл в интернете способа проще, чем этот. Нужен из-за смещения номеров листков при добавлении новых. Основу взял отсюда.
escapeHtml — Удалить спецсимволы
ll — для себя сделал Logger.log кратким, сокращает время, советую.
onOpen — Всем знакомая функция для отрисовки меню в Google Таблице.

Итак, наш Код.gs ловит ссылки с ВК через Tampermonkey и добавляет группы в Google Таблицу.

ВКЛЮЧАЕМ ЛЕНЬ

  • Мы сидим за компьютером.
  • Мы сидим в телефоне.

С компьютера мы научились добавлять группы через "плюсик" в ВК и через закладки.
Через телефон только через закладки в приложении ВК.

Разберём ещё два варианта внесения групп.

USI

Юзерскрипты в мобильном браузере.
Кому-то он покажется старомодным и ненужным, но найдутся те люди, которые вынесут плюсы из него.
Поискав в интернете нашёл пока только такой плагин.
Работает только в Firefox (тестировал только в android).
Огромный плюс — можно использовать скрипт Tampermonkey.
Из-за отличий вёрстки между vk.com и m.vk.com, а также из-за открывания окна по умолчанию в m.vk.com я не стал рисовать плюсик, а сделал простой скрипт VK_event_to_list_mvk, срабатывающий при открытии окна (гореть мне в аду за setTimeout, знаю).

Код.gs

// ==UserScript== // @name         VK_event_to_list_mvk // @namespace    https://m.vk.com/* // @match        https://m.vk.com/* // @grant    GM_xmlhttpRequest // ==/UserScript== setTimeout(function() {     var url_first = 'https://script.google.com/macros/s/111/exec';     var url_short = document.location.href.replace("https://m.vk.com/", "");     GM_xmlhttpRequest({         method: 'GET',         url: url_first + '?link=' + url_short,         headers: {             'Accept': 'application/atom+xml,application/xml,text/xml'         },         onload: function(x) {             alert(x.responseText);         }     }); }, 2000); 

Telegram Бот

Создаём бота по инструкции.
Нам нужен токен, пусть он будет 123123.
Создаём скрипт Бот.gs, вставляем в переменную botApi наш 123123, обрамляя кавычками и ссылкой api.telegram.org.
Далее надо сцепить нашего бота с Google Таблицей. Посмотреть, как это сделать через WebHook можно в предыдущей статье.

Что будет делать наш бот?
Разложим по командам:

  • /start — Начало работы бота
  • /sort — Сортировка
  • /getvkfave — Втянуть закладки из ВК
  • /addinfo — Дозаполнить пустые
  • /getall — Получить все группы

Видим, что у нас есть начало работы бота, туда мы вставим просто tutorial с описательной частью на ваше усмотрение.
Три команды из главного меню на всякий случай.
И очередной бонус — /getall, о нём ниже.

Команды для удобного вызова (в строке ввода сообщения написать слеш) можно добавить в том же @BotFather через /setcommands.
Формат — строки через тире:

start - Вернуться в начало sort - Сортировка getvkfave - Втянуть закладки из ВК addinfo - Дозаполнить пустые getall - Получить все группы

Бот.gs
doPost — принимает входящие сообщения от бота.
Естественно, как пытливый программист, я сразу начал использовать логи. Возможно есть способы проще, но я просто создал новый лист, назвал его «Логи» и ловлю в первую ячейку входящие запросы.
Поэтому после того, как мы распарсили входящее сообщение через JSON.parse(e.postData.contents), сразу пишем в логи.
Далее определяем, какая из команд нам пришла.
Если не команда, проверяем на валидность, то есть существует ли группа в ВК.
sendText — отправляет сообщения боту (по умолчанию parse_mode = HTML), документация.

/getall — разберём отдельно.
Пусть вас не пугает моё решение из

[[],[],[],[],[],[],[],[],[],[],['В начало']]

Сделано для заполнения строчек городами, пока ограничимся 8-10 строчками по 4 города (переменная j = 4).
Если музыкальная группа без города, вставляем —.
Просто выбираем город и ловим русские буквы в Бот.gs.
Выводим список ссылок, ничего более.

Помним, что доступ к документации и тестированию бота через адресную строку через Hotspot Shield Free VPN Proxy — Unlimited VPN (для Google Chrome).

Вот мы и изучили три способа внесения в нашу таблицу:

  • Юзерскрипты в браузере
  • Юзерскрипты в мобильном браузере (USI)
  • Telegram Бот

Что нужно знать и помнить?

Префикс club в ссылках ВК
В группах ВК есть 2 типа хранения идентификатора.

  1. Название на английском с допустимыми подчёркиваниями и дефисами.
  2. ID

Причём выкладываться могут и так и так.
Проверить просто.
Если есть группа, допустим vk.com/4soulsband, подставляем 4soulsband в group_ids в vk.com/dev/groups.getById, выводится перечень параметров, один из которых ID. И если мы перед ним поставим club, вуаля, попадаем на ту же страницу vk.com/club68130764.

Ограничение на хранение групп в ВК до 5000
Кажется смешным, но мне не хватило.

Моя боль с обновлением страницы ВК
Каюсь, пока не смог победить отлов перехода между страницами в ВК для сброса состояния плюсика в Tampermonkey. TODO

Использование Google Таблиц, как БД

  • Плюс — доступность
  • Минус — когда копится больше 5000 строк, работа с "БД" замедляется. Так что для серьёзных проектов лучше использовать нормальные СУБД.

Определение города группы
Адрес группы в ВК может быть тут vk.com/dev/groups.getAddresses, соответственно кто захочет улучшить поиск города для группы, может использовать его.

Итог

У нас есть:

  1. Google таблица для сбора данных, с которой мы научились работать.
  2. Знания по VK API. То есть вы уже в курсе, что мы можем не ограничиваться музыкальными группами.
  3. Telegram Бот с БД, которую не нужно разворачивать и настраивать.

Моя цель не кичиться очередной созданной игрушкой, моя цель показать новичкам (и не только) огромный пласт открытых API`шек, которые помогут облегчить жизнь в той или иной степени, перенестись с железной земли в «облака», так сказать.
Данный функционал готов, как и открыт для улучшений.
Удачи в разработке и постижении новых знаний.

Документация

Google Apps Script — Spreadsheet Service
Telegram Bot API
VK API
Учимся писать userscript’ы
Userscripts. Углубляемся
Мониторинг сайта с помощью Google Docs
Баловство. Пишем Telegram бота на Google script
[Примеры, Google Apps Script] Разработка дополнений/скриптов для Google Таблиц (spreadsheets)
How to use google spreadsheets to check for broken links

ссылка на оригинал статьи https://habr.com/ru/post/504664/

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *