Подводные камни в API Google Analytics

Попросил меня как-то раз очень давний знакомый написать ему небольшое веб-приложение по обработке отчетов полученных через API Google Analytics. Конечно сервисы Google, вещи то серьезные и соответственно ничто не предвещало никаких проблем.

Разработку предполагалось производить на PHP версии 5.2. После успешной находки пары примеров на PHP по взаимодействию с API Google Analytics и скачиванию уже разработанного клиента для работы с самим API, я начал разбираться, как и что работает. Пришлось для начала активировать сервис API Google Analytics и зарегистрировать приложение, ну а затем привязать его к своему аккаунту. Затем после небольшой модификации найденного мною примера исходного кода выяснилось, что нужна версия PHP 5.3. Хотя в документации было указано, что требуется использовать версию PHP 5.2.x или выше. Но и сотрудники службы поддержки Google заявляют тоже о необходимости использования PHP версии 5.3. Да, эта новость, конечно, не принесла радости, но все же было принято решение PHP обновить. Тем более что раньше уже было подобное желание, а тут еще и стимул появился.

Ну, а теперь-то точно все требования выполнены и соответственно работа должна была пойти на “ура”. Но не тут то было. Теперь стали происходить довольно странные вещи. Ну, к примеру: начал “вылетать” веб-сервер Apache. Так как новый Denwer 3 был только что установлен, поэтому было подозрение на то, что что-то “криво” установилось. Но в тоже время Denwer 3 давно был “обкатан” и соответственно в теории никой бреши в нем быть не могло. Но для того чтобы возникала такая ошибка, при которой смог бы “вылететь” сам Apache, должно произойти нечто серьезное. Поэтому было принято решение запускать скрипт через консоль. Но и это желаемого успеха ни принесло.

Возможные проблемы и методы их решения

При работе с API Google Analytics первое, на что требуется обратить внимание так это на идентификатор PROFILE ID. Дело в том, что идентификатор PROFILE ID это не идентификатор аккаунта, а идентификатор представления. Изначально я ошибся, указав неверный идентификатор.

Повторный запуск скрипта, c уже верно указанным идентификатором PROFILE ID снова оказался безуспешным. На этот раз появилась следующая ошибка:

Fatal error: Uncaught exception ‘Google_AuthException’ with message ‘Error refreshing the OAuth2 token, message: ‘{ «error» : «invalid_grant» }’

Ну вот, здесь время на поиски данной проблемы затянулось на очень долгое время. Как оказалось – данная ошибка была довольно известная. И поиски информации по ее решению успехов не принесли. Иногда конечно встречались темы, в которых люди писали, что им удалось решить эту проблему, но итогового решения нигде найдено не было. Время шло, а проблема еще оставалась. В итоге я уже сменил версию клиентской библиотеки для работы с API. Т.е. начал перебирать возможные варианты решения данной проблемы.

Но в один момент у меня появилась идея о размещении разрабатываемого для тестов скрипта на хостинге. И на мое удивление скрипт заработал. Ситуация уже начала обрастать загадками. А еще более загадочной она стала после того, как данный скрипт был размещен на виртуальном сервере и тоже оказался работоспособным. Да, ситуация стала странной как никогда. У меня возникло подозрение, что возможно нечто происходит в самом HTTP запросе. Но если на локальной машине его перехватить можно, то на сервере придется напрячься. Поэтому был выбран вариант по легче – немного модифицировать код клиентской библиотеки, чтобы иметь возможность просматривать весь лог HTTP запроса. Но после сравнения лога файлов скриптов, запущенных с локальной машины и сервера, выяснилось, что они ничем не отличаются (кроме значения POST параметра “assertion_type»). Но это не являлось существенно-важным результатом. Так как для шифрования значения параметра “assertion_type», требуется получать текущее время, то конечно данные в обоих логах совпасть не могут. Соответственно был сделан вывод, что HTTP запросы отправляются идентичные, но вот ответ от Google приходит другой. Иными словами Google не давал прав доступа, если скрипт был запущен с локальной машины. Ну, в таком случае оставался один возможный вариант решения проблемы. Что если вся тайна скрывается в самом IP адресе, вернее в его региональной принадлежности? Я знаю, что это звучало глупо, но других вариантов решения я не видел. Поэтому было решено воспользоваться VPN сервером с русским IP адресом. Но результат опять оказался нулевой. Конечно, можно было бы бросить это занятие по поиску возможных проблем и протестировать финальную версию скрипта на хостинге, но хотелось все-таки понять проблему такого поведения API. И уже на последнем отчаянии, я “попадаю” то ли на чей-то блог или форум и там один человек посоветовал другому: сменить время. Я соответственно быстро смотрю время на своем хостинге и сервере, устанавливаю идентичное время у себя на локальной машине и в результате скрипт все-таки заработал. Потом я еще специально поискал упоминание в документациях протокола OAuth 2.0 о таких вот подводных камнях, но ничего найдено не было.

Из всего выше сказанного можно сделать следующие выводы:

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