Наша собственная статистика посещений включена всегда. Google Analytics помогает нам понять, как пользуются нашими публичными страницами (но не вашим рабочим пространством после входа), и включается только с вашего разрешения. См. нашу политику конфиденциальности.

API отзывов Google Maps: как выбрать правильную точку входа и фиксировать отзывы о местах

Разберитесь в различиях между Business Profile, Places API и получением отзывов о местах через EveryInfra, проверяйте идентификацию места, язык и фильтры по времени, сохраняйте изменения оценок и ответов владельца и чётко задавайте границы выборки, хранения и показа.

Фраза «Хочу получать отзывы из Google Maps» может означать три разные задачи: управление отзывами о собственных точках, показ информации о месте в продукте или исследование отзывов пользователей по группе мест. Во всех трёх случаях речь идёт об отзывах, но права доступа, эндпоинты и правила хранения у них разные. Неверно выбранную точку входа потом не исправить ни увеличением числа запросов, ни сменой способа разбора.

Сначала это руководство поможет выбрать сценарий работы, а затем на примере google_maps_reviews.reviews из EveryInfra покажет, как проверять места, составлять небольшие запросы, обрабатывать оценки и ответы владельца и организовать регулярное наблюдение. Главное — однозначно соотносить каждую запись с нужным местом и объяснять пропуски в выборке, а не обещать выгрузку всех исторических отзывов по любому месту.

Каталог и реализация проверены на 2026-09-04. Платные запросы, упомянутые в тексте, в этот раз не выполнялись; синтетические записи в коде нужны только для демонстрации проверки изменений значений полей. Используйте шаблон в продакшене только после того, как подтвердите права на конкретные сценарии получения, обработки, хранения и показа данных.

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

Если вам нужно управлять точками, на которые у вас есть права, сначала изучите Google Business Profile API. В официальных руководствах операции чтения отзывов и ответов владельца организованы по аккаунтам и местам, а для интеграции нужны регистрация приложения и учётные данные OAuth. Отвечайте на отзывы пользователей с соответствующими правами управления, а не отправляйте универсальный запрос на запись по произвольной ссылке на карту.

Функция deleteReply в официальных руководствах удаляет ответы владельца, а не исходные отзывы пользователей. Для рабочих процессов это важно: удаление ошибочного ответа, который написали вы, и обработка неприемлемого отзыва пользователя проходят по разным процедурам, поэтому пример с DELETE не стоит использовать не по назначению.

Чтобы показывать информацию о месте в продукте, используйте эндпоинт Place Details в Google Places API. Он запрашивает данные по ID места и выбирает нужные поля через FieldMask; этот способ показа нельзя напрямую использовать как интерфейс массовой выгрузки всех исторических отзывов. При использовании контента Places также нужно соблюдать требования к кешированию, хранению и указанию авторства.

EveryInfra предлагает отдельный способ получать отзывы: платформа — google_maps_reviews, действие — reviews, а на вход передаётся URL места. В следующих разделах описан только этот способ получения данных. В них нет примеров изменения профилей компаний, публикации ответов или удаления, и этот способ не называется официальным API Google.

Выбор стороннего интерфейса не снимает ограничений на использование данных. Дополнительные условия Google Maps ограничивают копирование, повторное распространение и массовое скачивание, а у Places API есть собственные правила использования контента. Сам факт, что один запрос вернул данные, не означает, что их разрешено долго накапливать, перепродавать в больших объёмах или произвольно показывать повторно. Если планируемое использование выходит за разрешённые рамки, скорректируйте план, а не пытайтесь с помощью технических средств обойти лицензионные ограничения.

Если нужны точные параметры официального интерфейса управления профилем компании, обратитесь непосредственно к reviews.list: этот метод работает с аккаунтом и местом и возвращает список отзывов, общую среднюю оценку, общее количество отзывов и токен следующей страницы. Эта структура показывает, почему «количество записей, полученных на этой странице» и «общее количество отзывов о месте» нужно учитывать отдельно. Не считайте, что EveryInfra поддерживает те же поля и правила пагинации.

Шаг 1. Определите место однозначно, а не только по названию магазина

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

