Récompenser les votes avec l'API
Pour Minecraft et FiveM, des plugins prêts à l'emploi existent (voir les guides). Pour tous les autres jeux, l'API de Servote te permet de donner une récompense quand un joueur vote, avec n'importe quel langage capable de faire une requête web.
Sommaire
Le principe
- Le joueur vote sur la page de ton serveur en indiquant son pseudo et, pour les jeux Steam, son SteamID64 (facultatif).
- Ton serveur (ton script, ton plugin ou ton bot) demande à l'API de « réclamer » le vote de ce joueur.
- L'API répond
claimed:1= le vote vient d'être réclamé, donne la récompense ;2= déjà réclamé, ne donne rien ;0= aucun vote récent.
Un vote n'est réclamable qu'une seule fois, même si plusieurs scripts ou serveurs interrogent l'API en même temps : c'est ce qui empêche la double récompense. Un vote reste réclamable pendant 2 heures.
Mise en place en 4 étapes
Récupère ton token de vote
Sur ton dashboard, copie le token de vote de ton serveur et garde-le secret. Vérifie aussi que l'option « Activer le plugin / l'API de vote » est cochée dans ta fiche.
Choisis comment reconnaître le joueur
claim-username: par pseudo (les majuscules sont ignorées). Simple, mais le pseudo saisi sur le site doit être identique à celui du jeu.claim-steam: par SteamID64, plus fiable pour les jeux Steam, mais le joueur doit l'avoir renseigné au moment du vote.
Appelle l'API depuis ton serveur
Envoie le token dans l'en-tête Authorization: Bearer TON_TOKEN. Ajoute standard_http_code=true : l'API répond alors toujours en HTTP 200 et le vrai statut est dans le champ code du JSON (utile quand un client HTTP de jeu ignore le contenu des erreurs).
curl -H "Authorization: Bearer TON_TOKEN" \
"https://servote.fr/api/v1/votes/claim-username?playername=Steve&standard_http_code=true"
# Réponse :
# {"code":200,"success":true,"claimed":1,"message":"Vote réclamé."}Donne la récompense quand claimed vaut 1
Déclenche l'appel quand le joueur tape une commande (par exemple !vote ou /vote), ou automatiquement (voir les bonnes pratiques). Documentation complète des routes : API de vote.
Exemples de code
Adapte ces exemples à ton serveur, et lis le code avant de le mettre en production.
const TOKEN = process.env.SERVOTE_TOKEN;
// 0 = aucun vote récent, 1 = récompense à donner maintenant, 2 = déjà réclamé
async function claim(playerName) {
const url = new URL("https://servote.fr/api/v1/votes/claim-username");
url.searchParams.set("playername", playerName);
url.searchParams.set("standard_http_code", "true");
const res = await fetch(url, { headers: { Authorization: `Bearer ${TOKEN}` } });
const data = await res.json();
if (data.code !== 200) throw new Error(data.message);
return data.claimed;
}import os
import requests
TOKEN = os.environ["SERVOTE_TOKEN"]
def claim(player_name):
"""0 = aucun vote récent, 1 = récompense à donner, 2 = déjà réclamé"""
r = requests.get(
"https://servote.fr/api/v1/votes/claim-username",
params={"playername": player_name, "standard_http_code": "true"},
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=10,
)
data = r.json()
if data["code"] != 200:
raise RuntimeError(data["message"])
return data["claimed"]Exemples propres à un jeu : non testés
Les deux exemples ci-dessous suivent la documentation de leurs plateformes mais n'ont pas encore été essayés sur un vrai serveur Garry's Mod ou Rust. Teste-les sur un serveur de test, et adapte la récompense (argent, objet, permission) à ton mode de jeu.
-- garrysmod/lua/autorun/server/servote_vote.lua
local TOKEN = "COLLE_TON_TOKEN_ICI"
local URL = "https://servote.fr/api/v1/votes/claim-username"
local function reward(ply)
ply:ChatPrint("Merci pour ton vote !")
-- Exemple DarkRP : ply:addMoney(500)
end
hook.Add("PlayerSay", "ServoteVote", function(ply, text)
if string.lower(text) ~= "!vote" then return end
local name = ply:Nick()
http.Fetch(URL .. "?standard_http_code=true&playername=" .. util.URLEncode(name),
function(body)
if not IsValid(ply) then return end
local data = util.JSONToTable(body)
if not data or data.code ~= 200 then ply:ChatPrint("Service de vote indisponible.") return end
if data.claimed == 1 then reward(ply)
elseif data.claimed == 2 then ply:ChatPrint("Récompense déjà récupérée.")
else ply:ChatPrint("Aucun vote récent trouvé pour " .. name .. ".") end
end,
function() if IsValid(ply) then ply:ChatPrint("Service de vote indisponible.") end end,
{ Authorization = "Bearer " .. TOKEN })
return ""
end)// oxide/plugins/ServoteVote.cs
using System.Collections.Generic;
namespace Oxide.Plugins
{
[Info("ServoteVote", "Servote", "0.1.0")]
[Description("Récompense les votes Servote avec /vote")]
class ServoteVote : CovalencePlugin
{
private const string Token = "COLLE_TON_TOKEN_ICI";
[Command("vote")]
private void CmdVote(IPlayer player, string command, string[] args)
{
// Sur Rust, player.Id est le SteamID64 : le joueur doit l'avoir saisi sur Servote.
var url = "https://servote.fr/api/v1/votes/claim-steam?standard_http_code=true&steam_id=" + player.Id;
var headers = new Dictionary<string, string> { ["Authorization"] = "Bearer " + Token };
webrequest.Enqueue(url, null, (code, body) =>
{
if (code != 200 || string.IsNullOrEmpty(body)) { player.Reply("Service de vote indisponible."); return; }
if (body.Contains("\"claimed\":1"))
{
server.Command("inventory.giveto " + player.Id + " scrap 100");
player.Reply("Merci pour ton vote !");
}
else if (body.Contains("\"claimed\":2")) player.Reply("Récompense déjà récupérée.");
else player.Reply("Aucun vote trouvé : vote sur Servote avec ton SteamID64.");
}, this, Core.Libraries.RequestMethod.GET, headers);
}
}
}Bonnes pratiques et sécurité
- Garde le token côté serveur. Ne le mets jamais dans un fichier téléchargé par les joueurs, une page web publique ou un dépôt public. S'il fuit, contacte-nous pour le renouveler.
- Ne construis jamais une commande avec le pseudo saisi sur le site. C'est un texte libre : un pseudo contenant
;ou des guillemets peut détourner une commande console. Utilise le nom réel du joueur connecté ou son identifiant numérique. - Respecte la limite de 120 requêtes par minute. Pour récompenser automatiquement, interroge
votes/last(les votes de la dernière heure) toutes les 60 secondes et réclame seulement ceux des joueurs connectés, plutôt qu'une requête par joueur. - Gère les erreurs. Si l'appel échoue (réseau, 429), ne donne pas la récompense et propose au joueur de réessayer : un vote non réclamé reste disponible 2 heures.
Questions fréquentes
+« code 401 » ou « Token invalide »
Le token est absent ou incorrect. Envoie-le dans l'en-tête Authorization: Bearer … ou dans le paramètre server_token.
+« code 403 » : API désactivée
Coche « Activer le plugin / l'API de vote » dans la fiche de ton serveur (Dashboard → Modifier).
+claimed vaut toujours 0
Le pseudo (ou le SteamID64) envoyé ne correspond pas à celui saisi au moment du vote, ou le vote a plus de 2 heures.
+Mon jeu n'est pas dans les guides
Ce guide fonctionne pour n'importe quel jeu capable d'exécuter un script ou un plugin qui fait une requête web. Si tu bloques, écris-nous via Contact en précisant ton jeu.