313 lines
9.7 KiB
PHP
313 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Category;
|
|
use App\Services\WhatsAppBusinessService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class ChatController extends Controller
|
|
{
|
|
/**
|
|
* @var \App\Services\WhatsAppBusinessService
|
|
*/
|
|
private $whatsAppBusinessService;
|
|
|
|
/**
|
|
* @param \App\Services\WhatsAppBusinessService $whatsAppBusinessService
|
|
*/
|
|
public function __construct(WhatsAppBusinessService $whatsAppBusinessService)
|
|
{
|
|
$this->whatsAppBusinessService = $whatsAppBusinessService;
|
|
}
|
|
|
|
/**
|
|
* Get WhatsApp link for admin showroom
|
|
*
|
|
* @param int $categoryId - The category/car ID (optional)
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function getAdminWhatsAppLink($categoryId = null)
|
|
{
|
|
try {
|
|
// Get admin phone number from centralized service configuration.
|
|
$phoneNumber = config('services.whatsapp.admin_recipient');
|
|
$adminName = config('services.whatsapp.admin_name', 'Showroom');
|
|
|
|
if (!$phoneNumber) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Nomor WhatsApp admin tidak dikonfigurasi',
|
|
], 422);
|
|
}
|
|
|
|
$carName = null;
|
|
$carImageUrl = null;
|
|
$carDetailUrl = null;
|
|
$category = null;
|
|
if ($categoryId) {
|
|
$category = Category::find($categoryId);
|
|
if ($category) {
|
|
$carName = $category->name;
|
|
$carImageUrl = $this->getCarImageUrl($category);
|
|
$carDetailUrl = $this->getCarDetailUrl($category);
|
|
}
|
|
}
|
|
|
|
// Format phone number
|
|
$formattedPhone = $this->formatPhoneNumber($phoneNumber);
|
|
|
|
// Create WhatsApp message
|
|
$message = $this->buildWhatsAppMessage($category, $carImageUrl, $carDetailUrl);
|
|
$encodedMessage = urlencode($message);
|
|
|
|
// WhatsApp Web link format
|
|
$whatsappLink = "https://wa.me/{$formattedPhone}?text={$encodedMessage}";
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Link WhatsApp berhasil dibuat',
|
|
'data' => [
|
|
'admin_name' => $adminName,
|
|
'phone_number' => $phoneNumber,
|
|
'whatsapp_link' => $whatsappLink,
|
|
'car_name' => $carName,
|
|
'car_image_url' => $carImageUrl,
|
|
'car_detail_url' => $carDetailUrl,
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Direct redirect to WhatsApp admin.
|
|
*
|
|
* @param int $categoryId - The category/car ID (optional)
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function redirectAdminWhatsApp($categoryId = null)
|
|
{
|
|
try {
|
|
$phoneNumber = config('services.whatsapp.admin_recipient');
|
|
|
|
if (!$phoneNumber) {
|
|
return redirect()->back()->with('error', 'Nomor WhatsApp admin tidak dikonfigurasi');
|
|
}
|
|
|
|
// Format phone number
|
|
$formattedPhone = $this->formatPhoneNumber($phoneNumber);
|
|
|
|
$carImageUrl = null;
|
|
$carDetailUrl = null;
|
|
$category = null;
|
|
if ($categoryId) {
|
|
$category = Category::find($categoryId);
|
|
if ($category) {
|
|
$carImageUrl = $this->getCarImageUrl($category);
|
|
$carDetailUrl = $this->getCarDetailUrl($category);
|
|
$this->sendBusinessImageNotification($category, auth()->user());
|
|
}
|
|
}
|
|
|
|
// Create message
|
|
$message = $this->buildWhatsAppMessage($category, $carImageUrl, $carDetailUrl);
|
|
$encodedMessage = urlencode($message);
|
|
|
|
// Redirect to WhatsApp, but keep catalog/detail URLs based on this local app host.
|
|
$whatsappLink = "https://wa.me/{$formattedPhone}?text={$encodedMessage}";
|
|
return redirect($whatsappLink);
|
|
|
|
} catch (\Exception $e) {
|
|
return redirect()->back()->with('error', 'Terjadi kesalahan saat membuka WhatsApp');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send a WhatsApp Business notification with the car image to admin.
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @param int $categoryId
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function notifyAdminWithCarImage(Request $request, $categoryId)
|
|
{
|
|
try {
|
|
$category = Category::find($categoryId);
|
|
|
|
if (!$category) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Mobil tidak ditemukan.',
|
|
], 404);
|
|
}
|
|
|
|
$result = $this->whatsAppBusinessService->sendCarNotificationToAdmin(
|
|
$category,
|
|
$request->user()
|
|
);
|
|
|
|
return response()->json($result, $result['success'] ? 200 : 422);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Terjadi kesalahan saat mengirim notifikasi ke admin.',
|
|
'error' => $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format phone number to WhatsApp format
|
|
* Converts various formats to 62xxxxxxxxxx
|
|
*
|
|
* @param string $phoneNumber
|
|
* @return string
|
|
*/
|
|
private function formatPhoneNumber($phoneNumber)
|
|
{
|
|
// Remove all non-numeric characters
|
|
$phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
|
|
|
|
// Handle Indonesian phone numbers
|
|
// 081234567890 -> 6281234567890
|
|
if (strlen($phoneNumber) == 10 && substr($phoneNumber, 0, 1) == '8') {
|
|
$phoneNumber = '62' . $phoneNumber;
|
|
}
|
|
// 08xxxxxxxxxx -> 62xxxxxxxxxx
|
|
elseif (strlen($phoneNumber) >= 11 && substr($phoneNumber, 0, 2) == '08') {
|
|
$phoneNumber = '62' . substr($phoneNumber, 1);
|
|
}
|
|
// If doesn't start with 62, prepend it
|
|
elseif (substr($phoneNumber, 0, 2) != '62') {
|
|
$phoneNumber = '62' . $phoneNumber;
|
|
}
|
|
|
|
return $phoneNumber;
|
|
}
|
|
|
|
/**
|
|
* Build WhatsApp message with optional car image link.
|
|
*
|
|
* @param \App\Models\Category|null $category
|
|
* @param string|null $carImageUrl
|
|
* @param string|null $carDetailUrl
|
|
* @return string
|
|
*/
|
|
private function buildWhatsAppMessage(?Category $category = null, $carImageUrl = null, $carDetailUrl = null)
|
|
{
|
|
if (!$category) {
|
|
return "Halo admin, saya tertarik dengan salah satu mobil bekas yang ada di website. Apakah masih tersedia?";
|
|
}
|
|
|
|
$lines = [
|
|
'Halo admin, saya tertarik dengan mobil katalog ini.',
|
|
'',
|
|
'Nama mobil: ' . $category->name,
|
|
'Harga: Rp ' . number_format((float) $category->price, 0, ',', '.'),
|
|
'Tahun: ' . ($category->year ?: '-'),
|
|
];
|
|
|
|
if ($carImageUrl) {
|
|
$lines[] = 'Foto katalog: ' . $carImageUrl;
|
|
}
|
|
|
|
if ($carDetailUrl) {
|
|
$lines[] = 'Link detail: ' . $carDetailUrl;
|
|
}
|
|
|
|
$lines[] = '';
|
|
$lines[] = 'Apakah mobil ini masih tersedia?';
|
|
|
|
return implode("\n", $lines);
|
|
}
|
|
|
|
/**
|
|
* Get absolute public URL for the car image if available.
|
|
*
|
|
* @param \App\Models\Category $category
|
|
* @return string|null
|
|
*/
|
|
private function getCarImageUrl(Category $category)
|
|
{
|
|
if (!$category->image) {
|
|
return null;
|
|
}
|
|
|
|
return $this->publicUrl(Storage::disk('public')->url($category->image), $this->getClickableBaseUrl());
|
|
}
|
|
|
|
/**
|
|
* Get absolute detail page URL for the car.
|
|
*
|
|
* @param \App\Models\Category $category
|
|
* @return string
|
|
*/
|
|
private function getCarDetailUrl(Category $category)
|
|
{
|
|
return $this->publicUrl('/mobil-bekas/' . $category->id, $this->getClickableBaseUrl());
|
|
}
|
|
|
|
/**
|
|
* Build an absolute URL from the current local app host.
|
|
*
|
|
* @param string $path
|
|
* @return string
|
|
*/
|
|
private function publicUrl($path, $baseUrl = null)
|
|
{
|
|
if (filter_var($path, FILTER_VALIDATE_URL)) {
|
|
return $path;
|
|
}
|
|
|
|
$baseUrl = $baseUrl ?: url('/');
|
|
|
|
return rtrim($baseUrl, '/') . '/' . ltrim($path, '/');
|
|
}
|
|
|
|
/**
|
|
* Prefer a public local tunnel URL for WhatsApp, because WhatsApp often
|
|
* does not turn 127.0.0.1/localhost links into clickable links.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getClickableBaseUrl()
|
|
{
|
|
$requestUrl = rtrim(request()->getSchemeAndHttpHost(), '/');
|
|
|
|
if ($requestUrl) {
|
|
return $requestUrl;
|
|
}
|
|
|
|
$configuredUrl = rtrim((string) config('app.url'), '/');
|
|
|
|
if ($configuredUrl && ! preg_match('/^https?:\/\/(127\.0\.0\.1|localhost)(:\d+)?$/i', $configuredUrl)) {
|
|
return $configuredUrl;
|
|
}
|
|
|
|
return url('/');
|
|
}
|
|
|
|
/**
|
|
* Send selected catalog image through WhatsApp Business Cloud API.
|
|
* The direct WhatsApp redirect still works if the API send fails.
|
|
*/
|
|
private function sendBusinessImageNotification(Category $category, $customer = null)
|
|
{
|
|
try {
|
|
if ($this->whatsAppBusinessService->isConfigured()) {
|
|
$this->whatsAppBusinessService->sendCarNotificationToAdmin($category, $customer);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
}
|
|
}
|
|
}
|
|
|