'user', 'parts' => [ ['text' => "System instruction: " . $systemPrompt], ['text' => $testMsg] ] ]; } else { $contents[] = [ 'role' => 'user', 'parts' => [['text' => $testMsg]] ]; } $payloadData = [ 'contents' => $contents, 'generationConfig' => [ 'responseModalities' => ['AUDIO'], 'speechConfig' => [ 'voiceConfig' => [ 'prebuiltVoiceConfig' => [ 'voiceName' => 'Puck' ] ] ] ] ]; if ($useSystemInstructionField) { $payloadData['systemInstruction'] = [ 'parts' => [['text' => $systemPrompt]] ]; } $payload = json_encode($payloadData); $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_TIMEOUT, 15); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { $errorData = json_decode($response, true); $errMsg = $errorData['error']['message'] ?? 'Unknown error'; echo " ❌ Failed (HTTP {$httpCode}: {$errMsg})\n"; echo " Response: " . substr($response, 0, 500) . "\n\n"; } else { $data = json_decode($response, true); $part = $data['candidates'][0]['content']['parts'][0] ?? null; if ($part && isset($part['inlineData'])) { $audioResponse = [ 'audio' => $part['inlineData']['data'], 'mimeType' => $part['inlineData']['mimeType'] ?? 'audio/mp4' ]; $successfulModel = $model; echo " ✅ SUCCESS!\n\n"; break; // Stop at first successful model } else { echo " ❌ Failed (No inlineData in response)\n"; echo " Response: " . substr($response, 0, 500) . "\n\n"; } } } if ($successfulModel && $audioResponse && !empty($audioResponse['audio'])) { echo "\n✅ [Gemini] Successfully generated voice note using model: models/{$successfulModel}\n"; echo "ℹ️ [Gemini] Audio MimeType: " . $audioResponse['mimeType'] . "\n"; echo "ℹ️ [Gemini] Audio Size: " . strlen($audioResponse['audio']) . " base64 chars\n"; // 3. Test Audio-to-Audio conversion using the Service echo "\n--- Testing Audio-to-Audio (Speech-to-Speech) via GeminiService ---\n"; $startTime = microtime(true); $audioResponse2 = GeminiService::generateAudioResponseFromAudio($apiKey, $systemPrompt, $audioResponse['audio'], $audioResponse['mimeType'], 'Puck'); $elapsedTime2 = round(microtime(true) - $startTime, 2); if ($audioResponse2 && !empty($audioResponse2['audio'])) { echo "✅ [Gemini] Successfully generated Audio-to-Audio response in {$elapsedTime2} seconds!\n"; echo "ℹ️ [Gemini] Audio MimeType: " . $audioResponse2['mimeType'] . "\n"; echo "ℹ️ [Gemini] Audio Size: " . strlen($audioResponse2['audio']) . " base64 chars\n"; } else { echo "❌ [Gemini] Audio-to-Audio generation failed.\n"; } } else { echo "\n❌ [Gemini] All model trials for audio response generation failed.\n"; } // 4. Check Node.js WhatsApp Gateway Status echo "\n--- Checking Node.js Gateway Status ---\n"; $gatewayUrl = rtrim(getenv('WHATSAPP_GATEWAY_URL') ?: 'http://localhost:3722', '/'); echo "Gateway URL: {$gatewayUrl}\n"; $ch = curl_init($gatewayUrl . '/health'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $healthResponse = curl_exec($ch); $healthHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $healthError = curl_error($ch); curl_close($ch); if ($healthHttpCode === 200) { echo "✅ [Gateway] Gateway is ONLINE and healthy.\n"; echo "ℹ️ [Gateway] Response: {$healthResponse}\n"; } else { echo "❌ [Gateway] Gateway is OFFLINE or returning error. HTTP Code: {$healthHttpCode}. Error: {$healthError}\n"; } echo "\n=== Diagnostics Complete ===\n";