Oy ödülleri

Oy ödülleri server.vote Webhook olayını kullanır: handler olayı alır, API ile oy verisini çeker, oyuncuyu kendi sisteminizde bulur ve ödülü yalnızca bir kez verir.

Bu yöntemi entegre etmek için önce proje Webhook’unu ayarlayın ve signature doğrulayın. Oy verisi GET /votes/:vote_id ile istenir.

Akış nasıl çalışır

  1. Webhook olayını alın ve signature doğrulayın. is_test true ise oyu çekmeden ve ödül vermeden 204 dönün.
  2. event_type değerinin server.vote olduğundan emin olun.
  3. event_id değerini alın: server.vote için bu oy ID’sidir.
  4. GET /votes/:vote_id ile oy verisini alın ve oyuncuyu kendi sisteminizde bulun.
  5. event_type + event_id ile tekrar işleme korumasını uygulayın ve ödülü aynı transaction içinde verin.
  6. Ödül güvenli şekilde verilemiyorsa başarısız yanıt dönün, sebebi düzeltin ve teslimatı arayüzden tekrar gönderin.

Ödül örneği

PlayerName oyuncusunun ID’si 1 olan sunucu için oy verdiğini ve sisteminizin 100 coin eklemesi gerektiğini varsayalım.

  1. GAMEMONITORING event_type: server.vote ve event_id: 9824cabb-2203-437e-9b6c-aba43dde3e4b ile Webhook gönderir.
  2. Handler signature doğrular. İmza geçersizse 401 döner ve durur.
  3. Handler GET /votes/9824cabb-2203-437e-9b6c-aba43dde3e4b ister ve nickname, server, user bilgisi alır.
  4. Kendi veritabanınızda handler nickname veya hesap bağlantınızla yerel hesabı bulur.
  5. Transaction içinde handler server.vote + event_id ile tekrar işleme korumasını uygular ve 100 coin yazar.
  6. Aynı event’in tekrar teslimatını aynı tekrar işleme koruması kurallarıyla işleyin.

Aynı akış item, rol, VIP süresi, promosyon kodu veya iç kuyruk için de kullanılabilir.

Oy olayı

Bir sunucu oy aldığında GAMEMONITORING server.vote olayı gönderir. Gövde yalnızca teslimat verilerini içerir: event_type, event_id, is_test ve signature. Tam oy verisini ayrıca isteyin.

Olay örneği
{
  "event_id": "9824cabb-2203-437e-9b6c-aba43dde3e4b",
  "event_type": "server.vote",
  "is_test": false,
  "signature": "ae83b8aba88a3a9ab3b97b1f6d65664da5628a9cb64d56d5132807bca5472e4f"
}

Bu olayda event_id oy ID’sidir. Nickname, sunucu veya kullanıcı kaynağı olarak Webhook gövdesini kullanmayın: bu veriler API’den gelir.

Oy verisini alma

event_id değerini vote_id olarak kullanın ve oy verisini GET /votes/:vote_id ile isteyin:

Oy verisi isteği
curl -sS "https://api.gamemonitoring.tr/votes/9824cabb-2203-437e-9b6c-aba43dde3e4b"

Ödül teslimi için genellikle response.nickname, response.server ve public response.user verileri gerekir. Ödül belirli bir sunucuya bağlıysa mutlaka response.server.id kontrol edin.

Eşleme örneği: response.nickname oyuncu hesabını veritabanında bulur, response.server.id server ödül kuralını seçer, response.user.id ödül loguna yazılabilir.

API geçici olarak kullanılamıyorsa veya beklenmeyen yanıt dönerse körlemesine ödül vermeyin. Hata kodu dönün, nedeni düzeltin ve teslimatı tekrar gönderin.

Tam örnek

Örnek imzayı doğrular, oy verisini alır, ödülün tekrar verilmesini önler ve ödülü ekler. Kullanıcı tablosu adı, bakiye alanı ve oyuncu arama kuralını kendi sistem yapınızla değiştirin.

Örneği çalıştırmadan önce proje Webhook’unu ayarlayın, GET /votes/:vote_id endpoint’ini kontrol edin ve SQL user update sorgularını kendi hesap modelinizle değiştirin.

php
<?php
// Set the webhook token, API URL and local database connection.
$secret = 'paste-webhook-token-here';
$apiUrl = 'https://api.gamemonitoring.tr';
$rewardAmount = '1.00';
$pdo = new PDO('mysql:host=127.0.0.1;dbname=game;charset=utf8mb4', 'game', 'password', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

// Read the JSON payload sent by GAMEMONITORING.
$data = json_decode(file_get_contents('php://input'), true) ?: [];
$isTest = ($data['is_test'] ?? false) === true;
$signingData = array_replace($data, ['is_test' => $isTest ? 'true' : 'false']);

// Prepare payload keys for signature verification.
$fields = array_values(array_filter(array_keys($data), fn($field) => $field !== 'signature'));
sort($fields, SORT_STRING);

// Build the signing string and expected HMAC.
$signing = implode('&', array_map(fn($field) => $field . '=' . (string) ($signingData[$field] ?? ''), $fields));
$expected = hash_hmac('sha256', $signing, $secret);
$actual = (string) ($data['signature'] ?? '');

// Reject requests with an invalid signature.
if (!hash_equals($expected, $actual)) {
    http_response_code(401);
    exit;
}

// Acknowledge test deliveries without changing balance.
if ($isTest) {
    http_response_code(204);
    exit;
}

// Process server vote events.
if (($data['event_type'] ?? '') === 'server.vote') {
    $eventType = (string) $data['event_type'];
    $eventId = (string) $data['event_id'];

    // Load full vote data by event_id.
    $voteUrl = $apiUrl . '/votes/' . rawurlencode($eventId);
    $voteResponse = json_decode(file_get_contents($voteUrl), true) ?: [];
    $vote = $voteResponse['response'] ?? null;
    $voteServerId = (string) ($vote['server']['id'] ?? '');

    // Use vote nickname to update the local account. Use $voteServerId for per-server rules.
    $nickname = trim((string) ($vote['nickname'] ?? ''));

    if ($nickname !== '') {
        // Keep deduplication and reward update in one transaction.
        $pdo->beginTransaction();

        try {
            // Store the event once; duplicate deliveries affect zero rows.
            $reward = $pdo->prepare('INSERT IGNORE INTO gamemonitoring_webhooks (event_type, event_id) VALUES (?, ?)');
            $reward->execute([$eventType, $eventId]);

            // Reward the local user only for a newly stored event.
            if ($reward->rowCount() === 1) {
                $balance = $pdo->prepare('UPDATE users SET balance = balance + ? WHERE nickname = ?');
                $balance->execute([$rewardAmount, $nickname]);
            }

            // Commit after deduplication and balance update succeed.
            $pdo->commit();
        } catch (Throwable $error) {
            // Roll back if any database step fails.
            $pdo->rollBack();
            throw $error;
        }
    }
}

http_response_code(204);