Hãy cùng Nam tìm hiểu về cách tích hợp tính năng gửi Email và tạo bản ghi trên Google Sheet nhé
Dự án gần đây của Nam là xây dựng Landing page và đẩy lên server Apache / PHP - môi trường Setup Hosting cơ bản, thường thì với Landing, việc sử dụng Wordpress hoặc Ladipage cũng đang đến rất nhiều tiện lợi, nhưng với bản tính Tech Nerd thì Anyway, hãy cùng xử lý mọi thứ một cách nguyên thủy nhất xem nào (Sử dụng PHP và HTML để dựng Landing cho máu)
Điều kiện tiên quyết
- Môi trường máy ảo Xampp, Laragon... tùy bạn miễn là chạy được Webserver và PHP
- Composer (Gần đây mình mới vọc thì thấy nó cũng khá tiện) không khác gì NPM cào về các file Vendor rất tiện, có thể nói là dùng cũng không thua gì thư viện của Golang
- Chatgpt nhé!
Xây dựng môi trường Frontend và Form trỏ tới hàm gửi Email và in dữ liệu lên Google Sheet
Cơ bản thì thì mình xây 1 cái Form và nó sẽ trỏ tới hàm send_email.php nằm cùng cấp với bảng dữ liệu, như hình dưới là cấu trúc ổn nha
Lập App Password cho Email để thực hiện gửi Mail
Phần này thì đã có rất nhiều hướng dẫn rồi, bạn có thể tham khảo tại bài viết này, sau khi có App Password và Email gửi đi, ta sẽ lấy nó làm cơ sở để thực hiện gửi Email cho khách hàng điền Form
Bật Google Sheet API và Đăng ký Services App trên Google Cloud Console
- Truy cập Google Cloud Console.
- Tạo một dự án mới hoặc chọn dự án hiện tại.
- Tìm kiếm và kích hoạt Google Sheets API.
- Tạo Service Account Key trong mục APIs & Services > Credentials và tải file JSON về, ta sẽ để file JSON này cùng cấp với dự án
Xây dựng hàm send_email.php với cấu trúc như sau
isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = $smtpUser;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Email người gửi và người nhận
$mail->setFrom($smtpUser, 'PJCO Fest');
$mail->addAddress($email, $name);
// Tải template email
$template = file_get_contents('email_template.html');
// Thay thế các placeholder trong template
$emailContent = str_replace([
'{{name}}',
'{{birthYear}}',
'{{phone}}',
'{{email}}',
'{{city}}'
], [
$name,
$birthYear,
$phone,
$email,
$city
], $template);
// Nội dung email
$mail->isHTML(true);
$mail->Subject = '=?UTF-8?B?' . base64_encode('Bạn nhận được 1 thông báo mới') . '?=';
$mail->Body = $emailContent;
// Gửi email
$mail->send();
echo 'Email đã được gửi thành công.';
// Cập nhật Google Sheets
$client = new Client();
$client->setApplicationName('Người đăng ký mới');
$client->setScopes(Sheets::SPREADSHEETS);
$client->setAuthConfig('kinetic-center-291115-1695aeb2a408.json'); // Đường dẫn tới file JSON
$sheetsService = new Sheets($client);
$values = [
[$name, $birthYear, $phone, $email, $city] // Dữ liệu ghi vào Sheets
];
$body = new Sheets\ValueRange(['values' => $values]);
$params = ['valueInputOption' => 'RAW'];
$sheetsService->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
echo ' Dữ liệu đã được cập nhật vào Google Sheets.';
} catch (Exception $e) {
echo "Không thể gửi email. Lỗi: {$mail->ErrorInfo}";
}
}
Nhớ khai báo đầy đủ Username và App Password nhé
Mình mất khá nhiều công Debug bản mới được tạo ra từ chatgpt, nhưng cuối cùng phát hiện ra đã bỏ quên đoạn $mail->Username ra khỏi khai báo STMP, thế là ngồi lúi cúi nửa buổi được giải quyết bằng một cái bổ sung đơn giản.
Update: Muốn sử dụng các nhà cung cấp SMTP khác?
Nam đánh giá rất cao cách triển khai hàm send_email.php kể trên bởi nó có thể dễ dàng thay thế SMTP của Google bằng các nhà cung cấp khác, ví dụ ở đây Nam sử dụng Brevo (Trả phí) thay vì Gmail SMTP để gửi đi (lúc này Nam cũng không cần phải sử dụng tới App password nữa, vì mình sẽ dùng giải pháp tới từ Brevo)
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use Google\Client;
use Google\Service\Sheets;
use Dotenv\Dotenv;
require 'vendor/autoload.php';
// Khởi tạo Dotenv và load file .env
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Lấy giá trị từ .env
$smtpBrevo = "địa chỉ SMTP của Brevo";
$smtpBrevoPassword = "passowrd App Brevo";
$smtpBrevoUser = "Địa chỉ Email gửi đi" -> Cần có xác minh tên miền từ phía Brevo cung cấp;
// ID Google Sheets và phạm vi
$spreadsheetId = '1jbZOmI1-Cr2tDAJ8Oq9GSvZWgc9_Y-ylPUyvhzQizb8'; // Thay bằng ID Google Sheets của bạn
$range = 'List-Full!A1:F1'; // Phạm vi ghi (ví dụ: Sheet1 từ cột A đến F)
// Xử lý Recaptcha
function verifyRecaptcha($token, $secretKey)
{
$url = 'https://www.google.com/recaptcha/api/siteverify';
$data = [
'secret' => $secretKey,
'response' => $token
];
// Gửi yêu cầu POST đến Google
$options = [
'http' => [
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
// Phân tích kết quả
$result = json_decode($response, true);
return $result['success'] ?? false;
}
// Hàm lấy ngày hiện tại
function getCurrentDate()
{
return date('Y-m-d H:i:s'); // Định dạng ngày tháng giờ phút giây
}
// Kiểm tra nếu form đã submit
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$recaptchaToken = $_POST['g-recaptcha-response'];
$secretKey = 'Secret key từ Google'; // Thay bằng Secret Key từ Google
if (!verifyRecaptcha($recaptchaToken, $secretKey)) {
echo 'Lỗi: Xác thực reCAPTCHA không thành công. Vui lòng thử lại.';
exit;
}
$name = htmlspecialchars($_POST['name']);
$birthYear = htmlspecialchars($_POST['birth_year']);
$phone = htmlspecialchars($_POST['phone']);
$email = htmlspecialchars($_POST['email']);
$city = htmlspecialchars($_POST['city']);
$currentDate = getCurrentDate(); // Lấy ngày hiện tại
$mail = new PHPMailer(true);
try {
// Cấu hình SMTP
$mail->isSMTP();
$mail->Host = 'smtp-relay.brevo.com';
$mail->SMTPAuth = true;
$mail->Password = $smtpBrevoPassword;
$mail->Username = $smtpBrevo;
$mail->CharSet = 'UTF-8';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Email người gửi và người nhận
$mail->setFrom($smtpBrevoUser, 'PJICO Fest');
$mail->addAddress($email, $name);
// Tải template email
$template = file_get_contents('email_template.html');
// Thay thế các placeholder trong template
$emailContent = str_replace([
'{{name}}',
'{{birthYear}}',
'{{phone}}',
'{{email}}',
'{{city}}'
], [
$name,
$birthYear,
$phone,
$email,
$city
], $template);
// Nội dung email
$mail->isHTML(true);
$mail->Subject = '=?UTF-8?B?' . base64_encode('Xác nhận đăng ký thành công vé Fanzone đại nhạc hội PJICO FEST') . '?=';
$mail->Body = $emailContent;
// Gửi email
$mail->send();
echo 'Đăng ký thành công. Vui lòng kiểm tra email xác nhận trong hòm thư.';
// Cập nhật Google Sheets
$client = new Client();
$client->setApplicationName('PJCO Fest Registration');
$client->setScopes(Sheets::SPREADSHEETS);
$client->setAuthConfig('kinetic-center-291115-1695aeb2a408.json'); // Đường dẫn tới file JSON
$sheetsService = new Sheets($client);
$values = [
[$name, $birthYear, $phone, $email, $city, $currentDate] // Dữ liệu ghi vào Sheets
];
$body = new Sheets\ValueRange(['values' => $values]);
$params = ['valueInputOption' => 'RAW'];
$sheetsService->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
echo ' Dữ liệu đã được cập nhật vào Google Sheets.';
} catch (Exception $e) {
echo "Không thể gửi email. Lỗi: {$mail->ErrorInfo}";
}
}
Lưu ý là để gửi Email qua tên miền của chúng ta thì cần 1 bước xác thực acme_challenge ở cấp tên miền với Brevo, phần này sẽ do Brevo hướng dẫn khá chi tiết đó.
Kết luận
Qua bài viết trên, hẳn bạn đã nắm được cách triển khai gửi Email qua SMTP đối với nền tảng PHP thuần (không sử dụng Plugins Wordpress), Nam rất hy vọng những ví dụ kể trên sẽ giúp được cả nhà, xin cảm ơn.