| Current Path : /home/seto/888mirror.pm/includes/ |
| 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]);
}
}
}