1 February 2011

Интеграция с ВКонтакте на базе Open API

Social networks and communities
From Sandbox
Социальная сеть ВКонтакте предоставляет широкие возможности для интеграции со сторонними сайтами. В основном эти возможности представлены уже готовыми виджетами. Однако, есть еще и Open API, которое позволяет не только авторизовать пользователя, но и выполнить любой метод, доступный приложениям ВКонтакте (ВКонтакте API).

Попробуем создать небольшое приложение-игру, используя возможности Open API. Тренироваться будем на игре «Память», суть которой заключается в том, что надо очистить игровое поле, открывая по 2 одинаковых картинки. В качестве картинок будем использовать фотографии друзей игрока.

Приступаем к работе


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



После этого переходим к настройкам приложения и указываем адрес сайта и базовый домен.



Реализация


Создадим HTML страницу, которая будет содержать несколько блоков:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>       
        <title>VK Memory</title>
        <script type="text/javascript" src="./js/jquery.min.js"></script>
        <script type="text/javascript" src="./js/jquery-ui.min.js"></script>
        <script type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>
        <script type="text/javascript" src="./js/jquery.pnotify.min.js"></script>
        <script type="text/javascript" src="./js/jquery.blockUI.js"></script>
        <script type="text/javascript" src="./js/general.js"></script>
        <link rel="stylesheet" href="./css/styles.css" type="text/css"/>
        <link rel="stylesheet" href="./css/ui-lightness/jquery-ui-1.8.9.custom.css" type="text/css"/>
        <link rel="stylesheet" href="./css/jquery.pnotify.default.css" type="text/css"/>
    </head>
    <body>
        <div id="content">
            <div id="header">
                VK Memory
            </div>
            <div class="flash-notice" style="display: none" id="login-bar">
                Для начала игры необходимо <a href="#" id="vk-login">авторизироваться</a>
            </div>
            <div class="flash-success" style="display: none" id="logout-bar">
                Вы можете <a href="./index.html" id="new-game">начать новую игру</a>, <a href="#" id="game-scores">посмотреть таблицу рекордов</a> или <a href="#" id="vk-logout">выйти</a>.
            </div>
            <div class="flash-error" style="display: none; text-align: center" id="stats"></div>
            <div id="game-container"></div>
        </div>
        <div id="scores-dialog" style="display: none"></div>
    </body>
</html>

Назначение блоков:
  • div#login-bar — содержит ссылку для авторизации пользователя
  • div#logout-bar — содержит ссылки для начала новой игры, просмотра статистики и выхода
  • div#game-container — контейнер для игрового поля

Важным моментом является подключение JavaScript файла, содержащего методы Open API:
<script type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>

Основная функциональность нашего приложения будет располагаться в файле general.js, поэтому перейдем к его рассмотрению.

Инициализация Open API


Важной частью скрипта является инициализация API, которая заключается в вызове метода VK.init, в который передается объект, содержащий минимум одно поле — apiId — ID приложения (он отображается на странице настроек приложения):
VK.init({
	apiId: 2151186
});


Авторизация


Для авторизации пользователя добавим обработчик для ссылки a#vk-login, который будет вызывать метод VK.Auth.login. Первым параметром передается callback-функция, а вторым — необходимые пользовательские настройки приложения, которые являются перечнем необходимых уровней доступа. В нашем случае необходим доступ только к списку друзей, поэтому обработчик для ссылки будет выглядеть так:
$('a#vk-login').click(function(event){
	event.preventDefault();
	VK.Auth.login(null, VK.access.FRIENDS);
});


Завершение сеанса


Для того, чтобы пользователь мог завершить сессию, добавим обработчик для ссылки a#vk-logout, который будет вызывать метод VK.Auth.logout. Первым параметром передается callback-функция, которая в нашем случае будет обновлять страницу:
$('a#vk-logout').click(function(event){
	event.preventDefault();
	VK.Auth.logout(function(){
		refreshPage(false);
	});
});


Отслеживание событий


Для того, чтобы перейти к игре (в нашем случае это заключается в обновлении страницы) после того как пользователь прошел авторизацию, необходимо подписаться на событие auth.login. Также подпишемся на событие auth.sessionChange, оно будет генерироваться, когда изменяются данные, связанные с авторизацией пользователя. Это необходимо для того, чтобы перейти к игре в том случае, если пользователь уже авторизирован ранее и только подтверждает доступ к списку друзей. Для добавления обработчика события необходимо вызвать метод VK.Observer.subscribe, который принимает два параметра — событие, на которое необходимо подписаться, и callback-функцию — обработчик события:
VK.Observer.subscribe('auth.login', function(response){
	refreshPage(true);
});
VK.Observer.subscribe('auth.sessionChange', function(response){
	refreshPage(true);
});

Метод refreshPage обновляет страницу, если пользователь не был ранее успешно авторизован:
function refreshPage(checkLogged)
{
    if((checkLogged && !isLogged) || !checkLogged)
    {
        location.href = 'index.html';
    }
}


Сбор начальных данных


