वोट पुरस्कार

Vote rewards server.vote Webhook event use करते हैं: handler event receive करता है, API से vote data लेता है, player को आपके system में ढूंढता है और reward सिर्फ एक बार देता है।

इस method को integrate करने के लिए पहले project Webhook configure करें और signature verify करें। Vote data GET /votes/:vote_id से लिया जाता है।

Flow

  1. Webhook event accept करें और signature verify करें। अगर is_test true है, vote fetch किए बिना और reward दिए बिना 204 लौटाएं।
  2. Confirm करें कि event_type server.vote है।
  3. event_id लें: server.vote के लिए यह vote ID है।
  4. GET /votes/:vote_id से vote data लें और player को अपने system में find करें।
  5. event_type + event_id से duplicate processing protection लागू करें और reward उसी transaction में दें।
  6. अगर reward safely नहीं दिया जा सकता, error response लौटाएं, cause fix करें और interface से delivery resend करें

Reward उदाहरण

मान लें player PlayerName ने ID 1 वाले server के लिए vote किया और system को 100 coins जोड़ने हैं।

  1. GAMEMONITORING event_type: server.vote और event_id: 9824cabb-2203-437e-9b6c-aba43dde3e4b के साथ Webhook भेजता है।
  2. Handler signature verify करता है। Signature invalid हो तो 401 लौटाकर रुकता है।
  3. Handler GET /votes/9824cabb-2203-437e-9b6c-aba43dde3e4b request करता है और nickname, server, user data लेता है।
  4. अपने database में handler nickname या account link से local account खोजता है।
  5. Transaction में handler server.vote + event_id से duplicate processing protection लागू करता है और 100 coins जोड़ता है।
  6. उसी event की repeated delivery को उन्हीं duplicate processing rules से handle करें।

यही flow items, roles, VIP time, promo code या internal queue के लिए भी काम करता है।

Vote event

जब server को vote मिलता है, GAMEMONITORING server.vote event भेजता है। Body में सिर्फ delivery data होता है: event_type, event_id, is_test और signature। Full vote data अलग से request करें।

Event उदाहरण
{
  "event_id": "9824cabb-2203-437e-9b6c-aba43dde3e4b",
  "event_type": "server.vote",
  "is_test": false,
  "signature": "ae83b8aba88a3a9ab3b97b1f6d65664da5628a9cb64d56d5132807bca5472e4f"
}

इस event में event_id vote ID है। Nickname, server या user data के source के रूप में Webhook body इस्तेमाल न करें: ये data API से आता है।

Vote data प्राप्त करें

event_id को vote_id की तरह use करें और GET /votes/:vote_id से vote data request करें:

Vote data अनुरोध
curl -sS "https://api.gamemonitoring.in/votes/9824cabb-2203-437e-9b6c-aba43dde3e4b"

Reward delivery के लिए आम तौर पर response.nickname, response.server और public response.user data चाहिए। अगर reward specific server पर depend करता है, हमेशा response.server.id check करें।

Mapping example: response.nickname आपके database में player account ढूंढता है, response.server.id server reward rule चुनता है, और response.user.id reward log में save किया जा सकता है।

API temporary unavailable हो या unexpected response दे, तो बिना जांच reward न दें। Error code लौटाएं, कारण fix करें और delivery retry करें

पूरा उदाहरण

Example signature verify करता है, vote data लेता है, duplicate rewards रोकता है और reward add करता है। Users table name, balance field और player lookup rule को अपने system structure से replace करें।

Example चलाने से पहले project Webhook configure करें, GET /votes/:vote_id check करें और SQL user update queries को अपने account model से बदलें।

php
<?php
// Set the webhook token, API URL and local database connection.
$secret = 'paste-webhook-token-here';
$apiUrl = 'https://api.gamemonitoring.in';
$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);