Сохраняйте полный URL места, использованный в запросе, вместе с достоверно полученным place_id. Объединяйте данные только после подтверждения, что они относятся к одному и тому же месту; не объединяйте отзывы о двух магазинах только из-за географической близости, одинаковых названий или сходства строк. Добавляйте неподтверждённые объекты в чек-лист для проверки, чтобы при последующем анализе данные ошибочно определённого магазина не приняли за тенденции в жалобах.

Текущая реализация использует сведения из URL, позволяющие идентифицировать место, но не все форматы URL карт одинаково подходят для выбора целевого места. Ссылки, содержащие только название магазина и координаты области просмотра карты, сами по себе нельзя считать подтверждёнными идентификаторами места. Сохраняйте проверенные полные исходные ссылки, а не составляйте URL-заглушки, лишь похожие на ссылки на страницы карты.

Здесь тоже есть граница интерфейса: внутри реализация распознаёт некоторые данные о месте, но в публичных запросах нельзя добавлять произвольные параметры placeId или place_id. Сейчас обязательный параметр действия reviews — url, и клиенты должны передавать параметры в соответствии с публичной документацией.

Шаг 2. Проверьте язык, сортировку и временные ограничения

Посмотреть только текущее описание Google Maps reviews
curl -fsS --max-time 30 \
  'https://api.everyinfra.com/api/v1/social/catalog?platform=google_maps_reviews' \
  | jq -e '.capabilities[] | select(.action == "reviews") | {
      platform, action, required_params, optional_params, param_meanings,
      mode, returns_list, default_limit, max_limit, response_fields
    }'

Для этого каталога параметр url обязателен. Результат возвращается синхронно в виде списка: по умолчанию 20 записей, не более 100. Поддерживаются необязательные параметры lang, language, since и sort. Точный идентификатор платформы — google_maps_reviews; не заменяйте его сокращённым идентификатором другой платформы, ориентируясь на заголовки статей.

newest и relevance соответствуют разным целям сортировки: newest выбирает свежий контент, а relevance формирует выборку по релевантности. Полученные выборки не взаимозаменяемы. При сравнении торговых точек используйте единые критерии отбора и сохраняйте идентификаторы фактически полученных отзывов; смена порядка сортировки может изменить состав выборки.

Поля языка не фильтруют отзывы по национальности или месту проживания автора. Допустимые значения lang определяются перечислением интерфейса (сейчас это en, zhcn и zhtw), и не стоит подставлять произвольные коды языков по общим описаниям. Не заполняйте lang и language одновременно вслепую: в текущем сопоставлении lang переопределяет language, поэтому в первой реализации выберите один явно поддерживаемый вариант.

since задаёт нижнюю границу для даты публикации отзывов, а каталог рекомендует использовать формат YYYY-MM-DD. Это не дата открытия компании, не метка времени обновления отзывов и не надёжный курсор, показывающий ход обработки. При необходимости используйте since как условие фильтрации и отдельно сверяйте граничные даты с фактическими результатами.

Шаг 3. Проверьте небольшую выборку результатов для места, с данными которого вам разрешено работать

Предположим, на сервере заданы EVERYINFRA_API_KEY и подтверждённый EVERYINFRA_MAPS_PLACE_URL. Каждый пример отправляйте только один раз и указывайте limit внутри params: на корневом уровне запроса он не управляет числом записей.

Шаблон минимального запроса отзывов о месте
: "${EVERYINFRA_API_KEY:?set the API Key first}"
: "${EVERYINFRA_MAPS_PLACE_URL:?set the authorized full place URL first}"
jq -cn --arg url "${EVERYINFRA_MAPS_PLACE_URL}" '{
  platform: "google_maps_reviews",
  action: "reviews",
  params: {url: $url, sort: "newest", limit: 3}
}' | curl --silent --show-error --include --max-time 180 \
  'https://api.everyinfra.com/api/v1/social' \
  -H "Authorization: Bearer ${EVERYINFRA_API_KEY}" \
  -H 'Content-Type: application/json' --data-binary @-

