Deploy Ladill Events / deploy (push) Successful in 48s
Mirror Care: suite platform keys count as ready for attendee email/SMS; Account Messaging is primary, product Bird/SMS keys are advanced. SmsService now prefers channel=suite before customer API keys.
103 lines
2.9 KiB
PHP
103 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Billing;
|
|
|
|
use App\Services\Messaging\CustomerSmsClient;
|
|
use App\Services\Messaging\MessagingCredentialsService;
|
|
|
|
/**
|
|
* Attendee SMS: prefer platform suite messaging (zero-config), fall back to
|
|
* product SMS API keys when suite is unavailable.
|
|
*/
|
|
class SmsService
|
|
{
|
|
private ?string $lastError = null;
|
|
|
|
public function __construct(
|
|
private readonly CustomerSmsClient $customer,
|
|
private readonly MessagingCredentialsService $credentials,
|
|
private readonly PlatformSmsClient $platformSms,
|
|
) {}
|
|
|
|
public function lastError(): ?string
|
|
{
|
|
return $this->lastError;
|
|
}
|
|
|
|
public function isConfiguredForOwner(string $ownerPublicId): bool
|
|
{
|
|
if ($this->platformSms->isConfigured()) {
|
|
return true;
|
|
}
|
|
|
|
return $this->credentials->forOwner($ownerPublicId)->hasValidSms();
|
|
}
|
|
|
|
public function send(string $ownerPublicId, string $to, string $message): bool
|
|
{
|
|
$this->lastError = null;
|
|
|
|
$phone = preg_replace('/\D+/', '', $to);
|
|
if (strlen($phone) < 9) {
|
|
$this->lastError = 'Enter a valid phone number.';
|
|
|
|
return false;
|
|
}
|
|
|
|
if (strlen($phone) === 9) {
|
|
$phone = '233'.$phone;
|
|
} elseif (str_starts_with($phone, '0')) {
|
|
$phone = '233'.substr($phone, 1);
|
|
}
|
|
|
|
$credential = $this->credentials->forOwner($ownerPublicId);
|
|
|
|
if ($this->platformSms->isConfigured()) {
|
|
$sender = $credential->sms_sender_id ?: null;
|
|
$sent = $this->platformSms->send(
|
|
$ownerPublicId,
|
|
$phone,
|
|
$message,
|
|
$sender ? (string) $sender : null,
|
|
);
|
|
if ($sent) {
|
|
return true;
|
|
}
|
|
|
|
$suiteError = $this->platformSms->lastError();
|
|
if ($this->tryCustomerSms($credential, $phone, $message)) {
|
|
return true;
|
|
}
|
|
|
|
$this->lastError = $suiteError ?: $this->lastError;
|
|
|
|
return false;
|
|
}
|
|
|
|
return $this->tryCustomerSms($credential, $phone, $message);
|
|
}
|
|
|
|
private function tryCustomerSms(object $credential, string $phone, string $message): bool
|
|
{
|
|
if (! $credential->hasValidSms()) {
|
|
$this->lastError = 'SMS is not available (platform SMS key missing and no product SMS credentials).';
|
|
|
|
return false;
|
|
}
|
|
|
|
$apiKey = $credential->smsApiKey();
|
|
if (! $apiKey) {
|
|
$this->lastError = 'SMS credentials could not be decrypted. Reconnect SMS under Advanced keys.';
|
|
|
|
return false;
|
|
}
|
|
|
|
$sent = $this->customer->send($apiKey, $phone, $message, (string) $credential->sms_sender_id);
|
|
if (! $sent) {
|
|
$this->lastError = $this->customer->lastError() ?: 'The SMS could not be sent.';
|
|
}
|
|
|
|
return $sent;
|
|
}
|
|
}
|