آموزش
ارسال ایمیل در PHP
ارسال با cURL (API) یا PHPMailer (SMTP) در پروژهی PHP بدون فریمورک.
آخرین ویرایش: ۲۱ آبان ۱۴۰۵
اگر فریمورک ندارید یا با Laravel کار نمیکنید، این دو راه را دارید. پیش از شروع، دامنهتان را تأیید و یک کلید بسازید. کلید را در متغیر محیطی بگذارید (getenv('SENDAK_KEY')) و در مخزن کد نگذارید.
با API (cURL)
<?php
function sendak_send(string $idempotencyKey, array $to, string $subject, string $text, array $tags = []): array
{
$payload = json_encode([
'from' => 'hello@shop.ir',
'to' => $to,
'subject' => $subject,
'text' => $text,
'tags' => $tags,
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
for ($attempt = 0; $attempt < 4; $attempt++) {
$ch = curl_init('https://api.sendak.ir/v1/emails');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.getenv('SENDAK_KEY'),
'Content-Type: application/json',
'Idempotency-Key: '.$idempotencyKey,
],
]);
$body = curl_exec($ch);
$status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($body !== false && $status >= 200 && $status < 300) {
return json_decode($body, true, 512, JSON_THROW_ON_ERROR)['data'];
}
// Only a network failure, 429 and 5xx are worth another try; the key makes it safe.
if ($body !== false && $status !== 429 && $status < 500) {
throw new RuntimeException("Sendak refused the message: {$body}");
}
sleep(2 ** $attempt);
}
throw new RuntimeException('Sendak did not accept the message after 4 tries');
}
$result = sendak_send('receipt-1201', ['ali@gmail.com'], 'رسید سفارش ۱۲۰۱', 'سفارش شما ثبت شد.');
echo $result[0]['id'], ' ', $result[0]['status']; // ... queued$idempotencyKey را برای هر ایمیل منطقی ثابت بگیرید؛ نه برای هر تلاش. توضیح بیشتر. کدهای خطا: خطاها و سقفها.
با SMTP (PHPMailer)
composer require phpmailer/phpmailer<?php
require __DIR__.'/vendor/autoload.php';
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.sendak.ir';
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true;
$mail->Username = getenv('SENDAK_USER');
$mail->Password = getenv('SENDAK_KEY');
$mail->Timeout = 20;
$mail->CharSet = 'UTF-8';
$mail->setFrom('hello@shop.ir', 'فروشگاه');
$mail->addAddress('ali@gmail.com');
$mail->Subject = 'اولین ایمیل';
$mail->Body = 'سلام از سندک';
$mail->send();
} catch (Exception $e) {
error_log('Sendak SMTP: '.$mail->ErrorInfo);
}ENCRYPTION_STARTTLSروی پورت ۵۸۷.ENCRYPTION_SMTPS(پورت ۴۶۵) پشتیبانی نمیشود.CharSet = 'UTF-8'را فراموش نکنید، وگرنه فارسی خراب میشود.
نکته: SMTP کلید یکتایی درخواست ندارد. برای ایمیلهایی که ارسال تکراریشان ضرر دارد (کد تأیید، بازیابی رمز)، API را بردارید.
بررسی وبهوک
<?php
$raw = file_get_contents('php://input'); // the raw body
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_SENDAK_SIGNATURE'] ?? ''), $parts);
$t = (int) ($parts['t'] ?? 0);
$expected = hash_hmac('sha256', $t.'.'.$raw, getenv('SENDAK_WEBHOOK_SECRET'));
if ($t === 0 || abs(time() - $t) > 300 || ! hash_equals($expected, (string) ($parts['v1'] ?? ''))) {
http_response_code(401);
exit;
}
$event = json_decode($raw, true);
// Put the event on your own queue and answer fast.
http_response_code(200);جزئیات رویدادها: وبهوک.