limit: 3 задаёт небольшую выборку для тестирования; это не гарантирует, что вернутся ровно три записи, и не означает, что у места всего три отзыва. 180 секунд приведены как пример допустимого времени ожидания на стороне клиента, а не как гарантия сервиса. Сначала проверьте HTTP-статус и ошибки, затем убедитесь, что поле results содержит ожидаемый список и что этот список относится к целевому месту.

Пустой массив нельзя сразу трактовать как «у этого магазина нет отзывов». Такой результат может означать сбой получения данных в текущем вызове или необходимость проверить цель, фильтры и доступность. Пока реальная причина неясна, сохраняйте статус «неизвестно». Если у клиента истёк тайм-аут, не повторяйте POST-запрос автоматически, предполагая, что предыдущая попытка не выполнилась и не была оплачена.

Шаг 4. Разделяйте оценку места, оценки отдельных отзывов и ответы

Текущие поля записи: id, text, rating, rating_scale, posted_at, place_id, place_name, owner_response и owner_response_at. Средняя оценка в данных о месте и оценка отдельного отзыва представляют разные объекты; не копируйте среднюю оценку точки в каждый отзыв, чтобы заполнить пустые значения.

Значения полей отзыва
curl -fsS --max-time 30 \
  'https://api.everyinfra.com/api/v1/social/fields?platform=google_maps_reviews&action=reviews' \
  | jq '{fields, undocumented}'

Оценку и основной текст тоже нужно обрабатывать раздельно. Запись только с оценкой без текста может пригодиться для выборки оценок, но её нельзя напрямую подавать в тематическую классификацию текстов. Если rating отсутствует, сохраняйте статус «неизвестно»; при сравнении между платформами учитывайте rating_scale вместе с оценками и не усредняйте числа по разным шкалам.

Поле detailed_rating, если оно возвращается, содержит оценки по отдельным параметрам, но не стоит предполагать, что у всех мест и отзывов набор параметров одинаков. is_local_guide и число прошлых отзывов автора нельзя напрямую считать подтверждением «реального пользователя» или оценкой достоверности. Это атрибуты, предоставляемые платформой, а не проверка фактической точности конкретного отзыва.

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

Шаг 5. Ведите отдельные записи для идентификации, наблюдений и изменений

  • Идентификация места: подтверждённый place_id, ссылки на источники и сведения о принадлежности места компании. Сначала выявляйте дубли по идентификаторам, а не объединяйте места приблизительно по совпадению названий.
  • Идентификация отзыва: сочетание ID места и ID отзыва; записи без надёжных ID обрабатывайте отдельно и не используйте никнейм автора отзыва как уникальный ключ.
  • Журнал наблюдений: ID запроса, фактическое время сбора, параметры сортировки, языка и даты, полученные поля и отсутствующие элементы.
  • Журнал изменений: наблюдаемые различия в тексте, оценке или ответе владельца для одного и того же отзыва; неизвестные поля не трактуются как удаление.

Сохраняйте поля, нужные для сравнения, только в разрешённых рамках и на разрешённый срок. Если текст хранить нельзя, сведите записи к минимальному разрешённому объёму данных и не оправдывайте бессрочное хранение «удобством аудита». В следующем разделе на примере вымышленных мест, отзывов и текстов показано, как отличать изменения значений, впервые полученные поля и неполученные данные.

Офлайн-обработка на JavaScript: отсутствие поля не означает удаления
function compareReview(before, after) {
  const identity = row => {
    if (typeof row.place_id !== "string" || !row.place_id
        || typeof row.id !== "string" || !row.id) {
      throw new Error("place and review ids required");
    }
    return JSON.stringify([row.place_id, row.id]);
  };
  if (identity(before) !== identity(after)) throw new Error("different review");
  const t0 = Date.parse(before.observed_at);
  const t1 = Date.parse(after.observed_at);
  if (!Number.isFinite(t0) || !Number.isFinite(t1) || t1 <= t0) {
    throw new Error("observations must have increasing times");
  }
  const changed = [], firstObserved = [], notObserved = [];
  for (const field of ["text", "rating", "owner_response", "owner_response_at"]) {
    if (!Object.hasOwn(after, field) || after[field] == null) {
      notObserved.push(field);
    } else if (!Object.hasOwn(before, field) || before[field] == null) {
      firstObserved.push(field);
    } else if (before[field] !== after[field]) {
      changed.push(field);
    }
  }
  return {changed, firstObserved, notObserved};
}

