Files
lelong/app/Services/WhatsAppCloudService.php
T

132 lines
3.8 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class WhatsAppCloudService
{
public function isEnabled()
{
return (bool) config('whatsapp.whatsapp_cloud_enabled')
&& !empty(config('whatsapp.token'))
&& !empty(config('whatsapp.phone_number_id'));
}
/**
* Normalize Malaysian phone numbers to digits with country code (e.g. 60123456789).
*/
public function normalizePhone($phone)
{
if ($phone === null || $phone === '') {
return null;
}
$digits = preg_replace('/\D+/', '', (string) $phone);
if ($digits === '') {
return null;
}
if (strpos($digits, '60') === 0) {
return $digits;
}
if (strpos($digits, '0') === 0) {
return '6' . $digits;
}
return '60' . ltrim($digits, '0');
}
/**
* In non-production, always send to ADMIN_PHONE_NUMBER.
*/
public function resolveRecipient($phone)
{
if (config('app.env') !== 'production') {
return $this->normalizePhone(config('app.admin_phone_number'));
}
return $this->normalizePhone($phone);
}
/**
* Send an approved WhatsApp Cloud API template message.
*
* @param string $to E.164-ish digits without +
* @param string $templateName
* @param array<int, string> $bodyParams Ordered body variables {{1}}, {{2}}, ...
* @return array{ok:bool,status:int,body:mixed}
*/
public function sendTemplate($to, $templateName, array $bodyParams = [], $languageCode = null)
{
if (!$this->isEnabled()) {
Log::warning('WhatsApp Cloud API skipped: not enabled or missing credentials.');
return ['ok' => false, 'status' => 0, 'body' => 'disabled'];
}
$to = $this->normalizePhone($to);
if (!$to) {
return ['ok' => false, 'status' => 0, 'body' => 'invalid_phone'];
}
$languageCode = $languageCode ?: config('whatsapp.template_lang', 'en_US');
$version = config('whatsapp.api_version', 'v25.0');
$phoneNumberId = config('whatsapp.phone_number_id');
$url = "https://graph.facebook.com/{$version}/{$phoneNumberId}/messages";
$template = [
'name' => $templateName,
'language' => ['code' => $languageCode],
];
if (!empty($bodyParams)) {
$template['components'] = [[
'type' => 'body',
'parameters' => array_map(function ($value) {
return [
'type' => 'text',
'text' => (string) $value,
];
}, array_values($bodyParams)),
]];
}
$payload = [
'messaging_product' => 'whatsapp',
'to' => $to,
'type' => 'template',
'template' => $template,
];
$response = Http::withToken(config('whatsapp.token'))
->acceptJson()
->asJson()
->post($url, $payload);
$result = [
'ok' => $response->successful(),
'status' => $response->status(),
'body' => $response->json() ?? $response->body(),
];
if (!$result['ok']) {
Log::error('WhatsApp Cloud API template send failed', [
'to' => $to,
'template' => $templateName,
'status' => $result['status'],
'body' => $result['body'],
]);
} else {
Log::info('WhatsApp Cloud API template sent', [
'to' => $to,
'template' => $templateName,
'message_id' => data_get($result['body'], 'messages.0.id'),
]);
}
return $result;
}
}