Что такое API ВКонтакте и зачем оно нужно? Логирование активности с использованием Web Beacon API

Viber OUT 12.07.2019
Viber OUT

Апрель 2018-го года. Мне было 14. Мы с друзьями играли в тогда очень популярную онлайн-викторину «Клевер» от ВКонтакте. Один из нас (обычно я) всегда был за ноутбуком, чтобы пытаться быстро гуглить вопросы и глазами искать в поисковой выдаче правильный ответ. Но вдруг я понял, что каждый раз выполняю одно и то же действие, и решил попробовать написать это на частично известном мне тогда Python 3.

Шаг 0. Что здесь происходит

Для начала я освежу в вашей памяти механику «Клевера».

Игра для всех начинается в одно и то же время - в 13:00 и в 20:00 по Москве. Чтобы сыграть, нужно в это время зайти в приложение и подключиться к прямой трансляции. Игра идет 15 минут, в течение которых участникам на телефон одновременно приходят вопросы. На ответ дается 10 секунд. Затем объявляется верный ответ. Все, кто угадали, проходят дальше. Всего вопросов 12, и если ответить на все – получишь денежный приз.

Получается, наша задача - мгновенно ловить новые вопросы от сервера Клевера, обрабатывать их через какой-либо поисковик, а по результатам выдачи определять правильный ответ. Вывод ответа было решено производить в телеграм-бота, чтобы уведомления из него всплывали на телефоне прямо во время игры. И все это желательно за пару секунд, ведь время на ответ сильно ограничено. Если вы хотите увидеть, как довольно простой, но рабочий код (а посмотреть на такой будет полезно новичкам) помогал нам обыгрывать Клевер – добро пожаловать под кат.

Привет, Хабр!

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

Так уж сложилось, что API Вк, реализован довольно хорошо, за исключением некоторых не логичных моментов, о которых я упомяну позднее. Но речь, сегодня не о качестве, а о конкретном применении.

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

  • Серверная авторизация(т.н. авторизация сайтов)
  • Клиентская авторизация(Standalone)
  • Авторизация сервера приложения
Самое интересное для разработчика, представляют первые два. Первый, позволяет авторизовать пользователя на сайте и получить его ключ доступа, второй позволит авторизовать ваше приложение, например Dekstop или Mobile. Забегая, вперёд, второй вариант предоставляет нам огромные возможности, а первый, лишь малую их часть.

Алгоритм получения в первом случае сводится к выполнению следующих пунктов:

  • Мы выводим ссылку для авторизации пользователя, которую форматируем в соответствии с документацией
  • Пользователь переходит по ней и авторизуется
  • Пользователя перенаправляют на REDIRECT_URI нашего приложения с GET параметром code
  • Наше приложение должно выполнить запрос к API содержащий code, чтобы получить ключ доступа пользователя
  • API отвечает, либо с объектом, содержащим ключ доступа, либо ошибкой.

Пример кода, с помощью которого можно провернуть это не хитрое дело.

$auth = getjump\Vk\Auth::getInstance(); $auth->setAppId("3470411")->setScope("SCOPE")->setSecret("SECRET CODE")->setRedirectUri("http://localhost/test.php"); $token=$auth->startCallback(); printf("LINK", $auth->getUrl());

Предполагается, что наш домен это localhost, а текущий файл test.php. Если, всё прошло хорошо, то в нашей переменной $token, будет содержаться ключ доступа пользователя, который прошёл авторизацию.

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

api.vk.com/method/METHOD_NAME?PARAMETERS&access_token=ACCESS_TOKEN

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

При использовании библиотеки нам необходимо создать базовый объект, например так:
$vk = getjump\Vk\Core::getInstance()->apiVersion("5.5")->setToken($token);

Пара примеров запросов с использованием библиотеки:

