Chào các bạn, mình là Hảo, Web developer đang làm việc tại công ty OneTech Asia. Các dự án gần đây mình tham gia có phần Sendmail trong Laravel sử dụng dịch vụ SES của Amazon mà mình thấy khá hay và muốn chia sẻ với các bạn. Hãy cùng tìm hiểu nhé:
1. Dịch vụ SES là gì?
SES (Simple Email Service) là một dịch vụ gửi mail được Amazon cung cấp, nhằm tiết kiệm chi phí, linh hoạt và dễ dàng thay đổi quy mô, cho phép nhà phát triển gửi email từ bên trong ứng dụng bất kỳ.
Các ưu điểm khi sử dụng dịch vụ SES:
- Gửi mail số lượng lớn phù hợp với nhu cầu của doanh nghiệp.
- Tốc độ gửi mail nhanh, server phân bố rộng trên toàn cầu.
- Tiết kiêm chi phí (1$/1000 email).
- Dễ dàng mở rộng quy mô.
- Dễ dàng kết hợp với các dịch vụ khác trong hệ sinh thái Amazon như: Cloudwatch, Simple Notification Service (SNS).
2. Gửi mail với Laravel và SES
Cấu hình trên AWS-SES
Trước tiên, bạn cần có tài khoản AWS để có thể sử dụng dịch vụ SES. Trong phạm vi bài này tôi không đề cập cách tạo tài khoản, các bạn có thể tham khảo thêm tại:
- https://beginaws.awsstudygroup.com/vi/1-account-setup/1-create-new-aws-account/
- https://cuongquach.com/aws-dang-ky-tai-khoan-aws-free-tier-mien-phi.html
Khi đã có tài khoản hãy đăng nhập vào dashboard quản trị của Amazon tại đây.
Tiếp theo hãy chọn phân vùng phù hợp.
Lưu ý: hiện tại SES chỉ được Amazon cung cấp ở 3 phân vùng: N.Virginia , Oregon và Ireland. Ở các phân vùng khác không sử dụng được.
Tiếp tục nhé, bạn cần tạo một SMTP Credential
- Hãy vào SES Services => Account dashboard => Create SMTP credentials
Sau đó bạn sẽ được chuyển đến màn hình tạo IAM, nhiệm vụ lúc này chỉ cần click vào nút create trên màn hình để tạo IAM thôi.
Khi đó, bạn sẽ được cấp SMTP Username và SMTP Password, hãy lưu lại hai thông tin này để có thể dùng trong ứng dụng của bạn nhé! Nhấn “Download Credentials” cho chắc luôn nha, vì chỉ cấp một lần thôi đấy!
Hãy quay lại màn hình dashboard để lấy thêm thông tin host nhé!
- Hãy vào SES Services => Account dashboard
Như vậy là đã đủ thông tin cho ứng dụng của bạn kết nối vào rồi đấy!
Mà khoan, có một lưu ý bạn cần biết: mặc định khi bạn tạo SES của bạn sẽ nằm trong Sandbox, tức là bạn không thể gửi mail ra bên ngoài cho bất kỳ email nào, điều này SES muốn bạn trong quá trình develop không bị gửi nhầm cho một email nào đó, khá hay đúng không? Vậy làm sao để gửi được mail?
Có 2 cách để bạn có thể gửi được mail:
+ Cách 1: Yêu cầu AWS mở Sandbox cho bạn, điều này bạn cần request cũng như nêu lý do để Amazon đồng ý mở Sandbox cho bạn. Tất nhiên điều này chỉ khi nào release ứng dụng của bạn thì mới phải làm cách này.
+ Cách 2: Thêm email/domain vào để xác nhận với Amazon, email/domain đó là của tôi và tôi muốn gửi đến nó.
Cách thêm email như sau:
- Hãy vào SES Services => Verified Identities => Create Identity
Ở đây tôi đã verify nhiều email, nếu bạn chưa verify thì nội dung trong bảng sẽ không có nhé!
Tiếp thôi, bạn hãy chọn Email address, nhập thông tin email và nhấn Create Identity
Khi đó, một email gửi đến hộp mail để xác nhận email trên. Nếu bạn quay lại màn hình Verified Identities sẽ thấy email của bạn đang ở trạng thái Verification pending.
Lúc này khi mở mail bạn sẽ thấy một mail từ Amazon.
Hãy mở mail và click vào link đính kèm trong nội dung để xác nhận nhé!
Khi xác nhận thành công, bạn sẽ nhận được màn hình này.
Nếu bạn quay lại màn hình Verified Identities sẽ thấy email của bạn đang ở trạng thái Verified.
Như vậy đã thêm mail vào được rồi, lúc này bạn có thể gửi mail cho người này bất cứ lúc nào. Tuy nhiên lưu ý mỗi ngày bạn sẽ có 200 email miễn phí để gửi test thôi nhé, khi nào mở Sandbox thì giới hạn sẽ là 50.000 emails/ ngày.
Tiếp theo là gì nhỉ? Chắc chắn là test xem gửi email đến email đó được chưa đúng không?
Click checkbox mail và chọn Send test email nhé!
Bạn sẽ được chuyển sang màn hình input sendmail:
- Chọn Formatted
- Scenario hãy chọn Custom
- Custom recipient hãy nhập email đã verify. Vì ở đây chỉ có 1 email được verify nên khi gửi mail là email sẽ tự gửi cho chính email đó.
- Nhập subject và body tùy ý để test sendmail
- Cuối cùng nhấn nút Send test email
Bạn sẽ nhận được màn hình trông như thế này:
Hãy vào hộp mail, bạn đã nhận được mail rồi đúng không? Easy nhỉ?
Cấu hình sendmail và gửi email trong Laravel
Ở bước trên bạn đã có host, username, password và email verify. Hãy thay thế vào code bên dưới, sau đó bỏ vào file .env nhé! (from_name đặt tùy bạn nhé)
1. MAIL_DRIVER=smtp
2. MAIL_HOST=host
3. MAIL_PORT=587
4. MAIL_USERNAME=username
5. MAIL_PASSWORD=password
6. MAIL_ENCRYPTION=tls
7. MAIL_FROM_ADDRESS=email_verify
8. MAIL_FROM_NAME=from_name
Vào routes/web.php để tạo thêm route
1. Route::get('/test-sendmail', 'SendmailController@send');
Tiếp theo tạo controller và phương thức send
1. php artisan make:controller SendmailController
1. <?php
2.
3. namespace App\Http\Controllers\Frontend;
4.
5. use App\Http\Controllers\Controller;
6. use Illuminate\Http\Request;
7.
8. class SendmailController extends Controller
9. {
10. public function send() {
11. $subject = "Test sendmail Laravel";
12. $email = "tronghao@gmail.com";
13. $mailer['from'] = env('MAIL_FROM_ADDRESS');
14. \Mail::raw('Test content', function($message) use ($email, $subject, $mailer) {
15. $message->from($mailer['from']);
16. $message->to($email)->subject($subject);
17. });
18.
19. echo "Send mail successfull";
20. }
21. }
Tiếp theo start serve lên bằng lệnh php artisan serve. Sau đó chạy đường dẫn 127.0.0.1:8000/test-sendmail
Khi đó bạn sẽ nhận được màn hình như sau.
Kiểm tra thư của bạn sẽ nhận được một email gửi từ ứng dụng Laravel của bạn.
Như vậy bạn đã kết nối và gửi được mail trong Laravel sử dụng dịch vụ SES của Amazon, tuy nhiên trong thực tế email cần đưa vào hàng đợi để giảm thời gian chờ khi gửi với số lượng email lớn nhé!
3. Tracking mail SES dễ dàng
Để tạo tracking mail, trước tiên bạn hãy tạo Configuration sets.
- Hãy vào SES Services => Configuration sets => Create set
Sau đó, nhập tên configuration set và nhấn Create set.
Như vậy là bạn đã tạo configuration set thành công.
Tiếp theo hãy nhấn vào tên của configuration set vừa tạo, vào tab Event destinations => chọn Add destination.
Check vào Opens và nhấn Next.
Chọn Amazon SNS và đặt tên Distionation
Nhấn Create SNS topic
Sau khi tạo xong, chọn topic vừa tạo và nhấn next
Chọn Add destination ở màn hình tiếp theo.
Tiếp tục nhé, vào SNS service (Simple Notification Service) bằng cách search trên thanh tìm kiếm, chọn Topics và nhấn vào tên của Topics vừa tạo lúc nãy.
Chọn Create subscription
Tiếp theo hãy làm các bước sau:
- Chọn Protocol tương ứng, ở đây tôi chọn là HTTPS.
- Nhập Endpoint chính là đường dẫn bạn sẽ đăng ký với Amazon rằng khi có sự kiện mở mail hãy báo cho tôi qua endpoint này.
- Nhấn Create subscription.
Hãy quay lại SNS service (Simple Notification Service) => chọn Topics và nhấn vào tên của Topics bạn sẽ thấy một subscription đang ở trạng thái Pending confirmation. Lúc này bạn cần xác nhận Endpoint đó là của bạn bằng cách check chọn vào subscription và nhấn Request confirmation.
Ở đây tôi không đề cập đến việc tạo một endpoint route trong Laravel, vì nó tương tự như mục 2.2 nên phần này tôi không đi chi tiết.
Trong function xử lý tracking của bạn hãy thêm vào đoạn mã này.
1. /**
2. * Tracking mail open from response SNS
3. */
4. public function trackingMailOpen(Request $request)
5. {
6. try {
7. $data = $request->json()->all();
8. if ($request->json('Type') == 'SubscriptionConfirmation') {
9. Log::info($data);
10. }
11. }
12. catch (\Exception $e) {
13. return $this->jsonCatchException($e->getMessage());
14. }
15. }
Đoạn mã này sẽ log ra cho bạn response để Confirm subscription, dữ liệu log được lưu trong thư mục storage/logs của Laravel. Trong response bạn sẽ có dạng sau:
1. array (
2. 'Type' => 'SubscriptionConfirmation',
3. 'MessageId' => 'xxx',
4. 'Token' => 'xxx',
5. 'TopicArn' => 'xxx',
6. 'Message' => 'xxx',
7. 'SubscribeURL' => 'xxx',
8. 'Timestamp' => '2022-11-17T16:01:23.001Z',
9. 'SignatureVersion' => '1',
10. 'Signature' => 'xxx',
11. 'SigningCertURL' => 'https://xxx',
12. )
Hãy copy value của SubscribeURL và làm tiếp các bước bên dưới để Confirm subscription.
Sau khi có SubscribeURL hãy check chọn subscription cần xác nhận và chọn Confirm subscription
Nhập url copy từ response vào và nhấn Confirm subscription
Khi đó trạng thái sẽ chuyển thành Confirmed.
Như vậy là đã xong, khi có sự kiện mở mail, Amazon sẽ gửi request đến endpoint mà bạn đã đăng ký.
Chúng ta cùng thêm đoạn code sau vào hàm xử lý tracking mail lúc nãy nhé!
1. /**
2. * Tracking mail open from response SNS
3. */
4. public function trackingMailOpen(Request $request)
5. {
6. try {
7. $data = $request->json()->all();
8. if ($request->json('Type') == 'SubscriptionConfirmation') {
9. Log::info($data);
10. }
11.
12. if ($request->json('Type') == 'Notification') {
13. $message = $request->json('Message');
14. $message = json_decode($message, true);
15.
16. switch (isset($message['eventType']) ? $message['eventType'] : null) {
17. case 'Open':
18. // handle tracking open mail here
19. break;
20. default:
21. // Do Nothing
22. break;
23. }
24. }
25. }
26. catch (\Exception $e) {
27. return $this->jsonCatchException($e->getMessage());
28. }
29. }
Bạn có thể viết logic xử lý tracking mở mail của bạn ở dòng 18.
Amazon trả về rất nhiều thông tin như email, userAgent, ipAddress, timestamp,… Tất cả dữ liệu sẽ nằm trong biến $message với properties là open ($message[‘open’]) nhé!
Cuối cùng, hãy thêm vào lúc gửi mail header có configuration set của bạn. Thay value của X-SES-CONFIGURATION-SET thành tên bạn đã đặt lúc tạo nhé!
\Mail::raw('Test content', function($message) use ($email, $subject, $mailer) {
$message->getHeaders()->addTextHeader('X-SES-CONFIGURATION-SET', 'SendEmail');
$message->from($mailer['from']);
$message->to($email)->subject($subject);
});
Kết luận
Trên đây là những chia sẻ của tôi về gửi mail bằng dịch vụ SES của Amazon cũng như một tính năng khá hay mà SES cung cấp đó là tracking mail open, nó sẽ giúp bạn có một số liệu chính xác cho mục đích của module bạn đang thực hiện cũng như doanh nghiệp của bạn. Mong là bài viết này sẽ hữu ích cho các bạn khi tìm hiểu và ứng dụng gửi mail bằng dịch vụ của Amazon.