Подписаться на блог

Текущая локация на странице

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

Самый первый вариант, который я рассматривал — по cron’у дергать “Find my phone” и ориентироваться на эти координаты, однако, этот вариант не особо мне понравился, ибо, во-первых, надо раскручивать API, которое может неожиданно поменяться, во-вторых, в моменты между городами cron также отрабатывает, и потом на сайте красуется какое-то неожиданное местоположение, но основная причина — сложно и ничего непонятно.

Второй вариант — сделать простой сервис с get и post ручками, развернуть его где-то в Heroku и все. Сервис я такой сделал, положил его на GitHub. Из интересного, post-метод работает через Telegram-бота — я просто кликаю кнопку и… все, ну и в MongoDB ведется лог местоположений, интересно будет потом посмотреть.

Интерфейс бота

Сервис работает как часы (еще бы одна RW-сущность плохо работала), хостится на Heroku. Осталось только интегрировать его с сайтом, но тут интересно, что сайт-то полностью статический, делать запросы лишние не очень хочется, ибо на Heroku инстансы поднимаются дольше, чем пользователи задерживаются на моем сайте. Потому все вынес в compile time, оказалось, из GraphQL все довольно удобно доставать.

В gatsby-nodes.js добавляем хук, создаем ноду в GraphQL

const fetch = require('node-fetch');
const config = require('../config');

exports.sourceNodes = async ({
  actions: { createNode },
  createContentDigest
}) => {
  const result = await fetch(config.locationUrl);
  const locationData = await result.json();

  createNode({
    ...locationData,
    id: 'author-location',
    parent: null,
    children: [],
    internal: {
      type: 'AuthorLocation',
      contentDigest: createContentDigest(locationData)
    }
  });
};

В компоненте страницы достаем это и рендерим.

query RootPage {
    authorLocation {
      city
      country
    }
}

В целом механизм работы такой:

  1. Отправляю боту местоположение.
  2. Он проверяет, что оно новое, сохраняет в MongoDB.
  3. Дергает webhook Netlify.
  4. Netlify стартует пересборку сайта.
  5. Gatsby делает запрос к сервису, получает новое местоположение.
  6. Сборка.
  7. Деплой.

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