update coba resend
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
16ca1eead7
commit
ca8a8c6c15
19
.env.example
19
.env.example
|
|
@ -47,15 +47,18 @@ REDIS_HOST=127.0.0.1
|
|||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=smtp.gmail.com
|
||||
MAIL_PORT=587
|
||||
MAIL_ENCRYPTION=tls
|
||||
MAIL_USERNAME=rimasazkya@gmail.com
|
||||
MAIL_PASSWORD="uamw iegn gjtg dkuw"
|
||||
MAIL_FROM_ADDRESS=SiJentik@noreply.com
|
||||
# MAIL_MAILER=smtp
|
||||
# MAIL_HOST=smtp.gmail.com
|
||||
# MAIL_PORT=587
|
||||
# MAIL_ENCRYPTION=tls
|
||||
# MAIL_USERNAME=rimasazkya@gmail.com
|
||||
# MAIL_PASSWORD="uamw iegn gjtg dkuw"
|
||||
# MAIL_FROM_ADDRESS=SiJentik@noreply.com
|
||||
# MAIL_FROM_NAME="${APP_NAME}"
|
||||
MAIL_FROM_NAME="SiJentik"
|
||||
# MAIL_FROM_NAME="SiJentik"
|
||||
RESEND_API_KEY=re_TSzu3Bt8_F8akQaw1DeNWvnbvUpJs2XLk
|
||||
MAIL_MAILER=resend_curl
|
||||
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
use Illuminate\Http\Request;
|
||||
use App\Mail\OtpMail;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class OtpController extends Controller
|
||||
|
|
@ -33,7 +32,6 @@ public function sendOtp(Request $request)
|
|||
Log::info("OTP DB: $otp");
|
||||
|
||||
try {
|
||||
set_time_limit(120);
|
||||
Mail::to($user->email)->send(new OtpMail($otp));
|
||||
} catch (\Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
|
@ -79,4 +77,4 @@ public function verifyOtp(Request $request)
|
|||
|
||||
return response()->json(['message' => 'OTP valid'], 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ public function __construct($otp)
|
|||
public function build()
|
||||
{
|
||||
return $this
|
||||
->from(env('MAIL_FROM_ADDRESS', 'rifaulardiyanto@gmail.com'))
|
||||
->subject('Kode OTP Anda')
|
||||
->view('emails.otp')
|
||||
->with(['otp' => $this->otp]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail\Transport;
|
||||
|
||||
use App\Services\ResendEmailService;
|
||||
use Symfony\Component\Mailer\Exception\TransportException;
|
||||
use Symfony\Component\Mailer\SentMessage;
|
||||
use Symfony\Component\Mailer\Transport\AbstractTransport;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
class ResendCurlTransport extends AbstractTransport
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ResendEmailService $service,
|
||||
private readonly string $defaultFromAddress,
|
||||
private readonly ?string $defaultFromName = null,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'resend_curl';
|
||||
}
|
||||
|
||||
protected function doSend(SentMessage $message): void
|
||||
{
|
||||
$originalMessage = $message->getOriginalMessage();
|
||||
|
||||
if (! $originalMessage instanceof Email) {
|
||||
throw new TransportException('Resend transport hanya mendukung Symfony Email.');
|
||||
}
|
||||
|
||||
$fromAddresses = $originalMessage->getFrom();
|
||||
$from = $fromAddresses !== []
|
||||
? $this->stringifyAddresses([$fromAddresses[0]])[0]
|
||||
: $this->formatFrom($this->defaultFromAddress, $this->defaultFromName);
|
||||
|
||||
$to = $this->stringifyAddresses($originalMessage->getTo());
|
||||
|
||||
if ($to === []) {
|
||||
throw new TransportException('Penerima email kosong.');
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'from' => $from,
|
||||
'to' => count($to) === 1 ? $to[0] : $to,
|
||||
'subject' => $originalMessage->getSubject() ?? '',
|
||||
];
|
||||
|
||||
$htmlBody = $this->normalizeBody($originalMessage->getHtmlBody());
|
||||
$textBody = $this->normalizeBody($originalMessage->getTextBody());
|
||||
|
||||
if ($htmlBody !== null) {
|
||||
$payload['html'] = $htmlBody;
|
||||
}
|
||||
|
||||
if ($textBody !== null) {
|
||||
$payload['text'] = $textBody;
|
||||
}
|
||||
|
||||
$response = $this->service->send($payload);
|
||||
|
||||
if (isset($response['id']) && is_string($response['id'])) {
|
||||
$message->setMessageId($response['id']);
|
||||
}
|
||||
|
||||
$message->appendDebug(json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: '');
|
||||
}
|
||||
|
||||
private function formatFrom(string $address, ?string $name): string
|
||||
{
|
||||
return $name ? sprintf('%s <%s>', $name, $address) : $address;
|
||||
}
|
||||
|
||||
private function normalizeBody(mixed $body): ?string
|
||||
{
|
||||
if ($body === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_resource($body)) {
|
||||
$body = stream_get_contents($body);
|
||||
}
|
||||
|
||||
if (! is_string($body)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$body = trim($body);
|
||||
|
||||
return $body === '' ? null : $body;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Mail\Transport\ResendCurlTransport;
|
||||
use App\Services\ResendEmailService;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
|
|
@ -19,6 +22,12 @@ public function register(): void
|
|||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
Mail::extend('resend_curl', function (array $config = []) {
|
||||
return new ResendCurlTransport(
|
||||
app(ResendEmailService::class),
|
||||
$config['from']['address'] ?? config('mail.from.address'),
|
||||
$config['from']['name'] ?? config('mail.from.name')
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ResendEmailService
|
||||
{
|
||||
private string $endpoint = 'https://api.resend.com/emails';
|
||||
|
||||
public function send(array $payload): array
|
||||
{
|
||||
$apiKey = config('services.resend.key');
|
||||
|
||||
if (! $apiKey) {
|
||||
throw new RuntimeException('RESEND_API_KEY belum diatur.');
|
||||
}
|
||||
|
||||
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
if ($body === false) {
|
||||
throw new RuntimeException('Gagal menyiapkan payload email untuk Resend.');
|
||||
}
|
||||
|
||||
$ch = curl_init($this->endpoint);
|
||||
|
||||
if ($ch === false) {
|
||||
throw new RuntimeException('Gagal inisialisasi cURL.');
|
||||
}
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Authorization: Bearer '.$apiKey,
|
||||
'Content-Type: application/json',
|
||||
],
|
||||
CURLOPT_POSTFIELDS => $body,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($response === false) {
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
throw new RuntimeException('Resend request gagal: '.$error);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
if ($statusCode < 200 || $statusCode >= 300) {
|
||||
$message = is_array($decoded) && isset($decoded['message'])
|
||||
? $decoded['message']
|
||||
: $response;
|
||||
|
||||
throw new RuntimeException('Resend API error: '.$message);
|
||||
}
|
||||
|
||||
return is_array($decoded) ? $decoded : ['raw' => $response];
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
"php": "^8.2",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/sanctum": "^4.3",
|
||||
"laravel/tinker": "^2.10.1"
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"resend/resend-php": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ad91ab9bde70e3576f2b64dd11542bc4",
|
||||
"content-hash": "94cb2ce06c9e2860c6251ecd8f0072c3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
|
@ -3357,6 +3357,63 @@
|
|||
},
|
||||
"time": "2025-12-14T04:43:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "resend/resend-php",
|
||||
"version": "v1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/resend/resend-php.git",
|
||||
"reference": "87d29d98271a0ab1c09cdbee102daa2f9b3419db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/resend/resend-php/zipball/87d29d98271a0ab1c09cdbee102daa2f9b3419db",
|
||||
"reference": "87d29d98271a0ab1c09cdbee102daa2f9b3419db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"php": "^8.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.13",
|
||||
"mockery/mockery": "^1.6",
|
||||
"pestphp/pest": "^1.0|^2.0|^3.0|^4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Resend.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Resend\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Resend and contributors",
|
||||
"homepage": "https://github.com/resend/resend-php/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Resend PHP library.",
|
||||
"homepage": "https://resend.com/",
|
||||
"keywords": [
|
||||
"api",
|
||||
"client",
|
||||
"php",
|
||||
"resend",
|
||||
"sdk"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/resend/resend-php/issues",
|
||||
"source": "https://github.com/resend/resend-php/tree/v1.3.0"
|
||||
},
|
||||
"time": "2026-04-11T10:48:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.4.0",
|
||||
|
|
@ -8456,5 +8513,5 @@
|
|||
"php": "^8.2"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
|
||||
*/
|
||||
|
||||
'default' => env('MAIL_MAILER', 'log'),
|
||||
'default' => env('MAIL_MAILER', 'resend_curl'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -65,6 +65,10 @@
|
|||
'transport' => 'resend',
|
||||
],
|
||||
|
||||
'resend_curl' => [
|
||||
'transport' => 'resend_curl',
|
||||
],
|
||||
|
||||
'sendmail' => [
|
||||
'transport' => 'sendmail',
|
||||
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
|
||||
|
|
|
|||
Loading…
Reference in New Issue