Как стать автором
Обновить

Как отправить Google Форму без участия пользователя

Время на прочтение3 мин
Количество просмотров3.3K

Однажды мне захотелось узнать сколько активных пользователей у моего проекта. По сути это библиотека из Spotify API со множеством надстроек. Каждый пользователь копирует код к себе на Google аккаунт, чтобы запускать разные действия по расписанию через Apps Script. Например, удалить из плейлиста недавно игравшие треки.

Другими словами, мне нужно собрать статистику из множества копий библиотеки. Предположим, что существуют готовые решения. Например, некий сервис, который готов получать запросы и рисовать красивую графику. Почти наверняка он прибегнет к пробному периоду или ограниченному плану. Будет зарубежным, что вызовет трудности с оплатой. С другой стороны, я бы не хотел тратиться да и локального сервера у меня нет. Поэтому, даже не пытаясь искать готовых решений, подумал про Google Формы - бесплатно, без заметных ограничений, есть выход к Google Таблицам для графики.

У Google Форм есть API как REST, так и внутри Apps Script. Но только для принимающей стороны (создать формы, читать ответы). То есть нельзя отправить ответ от лица пользователя. Что же делает сам Google когда мы нажимаем отправить?

Где пригодится

В следующий раз мне понадобилось собрать небольшую статистику для другого проекта - андроид приложения для Яндекс.Музыки. Просто отправляю единичный запрос с помощью Retrofit при первой установке, чтобы знать сколько пользователей у приложения. Помогает, когда нет возможности опубликовать в Google Play или другом сторе.

Как видите, пригодилось при разных сценариях и платформах. Надеюсь, будет полезно и в ваших хобби-проектах.

Перепись пользователей прочитавших статью

Разберем пошаговый пример, а заодно узнаем кто "прочитал" статью.

  1. Создаем свою форму с нужными полями. Для примера сделал два: имя и дата.

  2. Открываем форму для ответа и заполняем поля их же названием. Не отправляем.

  3. Открываем консоль браузера на странице формы (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 с нужными значениями

  1. Теперь остается отправить 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)
        }
      })
  })
}

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

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

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 4: ↑2 и ↓20
Комментарии5

Публикации

Истории

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн