S2S ping: Difference between revisions
| No edit summary | |||
| Line 1: | Line 1: | ||
| [[S2S ping en|English version]] | |||
| = Общий алгоритм работы = | = Общий алгоритм работы = | ||
| # Пользователь приходит на ваш сайт. Вы генерируете уникальный <code>kmnrId</code> и отстукиваетесь с ним на сервер Kaminari на URL /ping, мы сохраняем данные в кэш. | # Пользователь приходит на ваш сайт. Вы генерируете уникальный <code>kmnrId</code> и отстукиваетесь с ним на сервер Kaminari на URL /ping, мы сохраняем данные в кэш. | ||
Revision as of 16:14, 6 September 2023
Общий алгоритм работы
- Пользователь приходит на ваш сайт. Вы генерируете уникальный kmnrIdи отстукиваетесь с ним на сервер Kaminari на URL /ping, мы сохраняем данные в кэш.
- Затем вы показываете пользователю страницу с нашим JS-скриптом, добавив в вызов скрипта тот же самый kmnrId.
- Мы собираем данные о пользователе и шлём их на сервер Kaminari.
- На сервере мы проверяем в кэше:
- Если там есть запись с аналогичным kmnrId(пришедшая на /ping), мы склеиваем данные из кеша с результатами проверки и пишем их в статистику.
- Если записи с таким kmnrIdнет, мы ждём пять минут. Если вторая запись так и не приходит, мы пишем в статистику то, что есть.
- Так же мы периодически проверяем кэш и ищем просроченные клики, пришедшие на /ping, но так и оставшиеся без пары. Если нам не удалось никак их проверить, мы пишем их в стату со статусом «Технические потери».
 
- Если там есть запись с аналогичным 
Настройка на стороне клиента
Отправка данных на https://kaminari.systems/v2/ping
Когда пользователь приходит на страницу, необходимо на бэкенде сгенерировать kmnrId — уникальный идентификатор показа. 
Затем с помощью PHP, Python, NodeJS — в зависимости от того, на чём у вас написан сайт — послать на URL https://kaminari.systems/v2/ping инициализирующую информацию.
Запрос может не быть принят с первого раз (в таком случае сервер пришлёт статус 204), мы советуем слать запрос в цикле до получения ответа со статусом 200.
Данные должны слаться методом POST в формате JSON.
Список параметров:
| Название | Описание параметра | Обязательный? | 
|---|---|---|
| kmnrId | Рандомный идентификатор показа. Генерируется на стороне клиента. Это может быть всё, что угодно — UUID, случайное число, случайная текстовая строка. Должна слаться в виде строки. | да | 
| kmnrKey | Идентификатор интеграции, в рамках которой анализируется показ. | да | 
| sub1 | Заполенные суб-метки. Если какие-то метки вы не используете, их слать не обязательно. | нет | 
| sub2 | ... | нет | 
| sub3 | ... | нет | 
| sub4 | ... | нет | 
| sub5 | ... | нет | 
| sub6 | ... | нет | 
| sub7 | ... | нет | 
Также в этот запрос должны быть добавлены следующие заголовки, полученные от пользователя:
| Название | Описание | 
|---|---|
| user-agent | user agent пользователя | 
| referer | страница, с которой пришёл пользователь | 
| accept-language | язык интерфейса браузера | 
| x-original-ip | реальный IP пользователя | 
| x-forwarded-for | IP | 
| x-real-ip | IP | 
| sec-ch-ua-arch | |
| sec-ch-ua | |
| sec-ch-ua-full-version | |
| device-memory | |
| dpr | |
| sec-ch-ua-mobile | |
| sec-ch-ua-model | |
| sec-ch-ua-platform | |
| sec-ch-ua-platform-version | |
| viewport-width | 
Пример curl-запроса:
curl 'https://kaminari.systems/v2/ping' \
  -H 'accept: application/json' \ 
  -H 'accept-language: en-US,en;q=0.9' \ 
  -H 'cache-control: no-cache' \ 
  -H 'content-type: text/plain;charset=UTF-8' \
  -H 'origin: https://test.com' \ 
  -H 'pragma: no-cache' \ 
  -H 'referer: https://test.com/' \ 
  -H 'user-agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36' 
  --data-raw '{"kmnrKey":"XXXXXXXX","kmnrId":"1125570260","sub1":"test","sub2":"1001","sub3":"10","sub4":"1385282124113622","sub5":"222","sub6":"555666","sub7":"8833705265931305"}' 
  --compressed
