Recevoir les votes par webhook
Votifier demande un port entrant ouvert sur votre serveur de jeu. Si votre hébergeur ne le permet pas, ou si votre réseau a déjà son propre service web, le webhook est plus simple : nous envoyons chaque vote en POST à l'adresse de votre choix.
Les deux méthodes sont cumulables. Activez le webhook depuis la fiche de votre serveur, dans votre tableau de bord.
Ce que vous recevez
Un corps JSON, et trois en-têtes.
POST /votes HTTP/1.1
Content-Type: application/json
X-CubeVote-Event: vote
X-CubeVote-Timestamp: 1790000000
X-CubeVote-Signature: sha256=3f7a…
{
"server": { "slug": "mon-serveur", "name": "Mon Serveur" },
"username": "Steve",
"votes": { "month": 412, "total": 5120 },
"streak": 7,
"suspicious": false,
"at": "2026-09-20T18:04:11.482Z"
}suspicious signale un vote retenu au classement mais jugé douteux par nos heuristiques. À vous de décider si vous distribuez la récompense, nous vous conseillons de le faire, et de surveiller plutôt les récidives.
Vérifier la signature
Sans vérification, n'importe qui connaissant votre adresse pourrait vous envoyer de faux votes. La signature est le HMAC-SHA256 de horodatage + "." + corps brut, avec le secret affiché dans votre tableau de bord.
Comparez-la en temps constant, et refusez un horodatage vieux de plus de cinq minutes : cela ferme la porte au rejeu d'un ancien message.
Node.js
import crypto from "node:crypto";
app.post("/votes", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.get("X-CubeVote-Timestamp") ?? "";
const received = (req.get("X-CubeVote-Signature") ?? "").replace("sha256=", "");
// Refuser un message rejoué.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
return res.status(408).end();
}
const expected = crypto
.createHmac("sha256", process.env.CUBEVOTE_SECRET)
.update(timestamp + "." + req.body.toString("utf8"))
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(received);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(401).end();
}
const vote = JSON.parse(req.body.toString("utf8"));
donnerRecompense(vote.username);
res.status(200).end();
});PHP
<?php
$corps = file_get_contents("php://input");
$horodatage = $_SERVER["HTTP_X_CUBEVOTE_TIMESTAMP"] ?? "";
$recue = str_replace("sha256=", "", $_SERVER["HTTP_X_CUBEVOTE_SIGNATURE"] ?? "");
if (abs(time() - (int) $horodatage) > 300) { http_response_code(408); exit; }
$attendue = hash_hmac("sha256", $horodatage . "." . $corps, getenv("CUBEVOTE_SECRET"));
if (!hash_equals($attendue, $recue)) { http_response_code(401); exit; }
$vote = json_decode($corps, true);
donner_recompense($vote["username"]);Ce que nous attendons de vous
- Répondre vite. Un code 2xx en moins de cinq secondes. Faites le travail long après avoir répondu.
- Être tolérant aux doublons. En cas de doute sur la livraison, mieux vaut ignorer un vote déjà traité que d'en distribuer deux fois la récompense.
- Ne pas rediriger. Les redirections ne sont pas suivies : donnez directement l'adresse finale.
Un envoi qui échoue n'est pas réessayé : le vote reste enregistré chez nous, et vous pouvez le récupérer à tout moment avec l'API de vote. C'est le filet de sécurité recommandé.