sound-effects/webhook/webhook_processor.php
DJP 4c734e51d4 Initial commit: Sound Effects App
Added complete sound effects application with multiple versions (V1, V2),
configuration files, webhook functionality, and associated assets.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-14 16:04:47 -04:00

344 lines
No EOL
12 KiB
PHP

<?php
/**
* Reusable Webhook Processor for AI Image Generation Applications
*
* This class provides a standardized way to integrate webhook functionality
* into any application that generates AI images. Simply include this file
* and use the WebhookProcessor class to send generation data to external
* automation systems.
*
* Usage:
* require_once 'webhook_processor.php';
* $processor = new WebhookProcessor(['webhook_url' => 'https://your-hook.com']);
* $processor->sendGenerationData($data);
*/
class WebhookProcessor {
private $config;
private $defaultWebhookUrl = 'https://hook.us1.make.celonis.com/sbhcpk0athbdbxxmgijxc5sbwtjsg33h';
/**
* Initialize webhook processor with configuration
*
* @param array $config Configuration options:
* - webhook_url: Target webhook URL (optional)
* - client: Default client name (optional)
* - user_email: Default user email (optional)
* - deliverable_number: Default deliverable number (optional)
* - timeout: cURL timeout in seconds (default: 30)
* - verify_ssl: Whether to verify SSL certificates (default: true)
*/
public function __construct($config = []) {
$this->config = array_merge([
'webhook_url' => $this->defaultWebhookUrl,
'client' => 'Auto-Approved',
'user_email' => 'ai-comp-setup@oliver.agency',
'deliverable_number' => '00000',
'timeout' => 30,
'verify_ssl' => true
], $config);
}
/**
* Send AI generation data to webhook
*
* @param array $data Generation data:
* - prompt: The user's text prompt (required)
* - generation_type: Type of AI generation (DALL-E 3, Leonardo, etc.)
* - settings: Generation settings array
* - image_data: Raw image binary data OR image URL OR file path
* - image_url: Alternative to image_data - URL to download image
* - image_file: Alternative to image_data - file path to read image
* - client: Client name (overrides default)
* - user_email: User email (overrides default)
* - deliverable_number: Deliverable number (overrides default)
* - additional_data: Extra data to include in webhook
* @param string $webhookUrl Optional webhook URL override
* @return bool True on success, false on failure
*/
public function sendGenerationData($data, $webhookUrl = null) {
$webhookUrl = $webhookUrl ?: $this->config['webhook_url'];
// Build standardized webhook data
$webhookData = $this->buildWebhookData($data);
// Send the webhook
return $this->sendWebhook($webhookData, $webhookUrl);
}
/**
* Build standardized webhook data structure
*
* @param array $data Input data
* @return array Standardized webhook data
*/
private function buildWebhookData($data) {
$webhookData = [
'client' => $data['client'] ?? $this->config['client'],
'deliverableNumber' => $data['deliverable_number'] ?? $this->config['deliverable_number'],
'userEmail' => $data['user_email'] ?? $this->config['user_email'],
'generationType' => $data['generation_type'] ?? 'Unknown',
'settings' => $data['settings'] ?? [],
'timestamp' => time(),
];
// Add prompt to settings if provided
if (isset($data['prompt'])) {
$webhookData['settings']['prompt'] = $data['prompt'];
}
// Process image data if provided
if (isset($data['image_data'])) {
$normalized = $this->normalizeImageData($data['image_data']);
if ($normalized) {
$webhookData['imageFile'] = $normalized['base64'];
}
} elseif (isset($data['image_url'])) {
$normalized = $this->processImageUrl($data['image_url']);
if ($normalized) {
$webhookData['imageFile'] = $normalized['base64'];
}
} elseif (isset($data['image_file'])) {
$normalized = $this->processImageFile($data['image_file']);
if ($normalized) {
$webhookData['imageFile'] = $normalized['base64'];
}
}
// Add any additional data
if (isset($data['additional_data']) && is_array($data['additional_data'])) {
$webhookData = array_merge($webhookData, $data['additional_data']);
}
return $webhookData;
}
/**
* Normalize image data to standard format
*
* @param mixed $imageData Raw binary data, base64 string, or data URI
* @param string $targetFormat Target format (jpeg, png)
* @param int $quality JPEG quality (1-100)
* @return array|null Normalized image data or null on failure
*/
private function normalizeImageData($imageData, $targetFormat = 'jpeg', $quality = 90) {
// If already a data URI, extract the data
if (is_string($imageData) && strpos($imageData, 'data:') === 0) {
$parts = explode(',', $imageData, 2);
if (count($parts) === 2) {
$imageData = base64_decode($parts[1]);
}
}
// If base64 encoded string, decode it
elseif (is_string($imageData) && base64_decode($imageData, true) !== false) {
$imageData = base64_decode($imageData);
}
// Create image resource from binary data
$image = @imagecreatefromstring($imageData);
if ($image === false) {
// Try to detect mime type and return original
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->buffer($imageData);
return [
'mime_type' => $mimeType,
'base64' => 'data:' . $mimeType . ';base64,' . base64_encode($imageData),
'data' => $imageData
];
}
// Convert to target format
ob_start();
if ($targetFormat === 'jpeg' || $targetFormat === 'jpg') {
imagejpeg($image, null, $quality);
$mimeType = 'image/jpeg';
} elseif ($targetFormat === 'png') {
imagepng($image);
$mimeType = 'image/png';
} else {
imagejpeg($image, null, $quality);
$mimeType = 'image/jpeg';
}
$normalizedData = ob_get_contents();
ob_end_clean();
imagedestroy($image);
return [
'mime_type' => $mimeType,
'base64' => 'data:' . $mimeType . ';base64,' . base64_encode($normalizedData),
'data' => $normalizedData
];
}
/**
* Process image from URL
*
* @param string $imageUrl URL to download
* @param string $targetFormat Target format
* @param int $quality JPEG quality
* @return array|null Normalized image data or null on failure
*/
private function processImageUrl($imageUrl, $targetFormat = 'jpeg', $quality = 90) {
$context = stream_context_create([
'http' => [
'timeout' => $this->config['timeout'],
'user_agent' => 'WebhookProcessor/1.0'
]
]);
$imageData = @file_get_contents($imageUrl, false, $context);
if ($imageData === false) {
return null;
}
return $this->normalizeImageData($imageData, $targetFormat, $quality);
}
/**
* Process image from file path
*
* @param string $filePath Path to image file
* @param string $targetFormat Target format
* @param int $quality JPEG quality
* @return array|null Normalized image data or null on failure
*/
private function processImageFile($filePath, $targetFormat = 'jpeg', $quality = 90) {
if (!file_exists($filePath)) {
return null;
}
$imageData = file_get_contents($filePath);
if ($imageData === false) {
return null;
}
return $this->normalizeImageData($imageData, $targetFormat, $quality);
}
/**
* Send webhook using cURL
*
* @param array $data Data to send
* @param string $webhookUrl Target URL
* @return bool True on success, false on failure
*/
private function sendWebhook($data, $webhookUrl) {
$ch = curl_init($webhookUrl);
curl_setopt_array($ch, [
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => $this->config['verify_ssl'],
CURLOPT_TIMEOUT => $this->config['timeout'],
CURLOPT_USERAGENT => 'WebhookProcessor/1.0'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// Log errors if debugging is enabled
if ($httpCode < 200 || $httpCode >= 300 || !empty($curlError)) {
error_log("Webhook failed: HTTP {$httpCode}, Error: {$curlError}, URL: {$webhookUrl}");
return false;
}
return true;
}
/**
* Test webhook endpoint connectivity
*
* @param string $webhookUrl Optional URL to test (uses default if not provided)
* @return array Test results with status, http_code, and response_time
*/
public function testWebhook($webhookUrl = null) {
$webhookUrl = $webhookUrl ?: $this->config['webhook_url'];
$testData = [
'test' => true,
'timestamp' => time(),
'client' => 'WebhookProcessor Test',
'generationType' => 'Test'
];
$startTime = microtime(true);
$ch = curl_init($webhookUrl);
curl_setopt_array($ch, [
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => json_encode($testData),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => $this->config['verify_ssl'],
CURLOPT_TIMEOUT => $this->config['timeout'],
CURLOPT_USERAGENT => 'WebhookProcessor/1.0 Test'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
$responseTime = round((microtime(true) - $startTime) * 1000, 2);
curl_close($ch);
return [
'success' => ($httpCode >= 200 && $httpCode < 300 && empty($curlError)),
'http_code' => $httpCode,
'response_time_ms' => $responseTime,
'error' => $curlError,
'response' => $response
];
}
/**
* Get current configuration
*
* @return array Current configuration (sensitive values masked)
*/
public function getConfig() {
$config = $this->config;
// Mask sensitive webhook URL
if (isset($config['webhook_url'])) {
$config['webhook_url'] = substr($config['webhook_url'], 0, 30) . '...';
}
return $config;
}
/**
* Update configuration
*
* @param array $newConfig New configuration values
* @return void
*/
public function updateConfig($newConfig) {
$this->config = array_merge($this->config, $newConfig);
}
}
/**
* Convenience function for quick webhook sending
*
* @param array $data Generation data
* @param string $webhookUrl Webhook URL
* @param array $config Optional processor configuration
* @return bool Success status
*/
function sendAIWebhook($data, $webhookUrl = null, $config = []) {
if ($webhookUrl) {
$config['webhook_url'] = $webhookUrl;
}
$processor = new WebhookProcessor($config);
return $processor->sendGenerationData($data);
}