Your IP : 216.73.217.78


Current Path : /home/seto/888mirror.pm/includes/
Upload File :
Current File : /home/seto/888mirror.pm/includes/openai.php

<?php
require_once __DIR__ . '/db.php';

function openai_research_brand(string $brand_name): string {
    $api_key = setting('openai_key');
    $model   = setting('openai_model') ?: 'gpt-4o';

    if (!$api_key) {
        throw new RuntimeException('OpenAI API ключ не задан.');
    }

    $prompt = "Search the web for factual information about \"{$brand_name}\" online casino. Find and summarize in English:\n"
            . "- Welcome bonus (exact percentage and amount)\n"
            . "- Free spins offer\n"
            . "- Total number of games\n"
            . "- Game providers (list the main ones)\n"
            . "- Licensing authority (exact license name and jurisdiction)\n"
            . "- Payment methods (list)\n"
            . "- Withdrawal limits (min and max)\n"
            . "- Supported currencies\n"
            . "- Notable features or USPs\n\n"
            . "Write a concise fact sheet. For fields you cannot verify, write \"Unknown\".";

    $payload = json_encode([
        'model' => $model,
        'tools' => [['type' => 'web_search_preview']],
        'input' => $prompt,
    ]);

    $ch = curl_init('https://api.openai.com/v1/responses');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_TIMEOUT        => OPENAI_TIMEOUT,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key,
        ],
    ]);

    $response = curl_exec($ch);
    $err      = curl_error($ch);
    $http     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($err) throw new RuntimeException('Ошибка соединения с OpenAI: ' . $err);

    $data = json_decode($response, true);
    if ($http !== 200) {
        $msg = $data['error']['message'] ?? $response;
        throw new RuntimeException('OpenAI API ошибка: ' . $msg);
    }

    // Responses API: output[] → type=message → content[] → type=output_text
    $text = '';
    foreach ($data['output'] ?? [] as $item) {
        if (($item['type'] ?? '') === 'message') {
            foreach ($item['content'] ?? [] as $c) {
                if (($c['type'] ?? '') === 'output_text') {
                    $text .= $c['text'];
                }
            }
        }
    }

    return trim($text) ?: 'Не удалось найти информацию о бренде.';
}

function openai_generate(string $brand_name, array $language_codes, string $context = ''): array {
    $api_key = setting('openai_key');
    $model   = setting('openai_model') ?: 'gpt-4o';

    if (!$api_key) {
        throw new RuntimeException('OpenAI API ключ не задан. Добавьте его в настройках.');
    }

    $langs_str    = implode(', ', $language_codes);
    $context_block = $context
        ? "\n\nVerified facts about this brand (use as primary source — do NOT contradict these):\n{$context}"
        : '';

    $prompt = <<<PROMPT
You are a gambling industry data expert. Generate structured data about the following casino/gambling brand.

Brand: {$brand_name}{$context_block}

Return a JSON object where each key is a language code from this list: {$langs_str}
Each language object must contain these fields (all as strings):
- bonus: welcome bonus offer (e.g. "100% up to \$500")
- free_spins: number of free spins (e.g. "100 Free Spins")
- games_count: number of games (e.g. "3000+")
- advantages: JSON array of 3-5 key advantages written in the target language. Each item must be short — 4-6 words, like a punchy label. Examples: ["5000+ слотов от топ провайдеров", "Мгновенный вывод на крипто", "Лицензия MGA и Кюрасао"]. Make them specific to this brand, not generic filler.
- license: licensing authority (e.g. "MGA, Curacao")
- payment_methods: JSON array of payment methods (e.g. ["Visa", "Mastercard", "Bitcoin"])
- payment_methods_count: total count as string (e.g. "50+")
- min_withdraw: minimum withdrawal amount (e.g. "\$20")
- max_withdraw: maximum withdrawal amount (e.g. "\$10,000/day")
- currencies: comma-separated list of supported currencies. Put the LOCAL currency of the language FIRST (e.g. for "ru" → "RUB, USD, EUR, BTC"; for "de"/"fr"/"es" → "EUR, USD, GBP, BTC"; for "tr" → "TRY, USD, EUR"; for "pl" → "PLN, EUR, USD"; for "br" → "BRL, USD, EUR"), then other major currencies, then crypto if supported.

If you don't have reliable data for a field, use an empty string "".
Return ONLY valid JSON, no markdown, no explanation.
PROMPT;

    $payload = json_encode([
        'model'       => $model,
        'messages'    => [['role' => 'user', 'content' => $prompt]],
        'temperature' => 0.3,
    ]);

    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_TIMEOUT        => OPENAI_TIMEOUT,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key,
        ],
    ]);

    $response = curl_exec($ch);
    $err      = curl_error($ch);
    $http     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($err) {
        throw new RuntimeException('Ошибка соединения с OpenAI: ' . $err);
    }

    $data = json_decode($response, true);

    if ($http !== 200) {
        $msg = $data['error']['message'] ?? $response;
        throw new RuntimeException('OpenAI API ошибка: ' . $msg);
    }

    $content = $data['choices'][0]['message']['content'] ?? '';

    // Убрать возможные markdown-обёртки ```json ... ```
    $content = preg_replace('/^```(?:json)?\s*/i', '', trim($content));
    $content = preg_replace('/\s*```$/', '', $content);

    $result = json_decode($content, true);
    if (!is_array($result)) {
        throw new RuntimeException('OpenAI вернул невалидный JSON: ' . substr($content, 0, 200));
    }

    return $result;
}

