Teren-app/app/Services/Sms/SmsService.php
Simon Pocrnjič 930ac83604 SMS service
2025-10-24 21:39:10 +02:00

109 lines
3.5 KiB
PHP

<?php
namespace App\Services\Sms;
use App\Models\SmsLog;
use App\Models\SmsProfile;
use App\Models\SmsSender;
use App\Models\SmsTemplate;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class SmsService
{
public function __construct(
protected SmsClient $client,
) {}
/**
* Send a raw text message.
*/
public function sendRaw(SmsProfile $profile, string $to, string $content, ?SmsSender $sender = null, ?string $countryCode = null, bool $deliveryReport = false, ?string $clientReference = null): SmsLog
{
return DB::transaction(function () use ($profile, $to, $content, $sender, $countryCode, $deliveryReport, $clientReference): SmsLog {
$log = new SmsLog([
'uuid' => (string) Str::uuid(),
'profile_id' => $profile->id,
'to_number' => /*$to*/'',
'sender' => $sender?->sname,
'message' => $content,
'status' => 'queued',
'queued_at' => now(),
]);
$log->save();
$result = $this->client->send($profile, new SmsMessage(
to: $to,
content: $content,
sender: $sender?->sname,
senderPhone: /*$sender?->phone_number*/'',
countryCode: $countryCode,
deliveryReport: $deliveryReport,
clientReference: $clientReference,
));
if ($result->status === 'sent') {
$log->status = 'sent';
$log->sent_at = now();
} else {
$log->status = 'failed';
$log->failed_at = now();
}
$log->provider_message_id = $result->providerMessageId;
$log->cost = $result->cost;
$log->currency = $result->currency;
$log->meta = $result->meta;
$log->save();
return $log;
});
}
/**
* Render an SMS from template and send.
*/
public function sendFromTemplate(SmsTemplate $template, string $to, array $variables = [], ?SmsProfile $profile = null, ?SmsSender $sender = null, ?string $countryCode = null, bool $deliveryReport = false, ?string $clientReference = null): SmsLog
{
$profile = $profile ?: $template->defaultProfile;
if (! $profile) {
throw new \InvalidArgumentException('SMS profile is required to send a message.');
}
$sender = $sender ?: $template->defaultSender;
$content = $this->renderContent($template->content, $variables);
$log = $this->sendRaw($profile, $to, $content, $sender, $countryCode, $deliveryReport, $clientReference);
$log->template_id = $template->id;
$log->save();
return $log;
}
protected function renderContent(string $content, array $vars): string
{
// Simple token replacement: {token}
return preg_replace_callback('/\{([a-zA-Z0-9_\.]+)\}/', function ($m) use ($vars) {
$key = $m[1];
return array_key_exists($key, $vars) ? (string) $vars[$key] : $m[0];
}, $content);
}
/**
* Get current credit balance from provider.
*/
public function getCreditBalance(SmsProfile $profile): string
{
return $this->client->getCreditBalance($profile);
}
/**
* Get price quote(s) from provider.
* Returns array of strings as provided by the API.
*/
public function getPriceQuotes(SmsProfile $profile): array
{
return $this->client->getPriceQuotes($profile);
}
}