Как настроить интеграцию

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

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

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

Быстрая навигация
Виды викторин

В IntraQuiz есть два вида викторин:

  • публичные;
  • непубличные.

Публичные викторины

Публичные викторины — викторины, которые доступны по постоянной ссылке любому количеству респондентов с бесконечным количеством прохождений викторин.

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

Так выглядит публичная ссылка на викторину:

https://app.intraquiz.ru/q/37e857a1c070c48da8780711bfef92dc
Непубличные викторины

Непубличные викторины — викторины, которые доступны по одноразовой ссылке. Последняя становится неактивной после полного прохождения викторины пользователем (или в случае, если прошел срок ее действия — 7 дней), поэтому исключается повторная отправка результатов викторины конкретным респондентом, если ваш сервис не сгенерирует еще одну уникальную ссылку для этого же респондента. После прохождения викторины по непубличной ссылке IntraQuiz собирает результаты и отправляет webhook на ваш заранее установленный endpoint.

Так выглядит непубличная ссылка на викторину:

https://app.intraquiz.ru/q/37e857a1c070c48da8780711bfef92dc/?rid=a4ca4238a0b923820dcc509a6f75849b&t=5f5a8d5db35313457fb90f1d4173220e2710baa12639e9fc712f390aa8a3a6b9

Как вы могли заметить, здесь появляются дополнительные GET-параметры:

  • rid (идентификатор респондента);
  • t (одноразовый токен доступа).

Требования к формату параметров будут приведены далее.

Схема взаимодействия

1. Вы создаете аккаунт в IntraQuiz (генерируется API_KEY и API_SECRET);
2. В разделе с настройками устанавливаете endpoint, на который будете получать webhook;
3. В разделе с викторинами загружаете свои викторины (получаете их QUIZ_ID);
4. Со своего сервера отправляете POST-запрос на генерацию одноразовой ссылки;
5. Полученную в ответе от сервера одноразовую ссылку выдаете пользователю;
6. Ваш пользователь проходит викторину;
7. На ваш сервер отправляется webhook с результатами прохождения викторины в виде JSON;
8. Вы проверяете подлинность запроса по sha1_hash и обрабатываете данные.

Генерация уникальной ссылки на викторину

Вам необходимо отправить POST-запрос с данными в формате JSON, как в примере ниже.

  • quiz_id - ID викторины, формируется при создании викторины;
  • api_key - API-ключ, формируется при регистрации в IntraQuiz;
  • respondent_id - ID респондента, формируется на вашем сервере как MD5-хэш (32 символа);

<?php