Пример на PHP:
$url = 'https://kaminari.systems/v2/ping';
$ch = curl_init( $url );
$payload = json_encode([
    'kmnrKey' => 'XXXXXXXX',
    'kmnrId' => '1125570260',
    'sub1' => 'test',
    'sub2' => '1001',
    'sub3' => '10',
    'sub4' => '1385282124113622',
    'sub5' => '222',
    'sub6' => '555666',
    'sub7' => '8833705265931305',
]);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
    'Content-Type:application/json',
    'Accept-Language:' . $_SERVER['HTTP_ACCEPT_LANGUAGE'],
    'User-Agent:' . $_SERVER['HTTP_USER_AGENT'],
    isset($_SERVER['HTTP_REFERER']) ? 'Referer:' . $_SERVER['HTTP_REFERER'] : '',
]);
curl_exec($ch);
curl_close($ch);
Добавление kmnrId в скрипт
Сгенерированный kmnrId, а так же kmnrKey и субки затем нужно прокинуть в вызов JS-скрипта на странице.
<script>
    window.kmnr = {
        kmnrKey: 'XXXXXXXX',
        kmnrId: '1125570260',
        sub1: 'test',
        sub2: '1001',
        sub3: '10',
        sub4: '1385282124113622',
        sub5: '222',
        sub6: '555666',
        sub7: '8833705265931305',
    };
    var kmnrSc = document.createElement('script');
    var kmnrPrnt = document.getElementsByTagName('head')[0] || document.body;
    kmnrSc.setAttribute('async', true);
    kmnrSc.setAttribute('charset', 'utf-8');
    kmnrSc.src = '//kaminari.systems/v1/script.js?kmnrKey=' + window.kmnr.kmnrKey;
    kmnrPrnt && kmnrPrnt.appendChild(kmnrSc);
</script>
Тестирование
Для тестирования отправления данных и соответствия их API можно воспользоваться URL https://kaminari.systems/v1/pingtest
Пример на PHP:
$url = 'https://kaminari.systems/v1/pingtest';
try {
    $ch = curl_init( $url );
    $payload = json_encode([
        'kmnrKey' => 'XXXXXXXX',
        'kmnrId' => (string)mt_rand(),
        'sub1' => 'test',
        'sub2' => '1001',
        'sub3' => '10',
        'sub4' => '40',
        'sub5' => '555',
        'sub6' => '6',
        'sub7' => '77777',
    ]);
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
    curl_setopt( $ch, CURLOPT_HTTPHEADER, [
        'Content-Type:application/json',
        'Accept-Language:' . $_SERVER['HTTP_ACCEPT_LANGUAGE'],
        'User-Agent:' . $_SERVER['HTTP_USER_AGENT'],
        'DPR:2',
        isset($_SERVER['HTTP_REFERER']) ? 'Referer:' . $_SERVER['HTTP_REFERER'] : 'Referer:""',
    ]);
    curl_setopt( $ch, CURLOPT_HEADER, true);
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    
    $response = curl_exec($ch);
    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    $body = str_replace('", "', '",<br />    "', $body);
    $body = str_replace('{ "', '{<br />    "', $body);
    echo "<pre>1. Response length: $header_size</pre>";
    echo "<pre>2. Response body: $body</pre>";
    'curl error: ' . curl_error($ch);
    curl_close($ch);
} catch (Exception $e) {
    echo "Error register User: {$e->getMessage()}";
}
Ответ:
1. Response length: 287
2. Response body: {"errors": {
    "X-Forwarded-For":"recommended to add in request headers",
    "X-Real-IP":"recommended to add in request headers",
    "sec-ch-ua-arch":"recommended to add in request headers",
    "sec-ch-ua":"recommended to add in request headers",
    "sec-ch-ua-full-version":"recommended to add in request headers",
    "device-memory":"recommended to add in request headers",
    "sec-ch-ua-mobile":"recommended to add in request headers",
    "sec-ch-ua-model":"recommended to add in request headers",
    "sec-ch-ua-platform":"recommended to add in request headers",
    "sec-ch-ua-platform-version":"recommended to add in request headers",
    "viewport-width":"recommended to add in request headers"}}
Пример на Node.js:
const https = require('https');
const payload = JSON.stringify({
    'kmnrKey': 'XXXXXXXX',
    'kmnrId': (Math.random() + 1).toString(36).substring(9),
    'sub1': 'test',
    'sub2': '1001',
    'sub3': '10',
    'sub4': '40',
    'sub5': '555',
    'sub6': '6',
    'sub7': '77777',
});
const options = {
    host: 'kaminari.click',
    port: 443,
    path: '/v1/pingtest',
    method: 'POST',
    headers: { 
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(payload),
        'Accept-Language': 'en-US,en;q=0.5',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0',
        'DPR': '2',
        'Referer': '""',
    }
};
const req = https
    .request(options, (res) => {
        let data = '';
        res.on('data', (chunk) => {
            data += chunk;
        });
        
        res.on('end', () => {
            try {
                data = JSON.parse(data);
                console.log(data);
            } catch {
                console.log(data);
            }
        });
    });
req.on('error', (err) => {
    console.log("Error: " + err.message);
});
req.write(payload);
req.end();
Ответ:
{
  errors: {
    'X-Forwarded-For': 'recommended to add in request headers',
    'X-Real-IP': 'recommended to add in request headers',
    'sec-ch-ua-arch': 'recommended to add in request headers',
    'sec-ch-ua': 'recommended to add in request headers',
    'sec-ch-ua-full-version': 'recommended to add in request headers',
    'device-memory': 'recommended to add in request headers',
    'sec-ch-ua-mobile': 'recommended to add in request headers',
    'sec-ch-ua-model': 'recommended to add in request headers',
    'sec-ch-ua-platform': 'recommended to add in request headers',
    'sec-ch-ua-platform-version': 'recommended to add in request headers',
    'viewport-width': 'recommended to add in request headers'
  }
}