Для проверки текущего статуса пользователя существует метод VK.Auth.getLoginStatus. Задействуем его, чтобы определить, авторизирован ли пользователь, и скрыть/показать необходимые из описанных выше блоков. Также, если пользователь уже авторизирован, сразу перейдем к началу игру. В метод VK.Auth.getLoginStatus передается один параметр — callback-функция, в которую, в свою очередь, передается объект, содержащий сессионные данные пользователя:
VK.Auth.getLoginStatus(function(response){
	if(response.session)
	{
		// пользователь авторизирован
	}
	else
	{
		// пользователь не авторизирован
	}
});

Для вызова любого метода ВКонтакте API служит метод VK.Api.call, который принимает три параметра — название метода, объект, представляющий собой параметры, передаваемые в указанный метод, и callback-функцию, в которую будет передан результат вызова метода. Для получения списка друзей необходимо вызвать метод friends.get. Метод не имеет обязательных параметров и в случае вызова без параметров вернет список всех друзей. Поскольку нам нужны фотографии друзей пользователя, передадим в метод параметр fields со значением 'photo_rec', что соответствует квадратной фотографии со стороной 50 пикселей:
VK.Api.call('friends.get', {
	fields: 'photo_rec'
}, function(data){
	// обработка списка друзей
});

В случае возникновения ошибки, объект data будет содержать вложенный объект error, содержащий информацию об ошибке. Ошибка с кодом 7 говорит о том, что у приложения не хватает прав, то есть в нашем случае о том, что пользователь не разрешил доступ к списку друзей.
Если вызов метода завершен успешно, то объект data будет содержать поле response, которое является массивом объектов, каждый из которых представляет информацию об одном из друзей пользователя.
После того, как список друзей получен, отбираем из него тех, у кого задана фотография (то есть не является стандартной картинкой со знаком вопроса) и переходим к инициализации игры:
VK.Api.call('friends.get', {
	fields: 'photo_rec'
}, function(data){
	if(!data.error)
	{
		if(data.response.length > 0)
		{
			data.response.shuffle();
			for(i = 0; i < data.response.length; i++)
			{
				var friend = data.response[i];
				if(friend.photo_rec && friend.photo_rec.indexOf('images/question_c.gif') == -1)
				{
					photos.push({
						photo: friend.photo_rec,
						id: friend.uid
					});
				}
			}
		}
		initGameField();
	}
	else
	{
		if(data.error.error_code == 7)
		{
			isLogged = false;
			$('div#login-bar').show();
			$('div#logout-bar').hide();
			$.unblockUI();
		}
		else
		{
			showError(data.error.error_msg);
		}
	}
});


Подготовка игрового процесса


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

В случае успешного хода вызывается метод ВКонтакте API getProfiles, который возвращает информацию об указанных пользователях. Список пользователей, для которых необходимо получить информацию, передается в качестве параметра uids. Вызов этого метода используется для отображения имени и ссылки на профиль пользователя, который был успешно отгадан.
Если очищено все поле, сохраняем текущий результат (количество шагов, за которое было очищено поле) в таблицу рекордов. Для этого служит метод setUserScore, который принимает единственный параметр — рекорд пользователя:
VK.Api.call('setUserScore', {
	score: stepsCount
}, function(data){
	if(data.error)
	{
		 showError(data.error.error_msg, false);
	}
});

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

Список чемпионов


Для получения таблицы рекордов используется метод getHighScores, который не имеет параметров. Метод возвращает массив объектов, каждый из которых содержит информацию о пользователе и его рекорд.
Чтобы пользователь мог посмотреть таблицу рекордов, добавим обработчик ссылки a#game-scores, который будет вызывать указанный выше метод, формировать таблицу результатов и показывать ее в диалоговом окне:
$('a#game-scores').click(function(event){
	event.preventDefault();
	VK.Api.call('getHighScores', {}, function(data){
		if(!data.error)
		{
			var scoresTable = '';
			if(data.response && data.response.length > 0)
			{
				for(i = 0; i < data.response.length; i++)
				{
					scoresTable = '<tr><td><a href="http://vkontakte.ru/id' + data.response[i].user_id + '" target="_blank">' + data.response[i].user_name + '</a></td><td>' + data.response[i].score + '</td></tr>' + scoresTable;
				}
				scoresTable = '<table border="0" class="scores-table" align="center"><thead><tr><td>Пользователь</td><td>Результат</td></tr></thead><tbody>' + scoresTable + '</tbody></table>';
			}
			else
			{
				scoresTable = '<div style="text-align: center">Нет результатов</div>';
			}
			$('#scores-dialog:ui-dialog').dialog('destroy');
			$('#scores-dialog')
				.html(scoresTable)
				.dialog({
					title: 'Таблица рекордов',
					modal: true,
					draggable: false,
					resizable: false,
					buttons: {
						'Закрыть': function(){
							$(this).dialog('close');
						}
					}
				});
		}
		else
		{
			showError(data.error.error_msg, false);
		}
	});
})

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

Результат


Итоговый файл general.js можно посмотреть здесь, сама игра доступна по ссылке VK Memory.

Для создания приложения были использованы плагины для jQuery Pines Notify и BlockUI. Всю информацию об API ВКонтакте можно получить на странице для разработчиков.
Tags: вконтакте open api
Hubs: Social networks and communities
+69
25.9k 207
Comments 21
Ads