function openai_generate_landing(string $landing_name, string $geo, string $template, array $language_codes): array {
    $api_key = setting('openai_key');
    $model   = setting('openai_model') ?: 'gpt-4o';

    if (!$api_key) {
        throw new RuntimeException('OpenAI API ключ не задан. Добавьте его в настройках.');
    }

    $site_name    = setting('site_name') ?: '888mirror.pm';
    $current_year = date('Y');
    $langs_str = implode(', ', $language_codes);
    $geo_hint  = $geo ? "Target GEO/audience: {$geo}" : "Global audience";
    $layout    = str_starts_with($template, 'table-') ? 'table/rating' : (str_starts_with($template, 'row-') ? 'horizontal cards' : 'cards');

    $prompt = <<<PROMPT
You are an SEO copywriter for a casino affiliate website. Generate landing page content.

Landing name: {$landing_name}
{$geo_hint}
Layout style: {$layout}

Return a JSON object where each key is a language code from this list: {$langs_str}
Each language object must contain these fields (all as strings, written in the target language):
- h1: main heading (SEO-optimized, 40-70 chars, use year {$current_year} if including a year)
- subtitle: subtitle (1 engaging sentence)
- cta_text: call-to-action button text (2-5 words, e.g. "Get Bonus →")
- body_text: SEO body text (3-5 paragraphs separated by newline characters \\n, 200-400 words total)
- meta_title: SEO meta title (50-60 chars)
- meta_description: SEO meta description (140-160 chars, include a call to action)
- footer_text: short footer disclaimer (e.g. "© 2025 {$site_name} — 18+ | Gamble responsibly")

Return ONLY valid JSON, no markdown, no explanation.
PROMPT;

    $payload = json_encode([
        'model'       => $model,
        'messages'    => [['role' => 'user', 'content' => $prompt]],
        'temperature' => 0.4,
    ]);

    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_TIMEOUT        => OPENAI_TIMEOUT,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key,
        ],
    ]);

    $response = curl_exec($ch);
    $err      = curl_error($ch);
    $http     = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($err) {
        throw new RuntimeException('Ошибка соединения с OpenAI: ' . $err);
    }

    $data = json_decode($response, true);

    if ($http !== 200) {
        $msg = $data['error']['message'] ?? $response;
        throw new RuntimeException('OpenAI API ошибка: ' . $msg);
    }

    $content = $data['choices'][0]['message']['content'] ?? '';
    $content = preg_replace('/^```(?:json)?\s*/i', '', trim($content));
    $content = preg_replace('/\s*```$/', '', $content);

    $result = json_decode($content, true);
    if (!is_array($result)) {
        throw new RuntimeException('OpenAI вернул невалидный JSON: ' . substr($content, 0, 200));
    }

    return $result;
}

