Files
iddaai-be/src/example/feeder.js
T
fahricansecer 182f4aae16
Deploy Iddaai Backend / build-and-deploy (push) Successful in 33s
first (part 3: src directory)
2026-04-16 15:12:27 +03:00

276 lines
12 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const axios = require('axios');
const he = require('he'); // HTML entity decode etmek için (npm install he)
const cheerio = require('cheerio'); // HTML içinden data-settings almak için
const MATCH_ID = '18rkqb1lhon6ne1hdb6d15as'; // Barcelona - Real Madrid
// 1. ADIM: TANIMLARI (METADATA) ÇEK VE HARİTALAMA YAP
async function createMarketMap() {
// Bu URL bize HTML döndürür, ama içinde data-settings JSON'u vardır.
const url = `https://www.mackolik.com/ajax/iddaa/markets/soccer/all/${MATCH_ID}?template=all`;
const response = await axios.get(url, {
headers: { 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0' }
});
// Cheerio ile HTML'i yükle
const $ = cheerio.load(response.data.data.html);
// data-settings özniteliğini bul (Genelde "all" marketlerinde bulunur)
// Not: Bazen widget-iddaa-markets--all bazen başka class olabilir, genel arıyoruz:
const settingsRaw = $('.widget-iddaa-markets').first().attr('data-settings');
if (!settingsRaw) {
console.error("Data settings bulunamadı!");
return null;
}
// HTML Entity'lerini temizle (" -> ")
const settingsJson = JSON.parse(he.decode(settingsRaw));
// Şimdi elimizde ALTIN DEĞERİNDE bir sözlük var: marketCollection
const definitions = settingsJson.iddaaEventId.marketCollection;
// Bizim kullanacağımız Harita (Dictionary)
let marketMap = {};
// Sözlüğü oluşturuyoruz: ID -> İSİM
for (const key in definitions) {
const market = definitions[key];
const marketId = market.iddaaId || market.id; // Bazen iddaaId, bazen id kullanılır
marketMap[marketId] = {
name: market.name, // "Maç Sonucu"
outcomes: {}
};
// Seçenekleri de haritalayalım (1, X, 2, Alt, Üst)
// selectionCollectionAll varsa onu, yoksa selectionCollection kullan
const selections = market.selectionCollectionAll || market.selectionCollection;
for (const selKey in selections) {
const selection = selections[selKey];
// Outcome shortcode (Örn: 1.1) veya iddaaMarketId ile eşleşme yapabiliriz
// Live JSON'da outcome ID'leri "1.1", "1.2" gibi shortcode olarak geliyor.
marketMap[marketId].outcomes[selection.shortcode] = selection.name;
}
}
console.log("✅ Market Haritası Başarıyla Oluşturuldu (HTML'den).");
return marketMap;
}
// 2. ADIM: CANLI VERİYİ ÇEK VE HARİTA İLE BİRLEŞTİR
async function fetchLiveOdds(marketMap) {
// Bu URL sadece sayıları (oranları) verir, çok hızlıdır.
const url = `https://www.mackolik.com/ajax/iddaa/outcomes/soccer/all/${MATCH_ID}`;
const response = await axios.get(url, {
headers: { 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0' }
});
const liveMarkets = response.data.data.markets;
console.log("\n📊 GÜNCEL ORANLAR (Dinamik Eşleştirme İle):\n");
console.log(`| ${"BAHİS TÜRÜ".padEnd(35)} | ${"SEÇENEK".padEnd(15)} | ${"ORAN".padEnd(6)} |`);
console.log("-".repeat(65));
// Canlı veriyi dönüyoruz
for (const [marketId, data] of Object.entries(liveMarkets)) {
// Haritamızdan bu ID'nin adını buluyoruz
// JSON'daki marketId bazen Mackolik ID'si bazen Iddaa ID'si olabiliyor.
// Genelde 'code' alanı ile bizim map'teki ID eşleşir veya key ile.
// Senin attığın JSON'da keyler (örn: 1, 3, 184.5) Mapping ID'si olarak kullanılıyor.
// DİKKAT: Senin attığın JSON'da Keyler (1, 184.5) bizim Map'teki ID'ler olmayabilir.
// HTML JSON'undaki "id" alanı (örn: 1) ile Canlı JSON'daki Key (örn: 1) eşleşir.
// Eşleşme Algoritması:
// HTML'deki `market.id` == LiveJSON'daki `key`
// HTML Map'imizi ID bazlı (1, 3, 184.5 gibi) tekrar düzenlememiz gerekebilir ama
// senin HTML JSON'una baktığımda "id": 18, "iddaaId": 55512092 var.
// Live JSON key'i "184.5" (Bu aslında 18 nolu marketin 4.5 barajı).
// Basit Eşleştirme Denemesi (ID üzerinden):
// Live JSON'daki key (örn "1" veya "184.5") HTML map'te yoksa, "code" (50465) üzerinden arama yapabiliriz.
// Ama en garantisi HTML'deki marketCollection içindeki key yapısıdır.
// Şimdilik basit ID eşleştirmesi yapalım, eğer map'te yoksa "Bilinmeyen" yazarız.
// Live JSON Key'i ile Map arıyoruz.
// Ancak HTML'deki "id" (örn: 1) ile Live JSON key (1) tutuyor.
// Fakat "184.5" gibi olanlar HTML'de "id: 18, sov: 4.5" olarak geçiyor.
let definitions = findDefinition(marketMap, marketId, data);
let marketName = definitions ? definitions.name : `Bilinmeyen (${marketId})`;
// Eğer barajlı bir bahisse (184.5 gibi) isme barajı ekle
// (Zaten HTML'den gelen isimde "4,5 Alt/Üst" yazıyor olacak)
for (const [outcomeKey, outcomeData] of Object.entries(data.outcomes)) {
if (outcomeData.outcome !== '-') {
let label = outcomeData.label;
// Eğer label mapping'den gelirse daha doğru olur ama outcomeData.label da genelde doğrudur.
console.log(`| ${marketName.padEnd(35)} | ${label.padEnd(15)} | ${outcomeData.outcome.padEnd(6)} |`);
}
}
}
}
// Yardımcı Fonksiyon: Live JSON Key'ini HTML Map içinde bulma
function findDefinition(marketMap, liveKey, liveData) {
// 1. Doğrudan ID eşleşmesi (Örn: "1" == "1")
// HTML'i parse ederken ID'leri key olarak ayarlamalıyız.
// Yukarıdaki createMarketMap fonksiyonunu buna göre revize ettim aşağıda.
// Asıl sorun: HTML JSON'da keyler "0", "1", "2" diye gidiyor array indexi gibi.
// Ama içlerinde "id": 1, "id": 18 var.
// Biz map'i oluştururken liveKey ile eşleşecek şekilde kurmalıyız.
// LiveKey "184.5" ise -> id=18 ve sov=4.5 olanı bulmalıyız.
// Bu karmaşıklığı çözmek için MarketMap'i bir Array olarak tutup find ile aramak en iyisi.
for (const def of Object.values(marketMap)) {
// Eğer ID tutuyorsa (Örn: 1 == 1)
if (def.rawId == liveKey) return def;
// Eğer ID ve Baraj (sov) tutuyorsa (Örn: LiveKey "184.5", Def id=18, sov=4.5)
if (liveKey.includes('.')) {
const [mainId, sov] = liveKey.split('.');
// Tamam float problemleri olabilir ama string olarak "18" == def.rawId
// Bu kısım biraz manuel mapping gerektirebilir ama HTML içindeki "name" zaten barajı içeriyor.
// HTML'deki iddaaMarketNo veya iddaaId ile LiveData'daki code eşleşebilir!
if (def.iddaaCode == liveData.code) return def; // EN GARANTİ YÖNTEM BU!
}
if (def.iddaaCode == liveData.code) return def;
}
return null;
}
// ------------------------------------------------------------------
// REVIZE EDİLMİŞ HARİTA OLUŞTURUCU (EN SAĞLAMI)
// ------------------------------------------------------------------
async function main() {
const url = `https://www.mackolik.com/ajax/iddaa/markets/soccer/all/${MATCH_ID}?template=all`;
const response = await axios.get(url, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0' } });
const $ = cheerio.load(response.data.data.html);
const settingsRaw = $('.widget-iddaa-markets').first().attr('data-settings');
if (!settingsRaw) return;
const settingsJson = JSON.parse(he.decode(settingsRaw));
const definitions = settingsJson.iddaaEventId.marketCollection;
// Haritamızı bir dizi (array) yapalım, içinde arama yapacağız.
let marketDefinitions = [];
for (const key in definitions) {
const m = definitions[key];
marketDefinitions.push({
name: m.name, // Örn: "Maç Sonucu" veya "4,5 Alt/Üst"
rawId: m.id, // Örn: 1 veya 18
iddaaCode: m.iddaaNo, // Örn: "10313" (HTML'deki code) -> LiveData'da "code" ile eşleşecek mi bakacağız.
iddaaMarketId: m.iddaaId, // Örn: 21983276 -> LiveData'da code olarak gelebilir.
sov: m.sov // Baraj değeri (4.5)
});
}
// --- LIVE DATA ÇEK ---
const liveUrl = `https://www.mackolik.com/ajax/iddaa/outcomes/soccer/all/${MATCH_ID}`;
const liveRes = await axios.get(liveUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'User-Agent': 'Mozilla/5.0' } });
const liveMarkets = liveRes.data.data.markets;
// --- EŞLEŞTİRME VE YAZDIRMA ---
console.log(`\nMAÇ: ${MATCH_ID} | DATA ANALİZİ SONUCU`);
console.log("=".repeat(70));
for (const [liveKey, liveData] of Object.entries(liveMarkets)) {
// EŞLEŞTİRME MANTIĞI:
// Live Data içindeki "code" (Örn: 50465) ile HTML'deki "iddaaId" (Örn: 55507607) veya "iddaaNo" (Örn: 18660) eşleşmeli.
// Senin attığın son örneklerde:
// HTML JSON: "iddaaId": 55507607, "iddaaNo": "18660"
// LIVE JSON: "code": "50465"
// HATA: Kodlar (Code) maç başladığında (Live) ve başlamadan önce (Pre-match) değişiyor olabilir!
// Bu durumda en güvenilir eşleşme "Market Tipi" (ID) ve "Baraj" (SOV) üzerinden olur.
let matchedDef = marketDefinitions.find(def => {
// 1. Ana ID eşleşiyor mu? (1 == 1)
if (def.rawId == liveKey) return true;
// 2. Barajlı ID kontrolü (184.5 -> id:18, sov:4.5)
if (liveKey.includes('.')) {
// Float çevirmeden string karşılaştırması riskli olabilir, dikkat.
// LiveKey "184.5"
// Def: rawId=18, sov=4.5
// 18 == 18 AND 4.5 == 4.5
if (def.rawId == Math.floor(parseFloat(liveKey)) && def.sov == parseFloat(liveKey.split('.')[1] + '.' + (liveKey.split('.')[2] || '0'))) {
// Basitçe string match daha güvenli olabilir
return def.rawId == 18 && def.sov == 4.5 && liveKey == "184.5"; // Örnek mantık
}
// Daha basit: Mackolik Live Key yapısı: {MARKET_ID}{BARAJ}
// "18" + "4.5" -> "184.5"
if (def.rawId == 18 && liveKey == `18${def.sov}`) return true;
if (def.rawId == 19 && liveKey == `19${def.sov}`) return true; // 1. Yarı Alt üst
}
return false;
});
// Eğer yukarıdaki ID mantığı tutmazsa manuel düzeltme:
// Mackolik LiveKey formatı: {ID} veya {ID}{SOV}
// Örn: Market 1 -> Key "1"
// Örn: Market 18 (Alt/Üst), Sov 4.5 -> Key "184.5"
// Hızlı çözüm için bir Map oluşturuyorum:
const name = getMarketNameFromKey(liveKey, marketDefinitions);
for (const [k, v] of Object.entries(liveData.outcomes)) {
if (v.outcome !== '-') {
console.log(`| ${name.padEnd(35)} | ${v.label.padEnd(10)} | ${v.outcome} |`);
}
}
}
}
function getMarketNameFromKey(key, definitions) {
// 1. Tam eşleşme (ID 1, 3, 11 vb.)
let exact = definitions.find(d => d.rawId == key);
if (exact) return exact.name;
// 2. Noktalı Eşleşme (184.5, 191.5 vb.)
if (key.includes('.')) {
// key: 184.5 -> id: 18, sov: 4.5
// key: 190.5 -> id: 19, sov: 0.5
// Püf nokta: String olarak sov'u ayıklamak.
// Genelde sonu .5 ile biter.
// Ama ID 18, 19, 28, 29 gibi alt/üst türleri var.
// Bu kısmı senin için basitleştiriyorum:
// HTML'deki isimleri tara, hangisinin sov değeri key ile uyuşuyorsa onu al.
for (let def of definitions) {
if (def.sov !== null) {
// Basit bir string contains kontrolü bile çoğu zaman yeter.
// Örneğin key="184.5", def.rawId=18, def.sov=4.5 -> Eşleşir.
// key="280.5", def.rawId=28, def.sov=0.5 -> Eşleşir.
// Formül: Key, Def.ID ile başlıyor mu VE Key, Def.Sov ile bitiyor mu?
if (key.startsWith(def.rawId) && key.endsWith(def.sov)) {
return def.name;
}
}
}
}
return `Bilinmeyen Market (${key})`;
}
main();