Game Result Webhook Handler

Header Parameters :

  • X-Client-ID : unique id given by admin to identify game's identity.

  • X-Signature : HMAC Signature of the payload using the game's unique secret key.

  • X-Timestamp : unique timestamp.

🔐 Security & Integrity

  1. HMAC Signature Verification

    • Ensures that all incoming game session events are properly signed using a pre-shared secret.

  2. Replay Attack Prevention

    • Uses timestamps and unique signatures to prevent the same event from being processed multiple times.

Payload :

{
    roomId: ROOM_ID,
    sessionResults: [
        { userId: 1, rankUpdate: 10, winner: true },
        { userId: 2, rankUpdate: 10, winner: false }
    ]
}

Client Example ( Node.js )

const axios = require('axios');
const crypto = require('crypto');

const CONFIG = {
    CLIENT_ID: '1a473910-3437-4f4e-a6e8-e74daba8ce4e',
    SECRET_KEY: 'ZfmF5ZekzsdmZdx8fZG1YaPF3zHD2gGyhPpx9rKkxII',
    BASE_WEBHOOK_URL: 'http://api.bananaclip.io/api/v1/game-sessions'
};

const ROOM_ID = 'e6e92345-ae24-4d44-acd2-b2145d21c2aw';

/**
 * Generate an HMAC-SHA256 signature for the payload
 * @param {string} payload - JSON string of the webhook event
 * @returns {string} - Base64-encoded HMAC signature
 */
function generateSignature(payload) {
    return crypto.createHmac('sha256', Buffer.from(CONFIG.SECRET_KEY, 'base64'))
        .update(payload)
        .digest('base64');
}

/**
 * Send a webhook event with security headers
 * @param {Object} event - The event payload
 */
async function sendWebhookEvent(event, route) {
    const payload = JSON.stringify(event);
    const headers = {
        'X-Client-ID': CONFIG.CLIENT_ID,
        'X-Signature': generateSignature(payload),
        'X-Timestamp': Math.floor(Date.now() / 1000),
        'Content-Type': 'application/json'
    };

    const url = CONFIG.BASE_WEBHOOK_URL + route;

    try {

        await axios.post(url, payload, { headers });
        console.log('✅ Webhook sent successfully:', CONFIG.BASE_WEBHOOK_URL, payload, headers);
    } catch (error) {
        console.error('❌ Error sending webhook:', error.response ? error.response.data : error.message);
    }
}

// Webhook events
const gameResultEvent = {
    roomId: ROOM_ID,
    sessionResults: [
        { userId: 1, rankUpdate: 10, winner: true },
        { userId: 2, rankUpdate: 10, winner: false }
    ]
};

// Execute webhook requests
async function main() {
    await sendWebhookEvent(gameResultEvent,"/game/result");
}

main();

Last updated