function openai_save_landing_translations(int $landing_id, array $data): void {
    $db = db();

    $check  = $db->prepare("SELECT id FROM landing_translations WHERE landing_id=? AND language_code=?");
    $insert = $db->prepare("
        INSERT INTO landing_translations
            (landing_id, language_code, h1, subtitle, cta_text, body_text, meta_title, meta_description, footer_text, generated_at)
        VALUES (?,?,?,?,?,?,?,?,?,datetime('now'))
    ");
    $update = $db->prepare("
        UPDATE landing_translations SET
            h1=?, subtitle=?, cta_text=?, body_text=?, meta_title=?, meta_description=?, footer_text=?,
            generated_at=datetime('now')
        WHERE landing_id=? AND language_code=?
    ");

    foreach ($data as $lang => $values) {
        if (!is_array($values)) continue;
        $h1    = $values['h1']               ?? '';
        $sub   = $values['subtitle']         ?? '';
        $cta   = $values['cta_text']         ?? '';
        $body  = $values['body_text']        ?? '';
        $mt    = $values['meta_title']       ?? '';
        $md    = $values['meta_description'] ?? '';
        $ft    = $values['footer_text']      ?? '';

        $check->execute([$landing_id, $lang]);
        if ($check->fetchColumn()) {
            $update->execute([$h1,$sub,$cta,$body,$mt,$md,$ft,$landing_id,$lang]);
        } else {
            $insert->execute([$landing_id,$lang,$h1,$sub,$cta,$body,$mt,$md,$ft]);
        }
    }
}

function openai_save_translations(int $brand_id, array $data): void {
    $db = db();

    $check  = $db->prepare("SELECT id FROM brand_translations WHERE brand_id = ? AND language_code = ?");
    $insert = $db->prepare("
        INSERT INTO brand_translations
            (brand_id, language_code, bonus, free_spins, games_count, advantages, license,
             payment_methods, payment_methods_count, min_withdraw, max_withdraw, currencies, generated_at)
        VALUES (?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'))
    ");
    $update = $db->prepare("
        UPDATE brand_translations SET
            bonus=?, free_spins=?, games_count=?, advantages=?, license=?,
            payment_methods=?, payment_methods_count=?, min_withdraw=?, max_withdraw=?,
            currencies=?, generated_at=datetime('now')
        WHERE brand_id=? AND language_code=?
    ");

    foreach ($data as $lang => $values) {
        if (!is_array($values)) continue;

        $adv = isset($values['advantages']) && is_array($values['advantages'])
               ? json_encode($values['advantages'], JSON_UNESCAPED_UNICODE)
               : ($values['advantages'] ?? '');
        $pm  = isset($values['payment_methods']) && is_array($values['payment_methods'])
               ? json_encode($values['payment_methods'], JSON_UNESCAPED_UNICODE)
               : ($values['payment_methods'] ?? '');

        $bonus    = $values['bonus'] ?? '';
        $spins    = $values['free_spins'] ?? '';
        $games    = $values['games_count'] ?? '';
        $license  = $values['license'] ?? '';
        $pmc      = $values['payment_methods_count'] ?? '';
        $minw     = $values['min_withdraw'] ?? '';
        $maxw     = $values['max_withdraw'] ?? '';
        $curr     = $values['currencies'] ?? '';

        $check->execute([$brand_id, $lang]);
        if ($check->fetchColumn()) {
            $update->execute([$bonus,$spins,$games,$adv,$license,$pm,$pmc,$minw,$maxw,$curr,$brand_id,$lang]);
        } else {
            $insert->execute([$brand_id,$lang,$bonus,$spins,$games,$adv,$license,$pm,$pmc,$minw,$maxw,$curr]);
        }
    }
}