$url = "https://intraquiz.ru/api/v1/generate_quiz_uri";

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$headers = array(
    "Accept: application/json",
    "Content-Type: application/json",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

$data = json_encode(array(
    "quiz_id" => <YOUR_QUIZ_ID>,
    "api_key" => <YOUR_API_KEY>,
    "respondent_id" => <YOUR_RESPONDENT_ID_MD5_HASH>
));	

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

$response = json_decode(curl_exec($curl), true);
curl_close($curl);

echo $response['result']; // Одноразовый URI

?>

Если запрос прошел удачно, то сервер IntraQuiz вернет ответ response_code = 1 в следующем JSON-формате:

{
    "response_code": 1,
    "message": null,
    "result": "https://app.intraquiz.ru/q/37e857a1c070c48da8780711bfef92dc/?rid=a4ca4238a0b923820dcc509a6f75849b&t=5f5a8d5db35313457fb90f1d4173220e2710baa12639e9fc712f390aa8a3a6b9"
}

Если что-то пошло не так, то response_code = 0, и ответ будет похож на этот:

{
    "response_code": 0,
    "message": "По данному ID викторина не обнаружена",
    "result": null
}
Смена темы оформления

IntraQuiz поддерживает две темы оформления: светлую (light) и темную (dark). По умолчанию все викторины запускаются в светлом оформлении, но если вы хотите включить темную тему, то просто добавьте в ссылку на викторину GET-параметр theme=dark. Тема фиксируется только на одно прохождение викторины, поэтому помните, что вы всегда можете управлять ей через GET-параметр в ссылке.

https://app.intraquiz.ru/q/37e857a1c070c48da8780711bfef92dc/?theme=dark
Дополнительные GET-параметры

Вы можете добавить до 5 произвольных GET-параметров к ссылке на викторину. Все эти параметры мы отправим в вебхуке на ваш сервер в поле data.params. Данная функция может быть полезна в некоторых сценариях работы.

https://app.intraquiz.ru/q/37e857a1c070c48da8780711bfef92dc/?super_param=832794&useful_data=from_dark_theme
Советы при интеграции

Как хранить API_KEY?
API_KEY не стоит хранить на фронтенде, так как данный ключ — ваш идентификатор, благодаря которому IntraQuiz понимает, от кого приходит запрос. Если ключ попадет в чужие руки, то злоумышленники смогут осуществлять запросы от вашего имени.

Как генерировать respondent_id?
В базе данных идентификаторы ваших пользователей могут храниться, к примеру, в виде чисел (1, 2, 3...), но мы посчитали, что в таком виде передавать id пользователей не стоит. Вместо этого создайте функцию, которая будет формировать хэш идентификатора с помощью алгоритма MD5. Это будет удобно, чтобы потом, когда IntraQuiz пришлет вам webhook с результатами викторины, вы могли найти пользователя, идентификатору которого соответствует MD5-хэш. Мы также рекомендуем использовать при хэшировании строку произвольной длины (соль).
Например, данную задачу можно решить так:

<?php

function generateUserIdMd5Hash($userId)
{
    $salt = "dNhVvaj8g46f3wK5"; // Используйте другую соль
    return hash("md5", $userId . '&' . $salt);
}

?>

Как лучше автоматизировать выдачу одноразовых ссылок пользователям?
Лучше всего сделать так:

  • Пользователь нажимает на кнопку «Пройти викторину» внутри вашего сервиса;
  • С клиента отправляется AJAX-запрос с QUIZ_ID на ваш сервер о намерении пользователя пройти викторину;
  • Ваш сервер генерирует MD5-хэш идентификатора пользователя (respondent_id) и, используя API_KEY и QUIZ_ID, отправляет запрос на сервер IntraQuiz, чтобы сгенерировать одноразовую ссылку;
  • После получения ссылки вы возвращаете ответ на AJAX-запрос на сторону клиента и, к примеру, с помощью JavaScript открываете викторину по ссылке в новой вкладке.

Получение результатов викторин

После того, как ваш пользователь пройдет викторину по одноразовой ссылке, мы соберем данные и отправим вам вебхук следующего содержания (JSON):

{
    "quiz_id" : "37e857a1c070c48da8780711bfef92dc",
    "respondent_id" : "a4ca4238a0b923820dcc509a6f75849b",
    "is_public" : 0,
    "sha1_hash" : <SHA1_HASH>,
    "data" : {
        "right_answers" : 9,
        "right_percent" : 90,
        "contacts" : { 
            "name" : "Александр",
            "email" : "sanya@example.com",
            "phone" : "+7 (999) 999-99-99"
        },
        "params" : { 
            "custom_param_1" : "12345",
            "custom_param_2" : "a0b923820dcc509a6f"
        },
        "personal_response" : { 
            "header" : "Вы — флегматик!",
            "content" : "Подробнее о флегматиках читайте в интернете",
            "calc" : "Флегматик на 78%"
        },
        "answers" : { 
            "2ead0b35200d01e2284d4c625f9506b2" : 2,
            "eb97a537b72ba091f315cdd11df8dca2" : 3,
            "afcc6b14e82a9254f454da2d4ff21fce" : 2,
            "cfc54ca431ebbad5ac37f052d630847d" : 3,
            "debaf80a9b8828e32bf14426057b3753" : 4
        },
        "readable_answers" : [ 
            { 
                "question" : "Вопросы для викторины программа берет из той строки таблицы Excel, столбец А которой заполнен вопросом. Это своеобразный сигнал программе, что здесь вопрос, который нужно взять, понятно?",
                "answer" : "Да",
            },
            { 
                "question" : "Сколько зубов у среднестатистического взрослого здорового человека?",
                "answer" : "16",
            },
            { 
                "question" : "Какие звуки издает кошка?",
                "answer" : "Мяу",
            },
            { 
                "question" : "Как звали сына Аристотеля?",
                "answer" : "Никомах;",
            },
            { 
                "question" : "Собаку, которая являлась другом дяди Федора из мультфильма «Простоквашино» звали…",
                "answer" : "Шарик;",
            }
        ]
    }
}

В примере ответа выше основные данные передаются в ключе data, который содержит результаты прохождения респондентом викторины в абсолютной величине (right_answers) и в относительной (right_percent) — IntraQuiz самостоятельно проверяет, насколько правильно пользователь ответил на вопросы викторины. В поле answers содержится информация об ответах на вопросы в формате идентификатор_вопроса : вариант_ответа. Идентификаторы вопросов можно найти в личном кабинете IntraQuiz внутри нужной викторины — они необходимы, как правило, для ручного управления логикой, максимально гибкой конфигурации экрана результатов викторины, который будет показан пользователю после ее прохождения.

В ответе также можно заметить некий sha1_hash. Мы используем его, чтобы вы могли распознать подлинный запрос к вашему серверу. sha1_hash формируется на основе вашего API_SECRET, который знаете только вы и IntraQuiz. Чтобы определить, что webhook поступил именно от нашего сервера, необходимо до того, как вы начнете обрабатывать полученные данные, сгенерировать хэш на своем сервере по следующей схеме:

<?php

// Присвоим массиву $_POST данные из полученного JSON
$_POST = json_decode(file_get_contents('php://input'), true);

// Сгенерируем свой sha1_hash и сравним с тем, что пришло нам в webhook
$sha1Hash = sha1($_POST['quiz_id'] . "&" . <API_SECRET> . "&" . $_POST['respondent_id']);
if (!hash_equals($sha1Hash, $_POST['sha1_hash'])) {
    exit("Не удалось подтвердить подлинность запроса");
}
// Все хорошо, можно дальше работать с данными, которые пришли

?>

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

Персонализация экрана результатов

После обработки вебхука вы можете вывести для нашего сервиса ответ в JSON, где указать два необязательных параметра:

  • message (string) — сообщение для пользователя на экране результатов викторины (поддерживаются HTML-теги <b>, <i>, <br>);
  • show_results (boolean) — показывать ли пользователю результаты прохождения викторины (true по умолчанию).

Помимо прочего, это может быть полезно для выявления потребности пользователя или формирования для него советов, исходя из ответов на вопросы. Обычно в таком случае нет правильных или неправильных ответов, поэтому полезно иметь возможность не выводить результаты викторины, так как это лишено смысла. Для генерирования собственного текста для экрана результатов можно использовать как right_percent (процент правильного прохождения викторины), так и, к примеру, ответы на конкретные вопросы из answers.

{
    "message": "На основании ответов на вопросы мы подготовили для вас перечень советов...",
    "show_results": false
}

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

Кейс Syfer

Здесь мы поделимся парой лайфхаков, как мы делали интеграцию с IntraQuiz в https://syfer.ru

Нам понадобилось создать некую универсальную кнопку, нажатие пользователем на которую инициирует получение ссылки на викторину и ее запуск. Мы решили, что это должно решаться в одну строчку. К кнопке прикрепили событие onclick, которое запускает функцию iqOpenQuiz и передает ей саму кнопку. Данная функция содержится в файле iq.js, который мы поместили в <head></head> сайта, чтобы запуск викторины можно было инициировать с любой страницы.

<!DOCTYPE html>

<html lang="ru" style="height: 100%;">
    <head>
        <!-- Подключим JS, который будет обрабатывать нажатие на кнопки викторин -->
        <script src="/path/to/file/iq.js"></script>
    </head>
    <body>
        <!-- Так в одну строчку мы решили создавать кнопки для открытия викторин -->
        <button data-quiz="<YOUR_QUIZ_ID>" onclick="iqOpenQuiz(this)">Начать викторину</button>
    </body>
</html>

Для iq.js мы написали следующий достаточно универсальный код, который не имеет зависимостей от сторонних библиотек (например, JQuery):

function iqOpenQuiz(obj) {
    var xhr = new XMLHttpRequest();
    var requestUrl = "/path/to/script.php"; // сюда отправляем запрос на ваш сервер, откуда связываемся с IntraQuiz, и возвращаем ответ
    obj.disabled = true;
    obj.textContent = "Загрузка...";
    xhr.open("POST", requestUrl);
    xhr.responseType = "json";
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.send("quizId=" + obj.getAttribute("data-quiz"));
    xhr.onload = function () {
        obj.disabled = false;
        obj.textContent = "Пройти викторину снова";
        // с формированием ответа от своего сервера вы можете поработать самостоятельно
        // мы же просто отправляем response_code, uri и message
        if (xhr.response.response_code == 1) {
            alert("Сейчас откроется викторина. Если после закрытия этого окна ничего не произошло, то это значит, что ваш браузер заблокировал переход — в этом случае проверьте заблокированные окна или попробуйте снова.");
            window.open(xhr.response.uri, "_blank");
        } else {
            alert(xhr.response.message);
        }
    };
}

После нажатия кнопки «Начать викторину», запрос отправляется на сервер Syfer, где уже формируется запрос к сервису IntraQuiz для генерации одноразовой ссылки на викторину. Полученная ссылка попадает в iq.js и происходит автоматическое открытие викторины в новой вкладке.

Результаты прохождения викторин, хранятся в базе данных Syfer. Это удобно, если нужно организовать хранение и обработку по-своему, так как IntraQuiz записывает себе мало данных, которые полезны, прежде всего, для статистики.

Скоро в API

В ближайшем будущем мы хотим добавить в API методы:

  • get_quizzes для получения списка существующих викторин по API_KEY;
  • get_quiz_results для получения результатов прохождения викторин респондентами по API_KEY.