'whatsapp', 'recipient_type' => 'individual', 'to' => $phone, 'type' => 'template', 'template' => [ 'name' => $template->template, 'language' => [ 'code' => $gateway->params['language_code'] ?? 'en_US', ], ], ]; $components = self::buildComponents($template, $data); if (!empty($components)) { $payload['template']['components'] = $components; } $apiVersion = $gateway->params['api_version'] ?? 'v25.0'; $phoneNumberId = $gateway->params['phone_number_id']; $url = "https://graph.facebook.com/{$apiVersion}/{$phoneNumberId}/messages"; $response = Http::withToken($gateway->params['access_token']) ->withHeaders([ 'Content-Type' => 'application/json', ]) ->post($url, $payload); if ($response->successful()) { return $response->json(); } throw new \Exception( 'WhatsApp Cloud API Error: ' . $response->body() ); } protected static function buildComponents($template, array $data): array { $components = []; $header = self::buildHeader($template); $body = self::buildBody($template, $data); $button = self::buildButton($data['copy_text'] ?? null); if (!empty($header)) { $components[] = $header; } if (!empty($body)) { $components[] = $body; } if (!empty($button)) { $components[] = $button; } return $components; } protected static function buildBody($template, array $data): ?array { if (empty($template->variables) || !is_array($template->variables)) { return null; } $parameters = []; foreach ($template->variables as $variable) { if (in_array($variable, ['copy_text', 'expire_at'])) { continue; } if (!isset($data[$variable])) { continue; } $parameters[] = [ 'type' => 'text', 'text' => (string) $data[$variable], ]; } if (empty($parameters)) { return null; } return [ 'type' => 'body', 'parameters' => $parameters, ]; } protected static function buildHeader($template): ?array { if (empty($template?->attachment)) { return null; } $mediaType = self::mediaType($template->attachment); $media = ['link' => asset($template->attachment)]; if ($mediaType === 'document') { $media['filename'] = basename($template->attachment); } return [ 'type' => 'header', 'parameters' => [ [ 'type' => $mediaType, $mediaType => $media, ], ], ]; } protected static function buildButton(?string $copyText = null): ?array { if (!$copyText) { return null; } return [ 'type' => 'button', 'sub_type' => 'url', 'index' => 0, 'parameters' => [ [ 'type' => 'text', 'text' => $copyText, ], ], ]; } protected static function mediaType(string $attachment): string { $extension = strtolower(pathinfo($attachment, PATHINFO_EXTENSION)); if (in_array($extension, ['jpg', 'jpeg', 'png', 'webp'])) { return 'image'; } if (in_array($extension, ['mp4', '3gp'])) { return 'video'; } return 'document'; } }