ai_categorize.php

6.59 KB
12/09/2025 06:16
PHP
ai_categorize.php
<?php
// ai_categorize.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// Configuration
// อ่านค่า API key จาก environment variable เพื่อความปลอดภัย
$GOOGLE_AI_API_KEY = getenv('GOOGLE_AI_API_KEY') ?: 'GOOGLE_AI_API_KEY'; // แทนที่ด้วย API Key ของคุณ หรือตั้ง environment variable
$GOOGLE_AI_API_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent';

// Simple logger to file for debugging (make sure webserver can write to this path)
/**
 * @param $msg
 */
function ai_log($msg)
{
    $logfile = '/tmp/ai_categorize.log';
    $time = date('Y-m-d H:i:s');
    @file_put_contents($logfile, "[$time] ".$msg.PHP_EOL, FILE_APPEND | LOCK_EX);
}

try {
    // Check if request method is POST
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(405);
        echo json_encode(['success' => false, 'error' => 'Only POST allowed']);
        exit;
    }

    // Get JSON input
    $json = file_get_contents('php://input');
    ai_log('Incoming request body: '.substr($json, 0, 2000));
    $data = json_decode($json, true);

    if (!$data || !isset($data['prompt'])) {
        http_response_code(400);
        echo json_encode(['success' => false, 'error' => 'Invalid JSON data or missing prompt']);
        exit;
    }

    $prompt = $data['prompt'];

    // Prepare data for Google AI Studio API
    $postData = [
        'contents' => [
            [
                'parts' => [
                    [
                        'text' => $prompt.' Please respond with valid JSON format only, no additional text.'
                    ]
                ]
            ]
        ],
        'generationConfig' => [
            'temperature' => 0.1,
            'topK' => 1,
            'topP' => 1,
            'maxOutputTokens' => 1024,
            'stopSequences' => []
        ],
        'safetySettings' => [
            [
                'category' => 'HARM_CATEGORY_HARASSMENT',
                'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
            ],
            [
                'category' => 'HARM_CATEGORY_HATE_SPEECH',
                'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
            ],
            [
                'category' => 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
                'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
            ],
            [
                'category' => 'HARM_CATEGORY_DANGEROUS_CONTENT',
                'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
            ]
        ]
    ];

    // Initialize cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $GOOGLE_AI_API_URL.'?key='.$GOOGLE_AI_API_KEY);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    // Execute request
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlErrno = curl_errno($ch);
    $curlError = curl_error($ch);
    $curlInfo = curl_getinfo($ch);
    curl_close($ch);

    if ($curlErrno) {
        ai_log('cURL error: '.$curlError.' (errno '.$curlErrno.')');
        http_response_code(502);
        echo json_encode(['success' => false, 'error' => 'cURL error communicating with AI service', 'details' => $curlError]);
        exit;
    }

    ai_log('AI API HTTP code: '.$httpCode.' response snippet: '.substr($response, 0, 2000));

    if ($httpCode !== 200) {
        ai_log('Upstream API returned HTTP '.$httpCode.'. Raw response: '.substr($response, 0, 2000));
        http_response_code(502);
        echo json_encode(['success' => false, 'error' => 'Upstream API error', 'http_code' => $httpCode, 'raw_response' => $response]);
        exit;
    }

    // Decode upstream JSON
    $responseData = json_decode($response, true);

    if (!$responseData) {
        ai_log('Failed to json_decode API response');
        http_response_code(502);
        echo json_encode(['success' => false, 'error' => 'Invalid JSON from AI service', 'raw_response' => $response]);
        exit;
    }

    // Try known response shapes (keep flexible)
    $generatedText = null;
    if (isset($responseData['candidates'][0]['content']['parts'][0]['text'])) {
        $generatedText = $responseData['candidates'][0]['content']['parts'][0]['text'];
    } elseif (isset($responseData['output'][0]['content'][0]['text'])) {
        $generatedText = $responseData['output'][0]['content'][0]['text'];
    } elseif (isset($responseData['result'])) {
        // some responses might embed text differently
        $generatedText = is_string($responseData['result']) ? $responseData['result'] : json_encode($responseData['result']);
    }

    if (!$generatedText) {
        ai_log('Unexpected API response shape: '.substr(json_encode($responseData), 0, 2000));
        http_response_code(502);
        echo json_encode(['success' => false, 'error' => 'Unexpected API response format', 'raw_response' => $response]);
        exit;
    }

    // Clean up the response - remove markdown code blocks if present
    $generatedText = preg_replace('/```json\s*/', '', $generatedText);
    $generatedText = preg_replace('/```\s*$/', '', $generatedText);
    $generatedText = trim($generatedText);

    // Parse the JSON response from AI
    $categories = json_decode($generatedText, true);

    if (!$categories) {
        // If JSON parsing fails, try to extract JSON object/array from the response
        preg_match('/\{[\s\S]*\}/', $generatedText, $matches);
        if ($matches) {
            $categories = json_decode($matches[0], true);
        }
    }

    if (!$categories) {
        ai_log('Failed to parse AI JSON. Generated text: '.substr($generatedText, 0, 2000));
        http_response_code(502);
        echo json_encode(['success' => false, 'error' => 'Failed to parse AI response as JSON', 'raw_response' => $generatedText]);
        exit;
    }

    // Return successful response
    echo json_encode([
        'success' => true,
        'categories' => $categories,
        'raw_response' => $generatedText
    ]);

} catch (Exception $e) {
    // Return error response
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => $e->getMessage()
    ]);
}