console.log(compareReview(
  {place_id: "synthetic-place", id: "synthetic-review",
   text: "synthetic review", rating: 3, observed_at: "2026-09-01T00:00:00Z"},
  {place_id: "synthetic-place", id: "synthetic-review",
   text: "synthetic review", rating: 3, owner_response: "synthetic reply",
   observed_at: "2026-09-02T00:00:00Z"}
));

В этом примере owner_response записывается как firstObserved, а не как новый отзыв; если время ответа отсутствует, фиксируется notObserved. Даже если text попал в changed, это лишь значит, что тексты, полученные в двух запросах, различаются, и причиной может быть перевод или изменение представления; без подтверждающих данных никогда не утверждайте, что пользователь отредактировал исходный текст.

Хронологическая проверка не позволяет старым записям наблюдений перезаписать более новые, но не доказывает, что данные на сервере актуальны в реальном времени. Записанное вами observed_at отражает момент, когда вы увидели ответ, а не время обновления полей на платформе.

При сохранении записей наблюдений из разных часовых поясов используйте форматы времени RFC 3339 с указанием смещения, а исходные значения храните отдельно. Единый формат упрощает сравнение моментов времени, но не превращает время наблюдения во время обновления отзыва и не расширяет охват текущего получения данных.

Шаг 6. При инкрементальном наблюдении объясняйте охват, а не просто сдвигайте даты

Непрерывный мониторинг позволяет на разрешённых условиях многократно наблюдать фиксированный набор мест, оставлять перекрытие диапазонов в фильтрах по дате и устранять дубли по идентификации отзыва. Длина окна перекрытия зависит от наблюдаемых запаздывающих записей и частоты задач; универсальное число дней нельзя вывести напрямую из небольших выборок.

Однако окна перекрытия не устраняют все пропуски: в каждой выдаче число записей ограничено, к старым отзывам позже могут добавиться ответы владельца, а сортировка меняет возвращаемую выборку. Главное: не рассчитывайте, что since захватывает все обновлённые старые отзывы. Он фильтрует по времени публикации и не является полным потоком изменений.

При каждом запуске фиксируйте запланированные к проверке места, места с полученными записями, места с ошибкой или неизвестным статусом и число возвращённых записей по каждому месту. Чтобы обсуждать охват, нужно знать рамки сбора, сортировку и условия усечения; делить число возвращённых записей на неизвестный общий объём ради якобы точного процента охвата некорректно.

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

Шаг 7. Для анализа, внутренней обработки и публичного показа нужны разные права

Выбор языка может влиять на представление контента, но не гарантирует, что каждый возвращённый отзыв содержит исходный текст на этом языке. Перевод и оригинал не являются двумя независимыми мнениями пользователей; в результатах анализа фиксируйте применённые языковые условия, а расхождения между языками оставляйте на ручную проверку.

При публичном показе через Places API выполняйте требования к указанию авторства контента, сведениям об авторе и ссылкам на источник согласно действующим правилам, а не копируйте текст на свои страницы. Если данные получены другим способом, заранее определите применимые лицензии и не применяйте и не отменяйте автоматически требования Places. Примеры с хранением в памяти в этом документе не дают разрешения на хранение или повторное распространение.

Для внутреннего анализа в первую очередь обрабатывайте только поля, критичные для задачи, ограничивая круг лиц с доступом и сроки хранения; классификации и уровни срочности, выданные моделью, помечайте как производные суждения. Система может формировать очереди на ручную проверку, но низкие оценки не должны запускать автоматические ответы, публичные обращения к авторам или изменение рабочего статуса магазина.

Полностью проверьте одно место, прежде чем масштабировать процесс

После первой итерации интеграции вы должны уметь объяснить: почему у вас есть право обрабатывать этот набор данных, какой магазин был целью, какие варианты сортировки и языка выбраны, какие поля подтверждены, как выявляются изменения ответов и чего не хватило в этом прогоне. Вы также должны уметь связывать проблемы с ID запросов и проверять фактические списания, а не оставлять файл с отзывами без сведений об их происхождении.

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

Справочник LF-05