Nasıl Çalışır
metin2.gg Vote Rewards API, Metin2 sunucunuzun oyuncular oy verdiğinde otomatik olarak algılamasını ve oyun içi ödüller vermesini sağlar. Akış basittir: oyuncular metin2.gg'de karakter adlarıyla oy verir ve sunucunuz bu oyları kontrol etmek ve talep etmek için API'mizi sorgular.
İki entegrasyon modu vardır — kurulumunuza uygun olanı seçin:
Polling (Önerilen)
Sunucunuz düzenli olarak API'mizi çağırarak yeni oyları kontrol eder. Uygulanması en kolay — her Metin2 sunucu kurulumunda çalışır. Sadece oyun sunucu kodunuza bir HTTP isteği ekleyin.
Webhooks (Gelişmiş)
Bir oyuncu oy verdiği anda metin2.gg sunucunuza anında bildirim gönderir. Gerçek zamanlı, ancak tarafınızda herkese açık bir HTTPS uç noktası gerektirir.
Kimlik Doğrulama
Tüm API istekleri, X-API-Key başlığı aracılığıyla gönderilen bir API anahtarı gerektirir. Anahtarlar mg_live_... formatındadır ve sunucu panelinizden oluşturulur.
X-API-Key: mg_live_5bef...1a70API anahtarınız bir sunucuya bağlıdır ve yalnızca oluşturulduğunda bir kez gösterilir. Kaybederseniz, panelden yeni bir tane oluşturun (eski anahtar hemen geçersiz olur).
API Anahtarınızı Nasıl Alırsınız
- 1Panelim → Sunucularım bölümüne gidin. Yönetim sayfasını açmak için sunucunuzun adına tıklayın.
- 2Yönetim sayfasında, henüz yapmadıysanız sahipliği doğrulayın (DNS TXT kaydı veya meta etiketi).
- 3Partner statüsünü açmak için sunucunuzun web sitesine metin2.gg'ye bir geri bağlantı ekleyin.
- 4Sunucunuzun yönetim sayfasında "API Ayarları" butonuna tıklayın. Ardından "API Anahtarı Oluştur"a tıklayın ve kopyalayın — yalnızca bir kez gösterilir.
Oy Durumunu Kontrol Et
Belirli bir oyuncunun talep edilmemiş bir oyu olup olmadığını kontrol edin. Bekleyen bir oy varsa, otomatik olarak talep edilir (kullanılmış olarak işaretlenir), böylece aynı oy iki kez talep edilemez.
GET /api/v1/vote/check?player_id=PlayerName HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HERESorgu Parametreleri
| Parameter | Type | Required | Description |
|---|---|---|---|
| player_id | string | Yes | Oyuncunun oy verirken kullandığı karakter adı. Büyük/küçük harf duyarsız. |
Yanıt
Oyuncunun talep edilmemiş bir oyu var (şimdi talep edildi)
{
"voted": true,
"player_id": "PlayerName",
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"voted_at": "2026-03-02T14:30:00Z"
}Bu oyuncu için bekleyen oy yok
{
"voted": false
}Talep Edilmemiş Oyları Listele
Sunucunuz için tüm talep edilmemiş oyları alın. Toplu işleme için kullanışlı — örneğin, her 5 dakikada bir çalışan ve tüm bekleyen oylar için ödülleri tek seferde veren bir cron görevi.
GET /api/v1/vote/unclaimed?limit=50 HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HERESorgu Parametreleri
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Döndürülecek maksimum oy sayısı (1–100, varsayılan 50). |
Yanıt
{
"votes": [
{
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"player_id": "PlayerName",
"voted_at": "2026-03-02T14:30:00Z"
},
{
"vote_id": "660e8400-e29b-41d4-a716-446655440001",
"player_id": "AnotherPlayer",
"voted_at": "2026-03-02T14:32:00Z"
}
],
"total": 2
}Toplu Oy Talep Et
Birden fazla oyu tek bir istekte talep edilmiş olarak işaretleyin. Bunu unclaimed uç noktasından oyları işledikten sonra kullanın.
POST /api/v1/vote/claim HTTP/1.1
Host: metin2.gg
Content-Type: application/json
X-API-Key: mg_live_YOUR_KEY_HERE
{
"vote_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
]
}İstek Gövdesi (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
| vote_ids | string[] | Yes | Talep edilecek oy UUID'lerinin dizisi. İstek başına maksimum 100. |
Yanıt
{
"claimed": 2,
"failed": 0
}Webhooks
Polling yerine, bir oyuncu oy verdiğinde gerçek zamanlı push bildirimleri alabilirsiniz. Webhook URL'nizi sunucu panelinde API Ayarları altından yapılandırın.
Webhook Yükü
POST https://your-server.com/api/vote-webhook HTTP/1.1
Content-Type: application/json
X-Metin2GG-Signature: a1b2c3d4e5f6...
{
"event": "vote.created",
"vote_id": "550e8400-e29b-41d4-a716-446655440000",
"server_id": "your-server-uuid",
"player_id": "PlayerName",
"voted_at": "2026-03-02T14:30:00Z",
"timestamp": "2026-03-02T14:30:01Z"
}İmzayı Doğrulama
Her webhook isteği, API gizli anahtarınızla imzalanmış ham istek gövdesinin HMAC-SHA256 hex özetini içeren bir X-Metin2GG-Signature başlığı içerir. Yüke güvenmeden önce her zaman bu imzayı doğrulayın.
import hmac
import hashlib
def verify_webhook(request_body: bytes, signature: str, secret: str) -> bool:
"""Verify the X-Metin2GG-Signature header."""
expected = hmac.new(
secret.encode("utf-8"),
request_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature)
# Usage in your webhook handler:
# body = request.body (raw bytes)
# sig = request.headers["X-Metin2GG-Signature"]
# if not verify_webhook(body, sig, "your_api_secret"):
# return HttpResponse(status=403)<?php
function verifyWebhook(string $body, string $signature, string $secret): bool {
$expected = hash_hmac('sha256', $body, $secret);
return hash_equals($expected, $signature);
}
// Usage in your webhook handler:
// $body = file_get_contents('php://input');
// $sig = $_SERVER['HTTP_X_METIN2GG_SIGNATURE'] ?? '';
// if (!verifyWebhook($body, $sig, 'your_api_secret')) {
// http_response_code(403);
// exit('Invalid signature');
// }Metin2 Entegrasyonu: Python Komutu
Bu scripti oyun sunucunuzun Python komut sistemine yerleştirin. Bir oyuncu oyun içinde /reward yazdığında, metin2.gg'de bekleyen bir oy kontrol eder ve ödülü verir.
# vote_reward.py — Drop into your game server's command scripts
# Works with Python 2.7+ (common in Metin2 servers)
import json
import os
METIN2GG_API_KEY = "mg_live_YOUR_KEY_HERE"
METIN2GG_API_URL = "https://metin2.gg/api/v1/vote/check"
def check_vote(player_name):
"""Check if player has a pending vote and auto-claim it."""
url = "%s?player_id=%s" % (METIN2GG_API_URL, player_name)
# Method 1: Use urllib2 (Python 2) or urllib.request (Python 3)
try:
try:
import urllib2
req = urllib2.Request(url)
req.add_header("X-API-Key", METIN2GG_API_KEY)
resp = urllib2.urlopen(req, timeout=5)
data = json.loads(resp.read())
except ImportError:
import urllib.request
req = urllib.request.Request(url)
req.add_header("X-API-Key", METIN2GG_API_KEY)
resp = urllib.request.urlopen(req, timeout=5)
data = json.loads(resp.read().decode("utf-8"))
return data.get("voted", False)
except Exception:
pass
# Method 2: Fallback to curl (works even with broken SSL)
try:
cmd = 'curl -s -H "X-API-Key: %s" "%s"' % (METIN2GG_API_KEY, url)
raw = os.popen(cmd).read()
data = json.loads(raw)
return data.get("voted", False)
except Exception:
return None
# Example usage in your game command handler:
# def cmd_reward(player):
# result = check_vote(player.GetName())
# if result is True:
# player.GiveItem(50011, 10) # Example: 10x Dragon God Coins
# player.ChatInfoMessage("Vote reward claimed!")
# elif result is False:
# player.ChatInfoMessage("No pending vote. Vote at metin2.gg!")
# else:
# player.ChatInfoMessage("Could not reach metin2.gg. Try again.")Metin2 Entegrasyonu: Quest Dosyası (Lua)
Bu quest dosyası, oyuncuların oy durumlarını kontrol edebilecekleri bir NPC etkileşimi oluşturur. Python oy kontrolünü tetikleyen sunucu tarafı bir komutu çağırır.
quest vote_reward begin
state start begin
when login or letter begin
send_letter("Vote Reward")
end
when button or info begin
say_title("Vote Reward")
say("")
say("Vote for our server on metin2.gg")
say("and claim your reward here!")
say("")
local s = select("Check My Vote", "How to Vote", "Close")
if s == 1 then
-- Triggers the Python command that checks the API
cmdchat("checkvote "..pc.get_name())
elseif s == 2 then
say_title("How to Vote")
say("")
say("1. Open metin2.gg in your browser")
say("2. Find our server page")
say("3. Enter your character name")
say("4. Click the Vote button")
say("5. Come back here to claim your reward!")
say("")
end
end
end
endMetin2 Entegrasyonu: PHP Web Paneli
Sunucunuzun bir web paneli (PHP tabanlı) varsa, panelden oyları kontrol etmek ve talep etmek için bu snippet'i kullanın. cURL destekli herhangi bir PHP 7+ ortamında çalışır.
<?php
/**
* check_vote.php — Vote check for PHP-based web panels
* Requires PHP 7.0+ with cURL extension
*/
$apiKey = "mg_live_YOUR_KEY_HERE";
$playerName = $_GET["player"] ?? "";
if (empty($playerName)) {
echo json_encode(["error" => "Missing player name"]);
exit;
}
// Check vote status
$ch = curl_init(
"https://metin2.gg/api/v1/vote/check?player_id=" . urlencode($playerName)
);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
echo json_encode(["error" => "API returned HTTP $httpCode"]);
exit;
}
$data = json_decode($response, true);
if ($data["voted"] ?? false) {
// Player has voted — grant reward via your game DB
// Example: INSERT INTO player.reward_queue (player, item_vnum, count) ...
echo json_encode([
"success" => true,
"message" => "Vote reward granted!",
"vote_id" => $data["vote_id"],
]);
} else {
echo json_encode([
"success" => false,
"message" => "No pending vote found.",
]);
}Hız Sınırları ve Hata Kodları
API, adil kullanımı sağlamak için hız sınırları uygular. Mevcut sınırlar:
- 60 requests per minute per API key
- 1,000 requests per hour per API key
| Durum | Açıklama |
|---|---|
| 200 OK | İstek başarılı. |
| 400 Bad Request | Eksik veya geçersiz parametreler. player_id veya vote_ids formatını kontrol edin. |
| 401 Unauthorized | Eksik veya geçersiz API anahtarı. X-API-Key başlığını eklediğinizden emin olun. |
| 403 Forbidden | API erişimi devre dışı — genellikle geri bağlantı kaldırıldığı için. Geri bağlantıyı yeniden ekleyin ve tekrar kontrol edin. |
| 404 Not Found | Uç nokta mevcut değil. URL yolunu iki kez kontrol edin. |
| 429 Too Many Requests | Hız sınırı aşıldı. Retry-After başlık değerinden (saniye cinsinden) sonra bekleyin ve tekrar deneyin. |
| 500 Internal Server Error | Bizim tarafımızda bir sorun oluştu. Birkaç saniye sonra tekrar deneyin. |
Yeniden Deneme Stratejisi
On 429 errors, read the Retry-After header (value in seconds) and wait before retrying. For 500 errors, retry with exponential backoff (1s, 2s, 4s).
Sorun Giderme SSS
Her istekte 401 Unauthorized alıyorum
API anahtarını X-API-Key başlığında gönderdiğinizden emin olun (sorgu parametresi veya gövde olarak değil). Anahtar mg_live_ ile başlamalıdır.
API voted: false diyor ama oyuncu oy verdiğini iddia ediyor
Oyuncu karakter adını girmeden veya farklı bir ad kullanarak oy vermiş olabilir. Oy bağlantısı URL'sini kontrol edin — ?player_id=TAM_AD içermelidir. Adlar büyük/küçük harf duyarsızdır.
403 Forbidden alıyorum
API erişiminiz duraklatılmış, muhtemelen web sitenizden metin2.gg'ye geri bağlantı kaldırıldığı için. Yeniden ekleyin ve panelde 'Şimdi Kontrol Et'e tıklayarak tekrar doğrulayın.
API'yi gerçek oylar olmadan test edebilir miyim?
Şu anda sandbox modu yoktur. Entegrasyonu uçtan uca doğrulamak için kendi sunucu listenizde bir test karakter adıyla oy verin.
Python scriptim bağlanamıyor (zaman aşımı veya SSL hatası)
Çoğu Metin2 sunucusu güncel olmayan SSL sertifikalarına sahip Python 2.7 kullanır. Python örneğinde gösterilen os.popen('curl ...') yedek yöntemini kullanın veya sunucunuzun Python CA paketini güncelleyin.
API'yi ne sıklıkla pollamalıyım?
/check uç noktası için (oyuncu başına): oyuncu ödülünü talep ettiğinde çağırın (örn. /reward komutu). /unclaimed (toplu) için: cron ile her 3–5 dakikada bir idealdir. Dakikada birden fazla pollamayın.
Birden fazla sunucu bir API anahtarını paylaşabilir mi?
Hayır. Her API anahtarı bir sunucu listesine bağlıdır. Birden fazla sunucu çalıştırıyorsanız, ilgili panel sayfalarından her biri için ayrı bir anahtar oluşturun.
Webhook uç noktam çöktüğünde ne olur?
metin2.gg başarısız webhook teslimatlarını üstel geri çekilme ile 5 defaya kadar yeniden dener. Tüm denemeler başarısız olursa, oy talep edilmemiş olarak kalır ve polling uç noktaları aracılığıyla hala alınabilir.
Entegrasyona Hazır Mısınız?
Sunucunuzu metin2.gg'ye ekleyin, bir API anahtarı oluşturun ve dakikalar içinde oy verenleri ödüllendirmeye başlayın.