175 lines
5.4 KiB
PHP
175 lines
5.4 KiB
PHP
<?php
|
||
|
||
namespace App\Jobs;
|
||
|
||
use App\Models\EskizToken;
|
||
use Illuminate\Bus\Queueable;
|
||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||
use Illuminate\Foundation\Bus\Dispatchable;
|
||
use Illuminate\Queue\InteractsWithQueue;
|
||
use Illuminate\Queue\SerializesModels;
|
||
use Illuminate\Support\Facades\Log;
|
||
|
||
class SendSmsJob implements ShouldQueue
|
||
{
|
||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||
|
||
protected string $phoneNumber;
|
||
protected int $code;
|
||
|
||
public function __construct(string $phoneNumber, int $code)
|
||
{
|
||
$this->phoneNumber = $phoneNumber;
|
||
$this->code = $code;
|
||
}
|
||
|
||
public function handle(): void
|
||
{
|
||
$phoneNumber = $this->normalizePhoneNumber($this->phoneNumber);
|
||
|
||
// Bazadagi tokenni olish
|
||
$token = $this->getTokenFromDb();
|
||
|
||
// Token yo'q yoki expired bo'lsa yangilash
|
||
if (!$token) {
|
||
$token = $this->refreshToken();
|
||
if (!$token) {
|
||
Log::error('Eskiz token olish imkonsiz', ['phone' => $phoneNumber]);
|
||
return;
|
||
}
|
||
}
|
||
|
||
$postData = [
|
||
'mobile_phone' => $phoneNumber,
|
||
'message' => "DELGO hisobiga kirish uchun kod: {$this->code} Ushbu kodni ulashmang! #WBcz5ARFKcp",
|
||
// 'message' => "DELGO hisobiga kirish uchun kod: {$this->code} Ushbu kodni ulashmang! #WBcz5ARFKcp",
|
||
'from' => "4546"
|
||
];
|
||
|
||
$response = $this->sendSmsRequest($token, $postData, $phoneNumber);
|
||
|
||
// Token eskirgan bo‘lsa qayta olish
|
||
if ($response['http_code'] === 401) {
|
||
Log::warning("Eskiz token muddati tugagan, yangidan olinmoqda...");
|
||
|
||
$token = $this->refreshToken();
|
||
if ($token) {
|
||
$this->sendSmsRequest($token, $postData, $phoneNumber);
|
||
}
|
||
}
|
||
}
|
||
|
||
private function sendSmsRequest(string $token, array $postData, string $phoneNumber): array
|
||
{
|
||
$curl = curl_init();
|
||
curl_setopt_array($curl, [
|
||
CURLOPT_URL => "https://notify.eskiz.uz/api/message/sms/send",
|
||
CURLOPT_RETURNTRANSFER => true,
|
||
CURLOPT_POST => true,
|
||
CURLOPT_POSTFIELDS => http_build_query($postData),
|
||
CURLOPT_HTTPHEADER => [
|
||
"Authorization: Bearer $token",
|
||
"Content-Type: application/x-www-form-urlencoded"
|
||
],
|
||
]);
|
||
|
||
$response = curl_exec($curl);
|
||
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||
$err = curl_error($curl);
|
||
curl_close($curl);
|
||
|
||
if ($err) {
|
||
Log::error("Eskiz SMS cURL Error: " . $err, [
|
||
'phone' => $phoneNumber,
|
||
'http_code' => $httpCode
|
||
]);
|
||
return ['http_code' => $httpCode];
|
||
}
|
||
|
||
Log::debug("Eskiz SMS Response", [
|
||
'phone' => $phoneNumber,
|
||
'http_code' => $httpCode,
|
||
'response' => $response
|
||
]);
|
||
|
||
return ['http_code' => $httpCode, 'body' => $response];
|
||
}
|
||
|
||
private function normalizePhoneNumber(string $phoneNumber): string
|
||
{
|
||
$phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);
|
||
|
||
if (strlen($phoneNumber) === 9 && in_array(substr($phoneNumber, 0, 2), [
|
||
'33', '77', '88', '90', '91', '93', '94', '95', '97', '98', '99'
|
||
])) {
|
||
$phoneNumber = '998' . $phoneNumber;
|
||
} elseif (str_starts_with($phoneNumber, '+998')) {
|
||
$phoneNumber = substr($phoneNumber, 1);
|
||
}
|
||
|
||
return $phoneNumber;
|
||
}
|
||
|
||
private function getTokenFromDb(): ?string
|
||
{
|
||
$record = EskizToken::latest()->first();
|
||
|
||
if (!$record) return null;
|
||
|
||
// Token muddati tugagan bo'lsa
|
||
if ($record->expires_at && now()->greaterThan($record->expires_at)) {
|
||
return null;
|
||
}
|
||
|
||
return $record->token;
|
||
}
|
||
|
||
private function refreshToken(): ?string
|
||
{
|
||
$email = config('services.eskiz.email');
|
||
$password = config('services.eskiz.password');
|
||
|
||
$postData = ['email' => $email, 'password' => $password];
|
||
|
||
$curl = curl_init();
|
||
curl_setopt_array($curl, [
|
||
CURLOPT_URL => "https://notify.eskiz.uz/api/auth/login",
|
||
CURLOPT_RETURNTRANSFER => true,
|
||
CURLOPT_POST => true,
|
||
CURLOPT_POSTFIELDS => http_build_query($postData),
|
||
CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"],
|
||
]);
|
||
|
||
$response = curl_exec($curl);
|
||
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||
$err = curl_error($curl);
|
||
curl_close($curl);
|
||
|
||
if ($err) {
|
||
Log::error("Eskiz Auth Error: " . $err, ['http_code' => $httpCode]);
|
||
return null;
|
||
}
|
||
|
||
$data = json_decode($response, true);
|
||
|
||
if (isset($data['message'], $data['data']['token']) && $data['message'] === 'token_generated') {
|
||
$token = $data['data']['token'];
|
||
$expiresAt = now()->addHour(); // Token 1 soatga amal qiladi
|
||
|
||
// Tokenni bazaga saqlash (update yoki create)
|
||
EskizToken::updateOrCreate(
|
||
['id' => 1], // har doim 1-row ishlatiladi
|
||
[
|
||
'token' => $token,
|
||
'expires_at' => $expiresAt
|
||
]
|
||
);
|
||
|
||
return $token;
|
||
}
|
||
|
||
Log::error("Eskiz Auth Response Invalid", ['response' => $response]);
|
||
return null;
|
||
}
|
||
}
|