Refactor SMS sending to use KavehNegar VerifyLookup templates

- Removed SmsTextResolver dependency from multiple services and controllers.
- Introduced dispatchTemplate method in SmsService to handle SMS sending with templates.
- Updated existing SMS sending logic across various services (OtpService, PreRegistrationController, ClinicInvitationService, PaymentManager, SecretaryController, RepresentationActionController) to utilize the new dispatchTemplate method.
- Enhanced SmsMessageTemplate entity to include kavenegar_template and token_map fields.
- Created migration to add new fields to the sms_message_templates table and populate them with existing data.
- Updated SeedSmsMessageTemplatesCommand to handle new template structure.
- Added documentation for the new SMS template structure and usage.
This commit is contained in:
hamed
2026-07-05 11:20:53 +03:30
parent 828e3552c0
commit 969dc9651f
17 changed files with 480 additions and 102 deletions
@@ -26,7 +26,6 @@ class NotificationMobileController extends BaseController
private readonly DoctorRepository $doctorRepo,
private readonly ClinicRepository $clinicRepo,
private readonly SmsService $smsService,
private readonly \App\Sms\Service\SmsTextResolver $smsText,
) {}
// ── Request OTP ───────────────────────────────────────────────────────────
@@ -61,13 +60,10 @@ class NotificationMobileController extends BaseController
$this->em->flush();
// ارسال SMS
$message = $this->smsText->resolve(\App\Sms\Entity\SmsLog::TAG_NOTIFICATION_MOBILE, [
'code' => $otp->getOtpCode(),
]);
$this->smsService->dispatchAsync(
$this->smsService->dispatchTemplate(
\App\Sms\Entity\SmsLog::TAG_NOTIFICATION_MOBILE,
$mobile,
$message,
tag: \App\Sms\Entity\SmsLog::TAG_NOTIFICATION_MOBILE,
['code' => $otp->getOtpCode()],
);
return $this->success([
@@ -33,7 +33,6 @@ class PreRegistrationController extends BaseController
private readonly ClinicRepository $clinicRepo,
private readonly UserPasswordHasherInterface $hasher,
private readonly SmsService $sms,
private readonly \App\Sms\Service\SmsTextResolver $smsText,
private readonly LoggerInterface $logger,
) {}
@@ -155,15 +154,14 @@ class PreRegistrationController extends BaseController
$this->em->flush();
try {
$message = $this->smsText->resolve(\App\Sms\Entity\SmsLog::TAG_PRE_REGISTRATION, [
'username' => $preReg->getMobile(),
'password' => $password,
'link' => 'https://clinic-pro.ddev.site/admin',
]);
$this->sms->dispatchAsync(
$this->sms->dispatchTemplate(
\App\Sms\Entity\SmsLog::TAG_PRE_REGISTRATION,
$preReg->getMobile(),
$message,
tag: \App\Sms\Entity\SmsLog::TAG_PRE_REGISTRATION,
[
'username' => $preReg->getMobile(),
'password' => $password,
'link' => 'https://clinic-pro.ddev.site/admin',
],
);
} catch (\Throwable $e) {
$this->logger->warning('PreRegistration SMS failed', ['uuid' => $uuid, 'error' => $e->getMessage()]);
+2 -18
View File
@@ -7,7 +7,6 @@ use App\Shared\Constant\ErrorCodes;
use App\Shared\Exception\AppException;
use App\Sms\Entity\SmsLog;
use App\Sms\Service\SmsService;
use App\Sms\Service\SmsTextResolver;
use Symfony\Component\Uid\Uuid;
use Symfony\Contracts\Cache\CacheInterface;
@@ -16,11 +15,9 @@ class OtpService
public function __construct(
private readonly CacheInterface $cache,
private readonly SmsService $sms,
private readonly SmsTextResolver $smsText,
private readonly CityRepository $cityRepo,
private readonly int $otpTtl = 1200,
private readonly string $appEnv = 'dev',
private readonly ?string $otpTemplate = null,
) {}
private function key(string $uuid): string
@@ -72,21 +69,8 @@ class OtpService
$this->cache->save($item);
if ($this->appEnv !== 'dev') {
$site = $this->resolveSiteName($domain);
$message = $this->smsText->resolve(SmsLog::TAG_OTP, ['code' => $code, 'site' => $site]);
if ($this->otpTemplate) {
// Kavenegar VerifyLookup: code has no spaces → token; site may contain spaces → token10.
$this->sms->dispatchAsync(
$mobile,
$message,
templateCode: $this->otpTemplate,
templateVars: ['token' => $code, 'token10' => $site],
tag: SmsLog::TAG_OTP,
);
} else {
$this->sms->dispatchAsync($mobile, $message, tag: SmsLog::TAG_OTP);
}
$site = $this->resolveSiteName($domain);
$this->sms->dispatchTemplate(SmsLog::TAG_OTP, $mobile, ['code' => $code, 'site' => $site]);
}
return $uuid;