Однажды мне захотелось узнать сколько активных пользователей у моего проекта. По сути это библиотека из Spotify API со множеством надстроек. Каждый пользователь копирует код к себе на Google аккаунт, чтобы запускать разные действия по расписанию через Apps Script. Например, удалить из плейлиста недавно игравшие треки.
Другими словами, мне нужно собрать статистику из множества копий библиотеки. Предположим, что существуют готовые решения. Например, некий сервис, который готов получать запросы и рисовать красивую графику. Почти наверняка он прибегнет к пробному периоду или ограниченному плану. Будет зарубежным, что вызовет трудности с оплатой. С другой стороны, я бы не хотел тратиться да и локального сервера у меня нет. Поэтому, даже не пытаясь искать готовых решений, подумал про Google Формы - бесплатно, без заметных ограничений, есть выход к Google Таблицам для графики.
У Google Форм есть API как REST, так и внутри Apps Script. Но только для принимающей стороны (создать формы, читать ответы). То есть нельзя отправить ответ от лица пользователя. Что же делает сам Google когда мы нажимаем отправить?
Где пригодится
В следующий раз мне понадобилось собрать небольшую статистику для другого проекта - андроид приложения для Яндекс.Музыки. Просто отправляю единичный запрос с помощью Retrofit при первой установке, чтобы знать сколько пользователей у приложения. Помогает, когда нет возможности опубликовать в Google Play или другом сторе.
Как видите, пригодилось при разных сценариях и платформах. Надеюсь, будет полезно и в ваших хобби-проектах.
Перепись пользователей прочитавших статью
Разберем пошаговый пример, а заодно узнаем кто "прочитал" статью.
Создаем свою форму с нужными полями. Для примера сделал два: имя и дата.
Открываем форму для ответа и заполняем поля их же названием. Не отправляем.
Открываем консоль браузера на странице формы (F12) и выполняем код:
var form = document.querySelector('form')
var formId = form.action.match(/e\/(.+)\/formResponse/)[1]
var entries = Array.from(form.firstChild.querySelectorAll('input'))
.filter(i => i.name.includes('entry'))
.map(i => ({ name: i.name, value: i.value }))
console.log('action =', form.action)
console.log('formId =', formId)
console.log('entries =', entries)
В результате получаем id формы и всех полей
[
{
"name": "entry.2096275148",
"value": "имя"
},
{
"name": "entry.1516955237",
"value": "дата"
}
]
Если скрипт не работает
Возможно со временем Google изменит разметку и скрипт сбора id сломается. На такой случай вам нужно открыть разметку страницы и найти элемент form
![Элемент form с нужными значениями Элемент form с нужными значениями](https://habrastorage.org/getpro/habr/upload_files/7ed/46b/950/7ed46b950f4bd0c95b0ae98bd73379d4.png)
Теперь остается отправить POST-запрос по адресу
action
с теломname1=foo&name2=bar
.В качестве примера, откройте консоль браузера на странице этой статьи (F12) и выполните следующий код. Вы отправляете свое имя (логин) на хабре и текущую дату. Результат можно посмотреть здесь.
sendForm(
'https://docs.google.com/forms/u/0/d/e/1FAIpQLSdZ7RMKGc3nes4s8FL0hwLpiel52gJT5_4tf0EjVIrL0jmICA/formResponse',
{
'entry.2096275148': await getMyHabrAlias(),
'entry.1516955237': new Date().toISOString(),
}
)
function sendForm(action, body) {
// corsUrl - только для отправки из консоли браузера,
// в остальных случаях напрямую action
let corsUrl = `https://cors-anywhere.herokuapp.com/${action}`
fetch(corsUrl, {
method: 'post',
body: new URLSearchParams(body),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': window.origin // для corsUrl
}
})
}
function getMyHabrAlias(defaultAlias = "guest") {
return new Promise((resolve) => {
fetch('https://habr.com/ru/top/daily/')
.then(response => response.text())
.then(html => {
try {
let raw = html.split('window.__INITIAL_STATE__=')[1].split(';(function()')[0]
let state = JSON.parse(raw)
resolve(state.me.user.alias)
} catch (error) {
console.error(`Не удалось получить alias. Дефолт = ${defaultAlias}`)
resolve(defaultAlias)
}
})
})
}
В результате мы заполнили и отправили форму с устройства пользователя без его непосредственного участия.
Да, вы, возможно, только что явно запустили скрипт, который отправляет логин с хабра. Но это только пример формирования запроса. В рамках приложения, библиотеки, расширения и других программ - действий со стороны пользователя нет.