Через анонимную функцию в each, пройдёт ровно 100 объектов, содержащих данные о пользователях от 1 до 100. Заметьте, если мы уберём вызов функции, то не произойдёт никакого запроса, всё потому что вернётся объект, у которого переопределены магические методы __call и __get, что позволяет нам делать запрос, когда нам это действительно необходимо.
$vk->request("users.get", ["user_ids" => range(1, 100)])->each(function($i, $v) { if($v->last_name == "") return; print $v->last_name . "
"; });

Одна из вещей, что открывает, нам использование генераторов - пакетное получение. То есть, мы получаем данные только тогда, когда они нам нужны. Следующий пример, позволит нам получить ВСЕ наши сообщения, запросами по 100. Будьте внимательны, метод требует от вас прав для messages, Standalone приложения, такой-же авторизации и соответственно передачи ключа доступа.
foreach($vk->request("messages.get")->batch(100) as $data) { $data->each(function($i, $m) { if(isset($m->body)) print $m->body . PHP_EOL; }); }

Хороший метод, который можно отыскать в API - execute . Он принимает параметр code в качестве аргумента, code - некий псевдо JavaScript, который позволяет нам выполнять наш код на стороне сервера, так-же он позволяет выполнять хранимые процедуры, которые мы можем создать при редактировании нашего приложения.

Эту вещь я не смог обойти стороной и реализовал её в библиотеке. В двух словах, она позволяет выполнить несколько запросов, как один. Смотрите следующий пример кода.

$js1 = $vk->request("messages.get", ["count" => 200, "offset" =>0 * 200])->toJs(); // Вернёт объект типа VkJs $js2 = $vk->request("messages.get", ["count" => 200, "offset" =>1 * 200])->toJs(); $js3 = $vk->request("messages.get", ["count" => 200, "offset" =>2 * 200])->toJs(); $js4 = $vk->request("messages.get", ["count" => 200, "offset" =>3 * 200])->toJs(); $js1 ->append($js2) // Мы прибавляем js2 к js1 ->append($js3) ->append($js4) ->execute() // Мы хотим выполнить это(на самом деле это вернёт RequestTransaction) ->response //Запрос исполнится только сейчас ->each(function($i, $v) //Первая анонимная функция нужна для обхода всех элементов массива полученного от execute(массив из 4 элементов, 4 запроса) { $v->each(function($c, $d) { // Следующая для прохода всех 200 сообщений в каждом массиве if(isset($d->body)) print $d->body; //Выведем сообщение если такое поле присутствует }); });

Как и обещал, одно из тех недоразумений, которое вы можете встретить в текущей версии API(5.21), метод

Доброго времени суток, друзья!

Очень часто вижу, что многие начинающие Зенщики смотрят в сторону API & POST/GET и правильно делают. Ведь нет ничего лучше POST/GET для уменьшения жора ресурсов шаблонами, ну а API для того и сделано, что бы быстро получать конкретные результаты.

Примером я выбрал именно VK.COM потому что мне он привычней и понятней.

Для работы нам понадобится текстовый редактор и сниффер.

Текстовый редактор я использую Notepad ++ , а сниффер – HTTP Analyzer . Все это легко гуглится, но если будут какие то проблемы с поиском, то смело пишите в личку, помогу.

Рассматривать текстовый редактор мы не будем, а вот на сниффере остановимся по подробнее.

Общий вид рабочего окна сниффера HTTP Analyzer : ​


Я не буду останавливаться на том, что Вы уже активировали данную программу удобным Вам способом или используете триальную версию. У меня уже активирована и поэтому выглядит окно именно так.

Изначально программа всегда запускается на стопе. Нам нужно ее запустить, нажав на Start :

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

Есть один лайфхак – после первого запуска зайдите в Viewи выберите LocalTime :

Теперь каждый запрос будет отображаться во времени, что очень удобно.

Теперь давайте рассмотрим более внимательно рабочую область программы:

В основном мы будем работать с двумя зонами, которые на картинке выше обозначаются 1 и 2 соответственно. Где показано время сделанного запроса, метод запроса так же указано на картинке.

В зоне 1 у нас время запроса, метод запроса и сам запрос, откуда мы его можем скопировать, но об этом позже.
В зоне 2 у нас будет слева то, что мы отправляем на сервер, а справа то, что получим в ответ от сервера.

Данную программу мы используем для работы с POST/GET запросами. Алгоритм тут простой – сделали в браузере нужное действие – посмотрели что перехватила программа.
Повторили тоже самое в шаблоне. Все. Ничего сложного.
Ну а дальше нужно набивать руку и глаз.

Теперь давайте разберемся как нам работать с API Vk .

Четкое и полное описание работы с API можно найти на сайте - https://vk.com/dev/main

Для работы с методами API нам нужно авторизоваться. Авторизуясь раз, мы получаем токен, который потом можем постоянно использовать для отдельно выбранного аккаунта (пока сами не сменим токен или не забанят аккаунт).

Лично я рекомендую всегда делать Клиентскую авторизацию для Standalone -приложений и мобильных клиентов, так как большинство методов требуют именно ее. Простейшие методы, такие как спарсить что то просто и в открытом доступе, не требует такой сложной авторизации. Да и делается она на много проще.

Вот таким запросом:

    https://oauth.vk.com:443/token?grant_type=password&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={-Variable.username-}&password={-Variable.password-}&captcha_key={-Variable.captcha_key-}&captcha_sid={-Variable.captcha_sid-}

client_id и client_secret могут быть от Вашего приложения.
Можете использовать и мои данные, но сами понимаете, вероятность того что что то может пойти не так - огромная. Мало ли кто там в каких целях будет использовать это приложение?
Раз сделали, а потом не волнуетесь. Удобно же!

Вернемся к теме разговора.
Рассматривать мы будем именно клиентскую, так как она требует подтверждение прав от авторизованного аккаунта.
На примере авторизации в vk.com я Вам покажу как работать с HTTP Analyzer , обрабатывая запросы и куки.

Лично я для работы с ВК выделяю отдельно ЮзерАгенты в файл, а так же работаю через прокси. Поэтому все мои шаблоны заточены под них. Прокси использую с привязкой по IP.

Что бы начать с чем либо работать, изначально нужно понять точный порядок действий.
Для авторизации в ВК он будет такой:
1. Открываем vk.com
2. Вводим логин и пароль.
3. Вводим капчу при авторизации, если необходимо.
4. Отправляем данные логина и пароля на сервер ВК.
5. Проверяем - прошла ли авторизация на сервере.

Вроде ничего сложного. Начнем разбираться!

Первым делом в наш шаблон нужно добавить System.Web . Делается это так:
1. Переходите в расширенный редактор.
2. Ищите "Ссылки из GAC "
3. Добавляете (перетаскиваете) на панель внизу (смотрите скрин)
4. Дважды кликаете по появившемуся ярлыку с "книжками"
5. В всплывшем окне жмете "Добавить..." и в следующем вводите System.Web.
6. Выбираете под Вашу систему - 64 или 32 битную. Кликом выбираете.
Все.

Это делается для того, что бы можно было кириллические буквы перевести в читаемые сервером вк данные.

Делаем заготовки:
Тут мы берем прокси и помещаем в переменную {- Variable .proxy -}

Здесь берем ЮзерАгента и помещаем в переменную {- Variable .useragents -}

Потом нам нужно взять строчку с данными аккаунта и разделить на логин и пароль.

Работаю в основном с текстовыми данными, а не табличными, так как продают их именно в таком виде.
Далее есть проверка на разделитель, так как у разных продавцов бывает по разному. У кого то разделитель ": ", а у кого то - "; "

Следующим шагом устанавливаем прокси и смотрим нет ли русских букв в пароле:

Делаю я это через обработку текста с взятием регулярки и проверяю, пустая ли переменная или нет.
Если не пуста, то кириллица есть и ее надо обработать.
Для этого использую сниппет C# :

    return System.Web.HttpUtility.UrlEncode(project.Variables["password"].Value, Encoding.GetEncoding("windows-1251"));

Именно в кодировке windows-1251!

Все, на этом этап подготовки завершается и мы начинаем делать саму авторизацию через POST/GET .

Я делаю так:
1. Запускаю HTTP Analyzer
2. Проверяю его работоспособность обновлением страницы в браузере.
3. Удаляю куки и кэш в браузере
4. Произвожу необходимые мне действия (в нашем случае – перехожу на https://vk.com и совершаю авторизацию)

Вот что выдает Аналайзер:

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

Вот что осталось после очистки не нужных строк (удалил всякие картинки и прочие не нужные джава скрипты):

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

Теперь покажу как это все берется, откуда и куда помещается:

Выделяем первую строку, простым нажатием левой кнопки мыши на нее.
Определяем какой это метод (смотрим какая запись находится в этой строке в столбце "Method "). В данном случае это GET . Затем идем в закладку RawStream, именно от туда все необходимые данные я, как правило, и беру.
Дальше мы берем и копируем сам запрос и делается это так:

Нажимаем право кнопкой мыши на интересующую нас строку и в выпадающем меню выбираем «CopyCell ».
К получится, что мы скопируем текст - https://vk.com/
Это очень удобно.

Теперь более подробно рассмотрим как и что мы добавляем в наш экшин.

На картинке ниже, в левой стороне расположена часть из HTTP Analyzer "а – Закладка "RawStream ", а справа экшин GET запроса из ПроджектМэйкера:

Тут мы это экшин заполняем следующим образом:
URL – мы вставляем то, куда хоти обратиться (в нашем случае это https://vk.com)
Referer – берем из RawStream (на картинке выделили данный момент)
Кодировка windows-1251 (так как работаем с Русскоязычной частью ВК)
Таймаут я советую ставить более 300 на проксях. На хороших или на своем IP можно оставить и 30.
Далее всегда выбираем в «Загружать » - Заголовки и содержимое, так как часто использую проверку - какой пришел ответ от сервера.
И объявляем переменную. Для GET запросов я всегда использую переменную {- Variable .get_info -} . Так понятнее для меня. Вы можете называть и обзывать ее как Вам угодно.

Следующая картинка будет из закладки «Дополнительно » того же экшина:

Ставим галочку Редирект, которая означает, что если там есть переход на следующую/другую странице, то он выполнит соответствующий запрос автоматически (по крайней мере я это так понимаю). Иногда нужно отключать! Но так, вообще полезная штука - сокращает кол-во запросов.

В поле UserAgent первой строчкой ставим нашу переменную {- Variable .useragents -}, так как мы ранее в эту переменную поместили данные нашего ЮзерАгента.
Далее вставляем выделенный синим текст. По сути, так делаем всегда, при составлении GET и POST запросов.
Дальше там уже появится строка с куками, но ее мы будем помещать в окно Cockie , что ниже.
Вообще я всегда делаю так:
1. Выделяю все (в программе HTTP Analyzer в закладке Raw Stream ), что слева до первой строки и копирую в ProjectMaker в экшин (POST или GET ) в закладку "Дополнительно ".
2. Вставляю это все в поле UserAgent в закладке "Дополнительно " экшина.
3. В вставленном тексте нахожу строку начинающуюся с Cookie и вырезаю ее в поле ниже, которое так и называется "Cookie: ".
4. Удаляю от туда "Cookie: " из текста и оставляю пока данные куков и возвращаюсь к ЮзерАгенту.
5. Удаляю там строку с ЮзерАгентом, так как вместо него у нас там стоит переменная.
6. Удаляем так же строку Content-Lenght
7. Cтроку с Refferer переносим в первую часть экшина - "Основные " и вставляем в соответствующее поле.
8. Удаляем начало - "Refferer: ".
Если в рефферере используются какие либо параметры, то используем соотвествующие этим параметрам наши переменные. Если таковые имеются. Если нет, то нужно найти заранее, взять и объявить такие переменные.
Так же поступаем и с Cookie . Все должно быть через переменные.

Теперь нам нужно посмотреть, что пришло в ответ.
Смотрим ответ в правой части RawStream :

Как видим, тут мы уже получили наши первые куки.

Вот тут то нам и пригодится текстовый редактор. Я беру все, что лежит в ответе на наш запрос и копирую в текстовый редактор, а просматриваю уже там.

В общем нам тут интересны куки и еще две переменные:

Всего мы ищем такие параметры - "ip_h ", "remixlang ", "lg_h " и "remixlhk ". Для удобства я их называю так же - {- Variable .ip_h -} , {- Variable .remixlang -} , {- Variable .lg_h -} , {- Variable .remixlhk -}

Вот так это будет выглядеть в шаблоне:

Так же делаю простенькую проверку – нашлось ли во ответе на GET запрос ip_h .
Если нет, значит что то не то с проксей или просто подзависло. Если нашлось то все в порядке.

В общем там, как правило все хорошо и те данные, что мы ищем, находятся.

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

Теперь нам нужно отправить на сервер данные для авторизации – логин и пароль.
Работаем со следующей строкой:

Как видим, это уже POST запрос и мы будем тогда использовать другой экшин.

Как и в предыдущем примере – копируем ячейку и это будет URL’ом нашего будущего POST запроса:

Все то же самое. Так же проставляем Рефферера обязательно!

Данные берем так же из RawStream :

Content-Type: application/x-www-form-urlencoded определяет тип данных.
Именно поэтому urlencoded!

Данные выглядят так (на картинке выше в красном прямоугольнике и с текстовым указанием "ДАННЫЕ "):

    act=login&role=al_frame&expire=&captcha_sid=&captcha_key=&_origin=http%3A%2F%2Fvk.com&ip_h=4be754765f3544efab&lg_h=526aa8a2bec4cc5c0a&email=79998015427&pass=yEWwLdH

Думаю углубляться не стоит как все мы это заменяем? С нашими переменными станет уже так:

    act=login&role=al_frame&expire=&captcha_sid={-Variable.captcha_sid-}&captcha_key={-Variable.captcha_key-}&_origin=http%3A%2F%2Fvk.com&ip_h={-Variable.ip_h-}&lg_h={-Variable.lg_h-}&email={-Variable.login-}&pass={-Variable.password-}

Как правило я стараюсь называть переменные как и параметры в запросах - так проще потом вставлять.
Переменные начинающиеся с captcha – это то что мы берем, если есть капча.

В дополнительных настройках экшина у нас будет так:

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

Далее я проверяю наличие куков remixq_
Данные куки появляются при авторизации в аккаунте. Если не появились, значит что то пошло не так. Тогда проверяем на капчу. Если и капча не выскочила, то тут уже проблемы с самим аккаунтом.

Получение AccessTokenVK.COM бессрочный


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

Для получения токена, нам необходимо получить куки, что мы уже имеем делать из первой части и всего два GET –запроса! Хотя, упрощенный - всего один экшин. =)

Давайте посмотрим первый запрос.
Запрос делаем без редиректа!
В URL вставляем строку:
{-Variable .client_id-} - Это ID приложения, которое Вам нужно найти или самим создать тут:
https://vk.com/apps?act=manage
Ну или пользуйтесь моим, что я не советую.

Настройки приложения можете посмотреть на этом скрине:

А права доступа расписаны здесь – https://vk.com/dev/permissions

Если мы ничего не упустили, то в ответ на GET -запрос придет ссылка для получения токена.

Изначально я всегда проверяю – пришел ли правильный ответ. В данном случае я проверяю есть ли полученном ответе «grant_access_title ».

Это правильный ответ и тут имеются необходимые нам данные.
Далее мы парсим ссылку для подтверждения запроса, которую мы помещаем в переменную {- Variable .Location -}

И делаем последний запрос, так же без редиректа!

На скрине показан запрос и по вкладкам.
Обратите внимание, что у ВК практикуется такая тема, что на определенные действия используются определенные куки и не стоит, все куки пихать в запрос.
На некоторых запросах данный момент реально критичен!

Если и в этот раз ничего не упустили и не напутали, то в ответе будет нужный нам токен:

Отсюда мы его и парсим.

НА СКРИНЕ ПРИВЕДЕН ПРИМЕР С ПРАВАМИ НА «постинг без HTTPS»!
Отличается он тем, что в конце добавляется параметр – secret .
Более подробно прочитать можете тут - https://vk.com/dev/api_nohttps
Я же не беру такие токены, так как пока не было необходимости получать такой токен и что бы потом не генерировать переменную sig .

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

И так вернемся к загрузке

Будем рассматривать на примере загрузки фотографии в фотоальбом какой либо группы. Для этого нам нужно кроме токена еще {- Variable .group_id -} и {- Variable .album_id -}

{- Variable .group_id -} – ID группы

{- Variable .album_id -} - ID фотоальбома в этой группе.

Где и как Вы их брать будете, я не буду рассматривать. В моем примере, данные переменные я ввожу в шаблон через InputSettings :

Плюс работы с API заключается в том, что для работы нам нет нужды ни в куках ни в юзерагентах.

Первый запрос будет POST и выглядит он так:

В поле URL помещаем код:

    https://api.vk.com:443/method/photos.getUploadServer

Так как мы загружаем фотографию, то и используем Метод работы с фотографиями.
В частности - https://vk.com/dev/photos.getUploadServer
Со всеми возможными методами можно ознакомиться тут - https://vk.com/dev/methods

Запрос практически всегда формируется так - https://api.vk.com:443/method/ + выбранный метод .

Метод (какой текст присоединять к запросу) берем отсюда:

Данные будут такие:

    group_id={-Variable.group_id-}&album_id={-Variable.album_id-}&access_token={-Variable.access_token-}

Откуда мы все это взяли? Все просто! Смотрим внимательно на описание метода и видем такую часть - Параметры:

В данном случае тут присутствуют такие параметры как album_id и group_id . Они обязательны и нужны для правильного формирования запроса.

Строка запроса формируется как – необходимые параметры соединенные через “& ” и access_token в конце. Можно и версию API ставить.

В моем случае, album_id и group_id уже заданы, а access_token получен.
Где и как Вы будите брать album_id и group_id это уже решать Вам.

Тип данных – urlencode. Данный тип всегда используется, за исключением случаев, когда что то загружаем !
Так же напомню, что если сомневаетесь в типе данных, то посмотрите какой content-type используется.

В данном случае на скрине у меня почему то стоит загрузить – только содержимое.

Видимо ошибка, так как я использую всегда – Заголовки и содержимое, так удобнее – всегда можно проверить пришел ли ответ или он был пустой.

В общем при правильных данных и рабочем токене мы получим следующий ответ:

  1. Content-Type: application/json; charset=utf-8

    Content-Length: 202

    Connection: keep-alive

    X-Powered-By: PHP/3.19487

    Pragma: no-cache

    Cache-control: no-store

    Content-Encoding: gzip

    {"response":{"upload_url":"http:\/\/cs631229.vk.com\/upload.php?act=do_add&mid=187638093&aid=221646126&gid=103611875&hash=9a8b2772a9ceabc1821aee59faa2bc72&rhash=3c6d36c299672e7d8b3412029acef606&swfupload=1&api=1","aid":221646126,"mid":187638093}}

Рассматриваем данный ответ.
Есть указание – response и он не пустой.
"aid " и "mid " нас не интересуют это id фотоальбома группы и id анкеты, загружающей фотографию. Да, да. Везде все палится.

Нас тут интересует "upload_url ", его мы и парсим, так же обрабатываем текст – заменяем "\/ " на "/ " все и помещаем в переменную {- Variable. upload_url -}

  • Перевод
  • Tutorial

Beacon API - это основанный на JavaScript интерфейс для:

отправки небольшого количества данных на сервер с браузера, без ожидания ответа. В этой статье, мы рассмотрим в каких случаях будет полезен Beacon API, чем он отличается от использования XMLHTTPRequest (Ajax) для тех же целей и как его использовать.

Для чего нам очередной API?

Beacon API используется для отправки небольших по объему данных на сервер без ожидания ответа . Последняя часть утверждения является наиболее интересной. Beacon API разработан специально для того, что бы можно было отправить данные и забыть о них. Не нужно ожидать ответ, так как его и не будет.


Метафора с открытками, это такие карточки которые люди посылают/посылали друг другу. Как правило, на них писали небольшой по объему текст ("Ты где? А я на море лол.", "Тут у меня шикарная погода, не то что у тебя в офисе"), кидали в почту и забывали. Никто не ожидал ответа по типу "Я уже выехал за тобой", "У меня в офисе чудесно".


Существует множество случаев, когда подход "отправил и забыл" будет уместен.

Отслеживание статистики и Аналитическая информация

Это первое, что приходит на ум. Такие большие решения как Google Analytics могут предоставлять хороший обзор на базовые вещи. Но если мы хотим, что-то более кастомизированное? Нам необходимо написать немного кода для отслеживания того, что происходит на странице (как пользователи взаимодействуют с компонентами, как далеко они скролят, какие страницы были отображены до первой продажи), затем отправить эти данные на сервер когда пользователь покидает страницу. Beacon идеально подходит для решения такой задачи, так как мы просто отправляем данные, и нам ненужен ответ от сервера.

Дебаг и Логирование

Другое применение это логирования информации из JavaScript кода. Представьте себе ситуацию когда у вас большое приложение с богатым UI/UX. Все тесты зеленые, а на проде периодически всплывает ошибка о которой вы знаете, но не можете продебажить ее из за не хватки информации. В данном случае вы можете ипользовать Beacon для диагностики.


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

Разве мы не делали этого ранее?

Я знаю о чем вы думаете. Ничто из этого не ново? Мы общаемся с севером посредством XMLHTTPRequest уже более 10 лет. Недавно мы начали использовать Fetch API, что по факту делает то же самое, просто с новым Promise интерфейсом. Так зачем нам еще один Beacon API?


Ключевая особенность в том, что нам не нужен ответ от сервера. Браузер может поставить в очередь запрос и отправить данные не блокируя выполнение какого либо кода. Так как в это впрягается браузер, для нас не важно выполняется ли еще код или нет, браузер просто будет себе тихонько отправлять запросы в фоне.


C Beacon API не нужно дожидаться лучшего момента для CPU, сети. Просто добавить в очередь запрос с помощью beacon практически нечего не стоит.


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


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


Вы же понимаете насколько HTTP запросы медленные? И последнее, что вы хотите, так это впихивать HTTP запрос между переходами.

Пробуем Beacon API

Базовый пример использования очень прост:


let result = navigator.sendBeacon(url, data);

Использование navigator.sendBeacon()

navigator.sendBeacon принимает два параметра. Первый это URL на который будет послан запрос, второй это данные которые необходимо отправить. Запрос имеет вид HTTP POST .


data - этот параметр может принимать несколько форматов данных, все те с которыми работает Fetch API. Это может быть Blob, BufferSource, FormData или URLSearchParams и тд.


Мне нравится использовать FormData для простых key-value данных, это не сложный и простой в использовании класс.


// URL куда отправить данные let url = "/api/my-endpoint"; // Создание нового FormData let data = new FormData(); data.append("hello", "world"); let result = navigator.sendBeacon(url, data); if (result) { console.log("Добавлено в очередь!"); } else { console.log("Ошибка."); }

Поддержка браузерами

Поддержка этого API вполне себе солидная. Единственный браузер который не поддерживает, это Internet Explorer (не ожидал я такого) и Opera Mini. Но в Edge все работает. В большинстве случаев поддержка есть, но лучше на всякий случай проверить:


if (navigator.sendBeacon) { // Beacon код } else { // Использовать XHR? }

Пример: логируем время проведенное на странице

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


Так как нас интересует только время проведенное на странице, а не настоящее время, мы можем использовать performance.now() для получения базового timestamp при загрузке страницы:


let startTime = performance.now();

Давайте обернем небольшой кусочек логики в удобную в использовании функцию:


let logVisit = function() { // Test that we have support if (!navigator.sendBeacon) return true; // URL to send the data to, e.g. let url = "/api/log-visit"; // Data to send let data = new FormData(); data.append("start", startTime); data.append("end", performance.now()); data.append("url", document.URL); // Let"s go! navigator.sendBeacon(url, data); };

И наконец нам надо вызвать эту функцию когда пользователь покидает страницу. Первая мысль была использовать unload , но Safari на Mac, похоже блокирует запрос по соображениям безопасности. По этому лучше использовать beforeunload:


window.addEventListener("beforeunload", logVisit);

Когда страница выгружается (или перед этим), наша функция logVisit() будет вызвана и если браузер поддерживает Beacon API, отправит запрос на сервер.

Пару моментов

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

GDPR

Просто помните о нем.

DNT: DO NOT TRACK

В дополнение, браузеры имеют опцию которая позволяет пользователям обозначить, что они не хотят, что бы их активность отслеживалась. Do Not Track отправляет HTTP хедер, который выглядит так:


DNT: 1

Если вы отслеживаете данные которые могут индицировать пользователя и в хедерах запросов есть DNT: 1 , то лучше послушать пользователя и не сохранять какие-либо данные. Например использую PHP это можно проверить следующим образом:


if (!empty($_SERVER["HTTP_DNT"])) { // Не хочу, не надо }

В заключение

Beacon API действительно очень удобный способ для отправки данных на сервер, особенно в контексте логирования. Поддержка браузерами на достаточно хорошем уровне и позволяет вам легко логировать любую информацию без каких либо негативных последсвий для производительности и отзывчивости вашего UI. Non-blocking природа этих запросов играет в этом очень хорошую роль, это горазно быстрей альтернатив XHR и Fetch.


Теги: Добавить метки

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

Итак, что же нам предлагает API ВКонтакте - давайте разберемся.

Обзор

Как обычно, для начала почитаем, что об этом пишут наши коллеги.

Однако, никаких вразумительных статей, кроме материалов в рамках самого "ВКонтакте" найти не смог. Если кто-нибудь видел таковые - пожалуйста, киньте ссылочку в комменты. Итак:

Возможности API ВКонтакте

Попробуем выявить возможности приложений ВКонтакте, проанализировав функции API.

Работа с пользовательскими данными

Приложение имеет доступ к следующим данным:

  • Установил ли пользователь, который просматривает приложение себе на страницу данное приложение
  • Данные по любому пользователю, на основании его ID:
    - имя,
    - фамилия,
    - псевдоним,
    - пол,
    - дата рождения,
    - город,
    - страна,
    - часовой пояс,
    - url-адреса фото малого, среднего и большого размеров,
    - известен ли его мобильный телефон,
    - рейтинг
  • Баланс пользователя на счету приложения
  • Доступ к данным пользователя, просматривающего приложение:
    - разрешить отправлять ему уведомления,
    - доступ к друзьям,
    - доступ к фотографиям,
    - доступ к аудиозаписям,
    - доступ к предложениям,
    - доступ к вопросам,
    - доступ к wiki-страницам,
    - доступ к меню слева,
    - публикация на стенах пользователей.
  • Список групп, в которых состоит пользователь с общей информацией о каждой группе.

У каждого пользователя ВКонтакте есть друзья - другие пользователи ВКонтакте. Доступные данные друзей пользователя:

  • Список друзей текущего пользователя.
  • Список друзей текущего пользователя, которые уже установили данное приложение.

Приложение может так же осуществлять следующие действия:

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

Работа с фотографиями пользователя

Пользователь ВКонтакте может создавать множество альбомов с фотографиями в разделе "Мои Фотографии". API предоставляет широкий выбор возможностей по работе с альбомами и фотографиями.

Фотографии должны иметь формат JPG, PNG или GIF.

Приложение может получить:

  • Список фото-альбомов с общими данными о каждом альбоме.
  • Список фотографий из какого-либо альбома (или непосредственно по ID фотографии) с набором ссылок на изображения различных размеров и качества.

Приложение может осуществлять следующие действия с альбомами и фотографиями:

  • Создавать альбом (с описанием и контролем доступа к нему).
  • Редактировать данные существующего альбома.
  • Изменять порядок в списке альбомов.
  • Изменять порядок фотографий в альбоме.
  • Переносить фотографии из альбома в альбом.
  • Делать фотографию обложкой альбома.
  • Загружать фотографии на сервер ВКонтакте, на стену пользователя, на страницу пользователя.

Работа с аудиозаписями пользователя

Пользователь может загружать аудиозаписи и прослушивать их в разделе "Мои Аудиозаписи".

Аудиозапись должна быть в формате MP3, не превышать 10Мб и не нарушать авторских прав.

API предоставляет широкий выбор возможностей для работы с аудиозаписями:

  • Получать список аудиозаписей пользователя или группы с общей и подробной информацией о каждой записи.
  • Получать текст песен аудиозаписей.
  • Осуществлять поиск по аудиозаписям.
  • Загружать, удалять, восстанавливать удаленные аудиозаписи.
  • Редактировать данные аудиозаписи.
  • Добавлять аудиозапись на страницу пользователя или группы.
  • Менять порядок следования аудиозаписей.

Работа с видеозаписями пользователя

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

Стена пользователя

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

API предоставляет приложению доступ к следующим функциям:

  • Получить платежный баланс (количество голосов) приложения.
  • Получить платежный баланс (количество голосов) пользователя.
  • Перевести голоса со счета приложения на счет пользователя.
  • Перевести голоса со счета пользователя на счет приложения.
  • Перевести голоса со счета пользователя на счет другого пользователя в рамках приложения.
  • Просмотр историй транзакций по переводу голосов между пользователями и приложением

Работа с SMS

Приложение ВКонтакте может задействовать столь мощные сервисы, как отправка и прием SMS:

  • Отправка SMS-уведомления. При этом со счета приложения списывается 0.1 голоса.
  • Просмотр списка SMS-сообщений, полученных от пользователей приложением.
  • Просмотр истории SMS-уведомлений, посланных приложением.
Отправка SMS-сообщения бесплатна (стоимость обычного SMS-сообщения). Отправка осуществляется на телефон +7 921 000 00 07, а чтобы приложение получило свое сообщение, API предоставляет возможность установить приложению префикс, который пользователь должен указать в начале своего SMS-сообщения.

Работа с сервисом "Предложения"

С помощью сервиса "Предложения", пользователь получает возможность создать свое уникальное предложение. Это предложение смогут увидеть все пользователи ВКонтакте -этот сервис независим от личной странички. Любое предложение начинается со слов "Хотели бы Вы", далее следует сам текст, а в конце уже стоит вопросительный знак. Пользователи могут посматривать предложения других пользователей, принимать чужое предложение нажатием варианта «Да, конечно» или отказываться нажатием варианта «Нет».

Итак, функции для работы с предложениями:

  • Редактировать, открыть для общего доступа, и закрыть предложение пользователя, просматривающего приложение.
  • Просматривать, искать предложения пользователей.
  • Принимать и отклонять предложения пользователей.
  • Просматривать ответы на предложение пользователя.
  • Получать список ответов на предложения, принятые пользователем.
  • Удаление и пометка о прочтении ответов пользователей.

Работа с сервисом "Вопросы"

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

Работа с Wiki-страницами

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

Приложения имеют возможность работать с Wiki-страницами:

  • Получать текст и полную информацию о wiki-странице.
  • Редактировать и сохранять текст и настройки wiki-страницы.
  • Получать список wiki-страниц в группе.
  • Транслировать wiki-разметку в html-разметку.

Организация чата

API позволяет создавать в приложении чат, используя очередь сообщений - 127 сообщений. Для этого предусмотрены функции добавления сообщения в очередь и просмотра всей очереди сообщений.

Сохранение игровых рекордов

API предусматривает специальные функции для сохранения результатов игры пользователя и получения списка результатов.

Работа с переменными

Для хранения данных, API предоставляет каждому приложению 4096 уникальных переменных по 255 байт.

Причем, переменные распределяются по следующим диапазонам:

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

Однако, количество переменных не велико - всего по 1024 переменные на диапазон, и это без учета зарезервированных переменных.


Работа с удаленным сервером разработчика

Приложение ВКонтакте является обычным Flash-приложением и обладает одним большим недостатком. Его нельзя считать защищенным от взлома. Точнее говоря, затраты на взлом flash-приложения не столь велики как, к примеру взлом сервера. Существует достаточное количество программ SWF-декомпиляторов, при помощи которых можно легко получить исходный программный код, выяснить логику приложения и подтасовать запросы к API.

Поэтому, некоторые функции, которые были перечислены выше, работают только с удаленного сервера разработчика, минуя flash-приложение, а именно:

  • Работа с рейтингом пользователя
  • Вывод короткого статуса пользователя в приложении на его главной странице
  • Отправка уведомлений пользователя (только пользователям, которые установили себе данное приложение)
  • Работа с голосами (платежные операции)
  • Установка счетчика на приложение и работа с строкой статуса приложения
  • Отправка и просмотр SMS-уведомлений

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

А вообще, конечно, для крупных проектов, работающих в формате приложений ВКонтакте, безусловно, именно этот специальный сервер и должен являться "мозгом", отрабатывающим всю логику приложения. Flash-приложение в этом случае всего лишь "тонкий клиент", который лишь красиво отображает результат работы сервера.

Локализация приложений

Разработчики приложений имеют возможность переводить свои приложения на более чем 50 языков, используя платформу переводов ВКонтакте . В данный момент платформа на этапе тестирования и применима только для приложений с большим количеством пользователей.

Использование Flash-контейнера приложения

Альтернативный способ внедрения flash-приложения в страницу ВКонтакте - через Flash-контейнер.

Flash-контейнер предоставляет следующие возможности для приложения:

Особенности API ВКонтакте

Итак, мы ознакомились со всеми возможностями, которые предоставляет API ВКонтакте. Хочется выделить особенности (скорее недостатки) API, с которыми мне пришлось столкнуться:

Итог

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



Рекомендуем почитать

Наверх