Şimdi whatsapp dan aldığım resimleri OpenAI editlemesi için gönderiyorum fakat bana aynı resmi geri dönüyor. Resmi düzenlemiyor nerede yanlış yapıyorum ben acaba

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Twilio\Rest\Client;
use App\Services\OpenAIImageService;
class WhatsAppController extends Controller
{
protected $client;
protected $imageService;
protected $userPrompts = [];
public function __construct(OpenAIImageService $imageService)
{
$this->client = new Client(
env('TWILIO_SID'),
env('TWILIO_AUTH_TOKEN')
);
$this->imageService = $imageService;
}
public function receiveMessage(Request $request)
{
Log::info('WhatsApp webhook alındı:', $request->all());
$from = $request->input('From');
$body = $request->input('Body');
$numMedia = (int)$request->input('NumMedia', 0);
$userNumber = str_replace('whatsapp:', '', $from);
try {
if ($numMedia > 0) {
$mediaUrl = $request->input('MediaUrl0');
$mediaContentType = $request->input('MediaContentType0');
if (strpos($mediaContentType, 'image/') === 0) {
// Kullanıcı daha önce istekte bulunmuş mu kontrol et
if (isset($this->userPrompts[$userNumber]) && !empty($this->userPrompts[$userNumber])) {
$prompt = $this->userPrompts[$userNumber];
unset($this->userPrompts[$userNumber]); // Kullanıldığı için sil
$this->sendWhatsAppMessage(
$userNumber,
'Resminiz alındı ve AI tarafından düzenleniyor... İsteğiniz: "' . $prompt . '". Birazdan dönüş yapacağız.'
);
$this->processImageEdit($mediaUrl, $userNumber, $prompt);
} else {
$this->sendWhatsAppMessage(
$userNumber,
'Resminiz alındı. Lütfen nasıl düzenlemek istediğinizi açıklayan bir metin mesajı gönderin.'
);
// Kullanıcının resim gönderdiğini ve düzenleme komutu beklediğimizi kaydet
session(["pending_image_$userNumber" => $mediaUrl]);
}
}
} else {
// Kullanıcının bekleyen bir resmi var mı kontrol et
$pendingImage = session("pending_image_$userNumber");
if ($pendingImage) {
session()->forget("pending_image_$userNumber");
$this->sendWhatsAppMessage(
$userNumber,
'Düzenleme talebiniz alındı: "' . $body . '". Resminiz işleniyor...'
);
$this->processImageEdit($pendingImage, $userNumber, $body);
} else {
// Gelecekteki resim düzenleme isteği için bilgiyi sakla
$this->userPrompts[$userNumber] = $body;
$this->sendWhatsAppMessage(
$userNumber,
'Düzenleme talebiniz kaydedildi: "' . $body . '". Şimdi lütfen düzenlemek istediğiniz resmi gönderin.'
);
}
}
} catch (\Exception $e) {
Log::error('Webhook işleme hatası: ' . $e->getMessage());
$this->sendWhatsAppMessage(
$userNumber,
'Üzgünüz, bir hata oluştu: ' . $e->getMessage()
);
}
$response = '<?xml version="1.0" encoding="UTF-8"?><Response></Response>';
return response($response, 200)
->header('Content-Type', 'text/xml');
}
private function sendWhatsAppMessage($to, $message)
{
try {
$message = $this->client->messages->create(
"whatsapp:" . $to,
[
'from' => "whatsapp:" . env('TWILIO_WHATSAPP_NUMBER'),
'body' => $message
]
);
Log::info('WhatsApp mesajı gönderildi: ' . $message->sid);
return $message;
} catch (\Exception $e) {
Log::error('WhatsApp mesajı gönderme hatası: ' . $e->getMessage());
throw $e;
}
}
private function sendWhatsAppImage($to, $imageUrl, $caption = '')
{
try {
$message = $this->client->messages->create(
"whatsapp:" . $to,
[
'from' => "whatsapp:" . env('TWILIO_WHATSAPP_NUMBER'),
'body' => $caption,
'mediaUrl' => [$imageUrl]
]
);
Log::info('WhatsApp resim mesajı gönderildi: ' . $message->sid);
return $message;
} catch (\Exception $e) {
Log::error('WhatsApp resim gönderme hatası: ' . $e->getMessage());
throw $e;
}
}
private function processImageEdit($mediaUrl, $userNumber, $prompt)
{
try {
$jpgImage = file_get_contents($mediaUrl);
$imageResource = imagecreatefromstring($jpgImage);
if (!$imageResource) {
throw new \Exception("Görsel formatı okunamadı");
}
$imageName = time() . '.png';
$path = storage_path('app/public/uploads/' . $imageName);
if (!file_exists(storage_path('app/public/uploads'))) {
mkdir(storage_path('app/public/uploads'), 0755, true);
}
imagepng($imageResource, $path);
imagedestroy($imageResource);
try {
$editedImages = $this->imageService->editImage($path, $prompt);
if (!empty($editedImages)) {
$aiImageUrl = isset($editedImages[0]['url']) ? $editedImages[0]['url'] : null;
if (!$aiImageUrl) {
throw new \Exception('Düzenlenen resim URL\'i alınamadı');
}
Log::info('AI tarafından düzenlenen resim: ' . $aiImageUrl);
$this->sendWhatsAppImage(
$userNumber,
$aiImageUrl,
'İşte AI tarafından düzenlenen resminiz. İsteğiniz: "' . $prompt . '"'
);
} else {
throw new \Exception('AI resmi düzenlenemedi: Boş yanıt');
}
} catch (\Exception $aiError) {
Log::error('AI resim düzenleme hatası: ' . $aiError->getMessage());
$this->sendWhatsAppMessage(
$userNumber,
'Üzgünüz, AI resmi düzenlerken bir hata oluştu: ' . $aiError->getMessage()
);
}
} catch (\Exception $e) {
Log::error('Resim işleme hatası: ' . $e->getMessage());
$this->sendWhatsAppMessage(
$userNumber,
'Üzgünüz, resminiz işlenirken bir hata oluştu: ' . $e->getMessage()
);
}
}
public function handleStatus(Request $request)
{
Log::info('WhatsApp mesaj durumu:', $request->all());
$messageSid = $request->input('MessageSid');
$messageStatus = $request->input('MessageStatus');
switch($messageStatus) {
case 'delivered':
Log::info("Mesaj $messageSid alıcıya teslim edildi");
break;
case 'read':
Log::info("Mesaj $messageSid alıcı tarafından okundu");
break;
case 'failed':
Log::error("Mesaj $messageSid gönderilemedi");
break;
}
return response('OK', 200);
}
}
<?php
namespace App\Services;
use OpenAI\Laravel\Facades\OpenAI;
use Illuminate\Support\Facades\Log;
use OpenAI\Exceptions\ErrorException;
use OpenAI\Exceptions\TransporterException;
use GuzzleHttp\Exception\ConnectException;
use Illuminate\Support\Facades\Storage;
class OpenAIImageService
{
public function editImage(string $imagePath, string $prompt, string $maskPath = null)
{
try {
$cleanPrompt = $this->cleanPrompt($prompt);
Log::info('OpenAI API resim düzenleme isteği başlatılıyor', [
'prompt' => $cleanPrompt,
'imagePath' => $imagePath,
'model' => 'dall-e-2'
]);
// Resmi kare PNG formatına dönüştür (DALL-E 2 gerekliliği)
$squareImagePath = $this->convertToSquarePng($imagePath);
// Parametreleri hazırla
$params = [
'model' => 'dall-e-2',
'image' => fopen($squareImagePath, 'r'),
'prompt' => $cleanPrompt,
'n' => 1,
'size' => '1024x1024',
'response_format' => 'url'
];
// Varsa mask ekle
if ($maskPath && file_exists($maskPath)) {
// Maske de kare PNG olmalı
$squareMaskPath = $this->convertToSquarePng($maskPath);
$params['mask'] = fopen($squareMaskPath, 'r');
}
Log::info('OpenAI API parametreleri hazırlandı', [
'params' => array_keys($params)
]);
// API isteği
$response = OpenAI::images()->edit($params);
Log::info('OpenAI API resim düzenleme yanıtı alındı', [
'response_keys' => isset($response->data) ? 'data mevcut' : 'data yok',
'data_count' => isset($response->data) ? count($response->data) : 0
]);
return $response->data;
} catch (ErrorException $e) {
$errorMessage = $e->getMessage();
$errorType = $e->getErrorType();
$errorCode = $e->getCode();
Log::error('OpenAI API ErrorException', [
'message' => $errorMessage,
'type' => $errorType,
'code' => $errorCode,
'prompt' => $prompt
]);
throw new \Exception("OpenAI API hatası: {$errorType} - {$errorMessage} (Kod: {$errorCode})");
} catch (TransporterException $e) {
Log::error('OpenAI API TransporterException', [
'message' => $e->getMessage(),
'code' => $e->getCode()
]);
throw new \Exception("OpenAI API bağlantı hatası: {$e->getMessage()} (Kod: {$e->getCode()})");
} catch (ConnectException $e) {
Log::error('OpenAI API ConnectException', [
'message' => $e->getMessage(),
'code' => $e->getCode()
]);
throw new \Exception("OpenAI API'ye bağlanılamadı: {$e->getMessage()}");
} catch (\Exception $e) {
Log::error('OpenAI API hatası', [
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
]);
throw new \Exception("OpenAI API işlem hatası: {$e->getMessage()} (Kod: {$e->getCode()})");
}
}
// Görüntüyü kare PNG formatına dönüştürme (DALL-E 2 için gerekli)
private function convertToSquarePng($imagePath)
{
$imageInfo = getimagesize($imagePath);
if (!$imageInfo) {
throw new \Exception("Geçerli bir görüntü dosyası değil");
}
// Görüntünün genişlik ve yüksekliğini al
$width = $imageInfo[0];
$height = $imageInfo[1];
$type = $imageInfo[2];
// Orijinal görüntüyü yükle
switch ($type) {
case IMAGETYPE_JPEG:
$sourceImage = imagecreatefromjpeg($imagePath);
break;
case IMAGETYPE_PNG:
$sourceImage = imagecreatefrompng($imagePath);
break;
case IMAGETYPE_GIF:
$sourceImage = imagecreatefromgif($imagePath);
break;
case IMAGETYPE_WEBP:
$sourceImage = imagecreatefromwebp($imagePath);
break;
default:
throw new \Exception("Desteklenmeyen görüntü formatı");
}
// En büyük kenarı bul ve kare görüntü oluştur
$maxSide = max($width, $height);
$squareImage = imagecreatetruecolor($maxSide, $maxSide);
// Arka planı şeffaf yap (PNG için)
imagealphablending($squareImage, false);
imagesavealpha($squareImage, true);
$transparent = imagecolorallocatealpha($squareImage, 255, 255, 255, 127);
imagefilledrectangle($squareImage, 0, 0, $maxSide, $maxSide, $transparent);
// Orijinal görüntüyü merkezle
$offsetX = ($maxSide - $width) / 2;
$offsetY = ($maxSide - $height) / 2;
// Görüntüyü kare alana kopyala
imagecopy($squareImage, $sourceImage, $offsetX, $offsetY, 0, 0, $width, $height);
// Geçici dosya oluştur
$outputPath = sys_get_temp_dir() . '/' . uniqid() . '.png';
// PNG olarak kaydet
imagepng($squareImage, $outputPath);
// Temizle
imagedestroy($sourceImage);
imagedestroy($squareImage);
return $outputPath;
}
public function generateImage(string $prompt, int $count = 1, string $size = '512x512')
{
try {
$cleanPrompt = $this->cleanPrompt($prompt);
Log::info('OpenAI API isteği başlatılıyor', [
'prompt' => $cleanPrompt,
'count' => $count,
'size' => $size
]);
$response = OpenAI::images()->create([
'model' => 'dall-e-2',
'prompt' => $cleanPrompt,
'n' => $count,
'size' => $size,
'response_format' => 'url',
]);
Log::info('OpenAI API yanıtı alındı', [
'response_status' => 'success',
'data_count' => count($response->data)
]);
return $response->data;
} catch (ErrorException $e) {
$errorMessage = $e->getMessage();
$errorType = $e->getErrorType();
$errorCode = $e->getCode();
Log::error('OpenAI API ErrorException', [
'message' => $errorMessage,
'type' => $errorType,
'code' => $errorCode,
'prompt' => $prompt
]);
throw new \Exception("OpenAI API hatası: {$errorType} - {$errorMessage} (Kod: {$errorCode})");
} catch (TransporterException $e) {
Log::error('OpenAI API TransporterException', [
'message' => $e->getMessage(),
'code' => $e->getCode()
]);
throw new \Exception("OpenAI API bağlantı hatası: {$e->getMessage()} (Kod: {$e->getCode()})");
} catch (ConnectException $e) {
Log::error('OpenAI API ConnectException', [
'message' => $e->getMessage(),
'code' => $e->getCode()
]);
throw new \Exception("OpenAI API'ye bağlanılamadı: {$e->getMessage()}");
} catch (\Exception $e) {
Log::error('OpenAI API hatası', [
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
]);
throw new \Exception("OpenAI API işlem hatası: {$e->getMessage()} (Kod: {$e->getCode()})");
}
}
private function cleanPrompt(string $prompt): string
{
if (mb_strlen($prompt) > 1000) {
$prompt = mb_substr($prompt, 0, 1000);
}
$prompt = trim($prompt);
$prompt = preg_replace('/[\x00-\x1F\x7F]/', '', $prompt);
return $prompt;
}
public function validateResponse($response)
{
if (!isset($response->data) || empty($response->data)) {
throw new \Exception("API yanıtı boş veya geçersiz");
}
return true;
}
}