Hướng dẫn Sendmail trong Laravel sử dụng dịch vụ SES của Amazon

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ỳ.

Dịch vụ SES là gì?
Dịch vụ SES của Amazon

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:

  1. https://beginaws.awsstudygroup.com/vi/1-account-setup/1-create-new-aws-account/
  2. 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.

đăng nhập vào dashboard quản trị của Amazon

Tiếp theo hãy chọn phân vùng phù hợp. 

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
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.

màn hình tạo IAM

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!

SMTP Username và SMTP Password

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
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
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

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.

Verification pending

Lúc này khi mở mail bạn sẽ thấy một mail từ Amazon.

mail từ Amazon.

Hãy mở mail và click vào link đính kèm trong nội dung để xác nhận nhé!

xác nhận

Khi xác nhận thành công, bạn sẽ nhận được màn hình này.

xác nhận thành công

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.

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é!

Send test email 

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
Formatted

Bạn sẽ nhận được màn hình trông như thế này:

Màn hình báo nhận được

Hãy vào hộp mail, bạn đã nhận được mail rồi đúng không? Easy nhỉ?

bạn đã nhận được mail

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 serveSau đó 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.

127.0.0.1:8000/test-sendmail

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.

email gửi từ ứng dụng Laravel

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.

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.

 chọn Add destination

Check vào Opens và nhấn Next.

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

Create SNS topic

Chọn Add destination ở màn hình tiếp theo.

Add destination

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 Topics

Chọn Create subscription

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.
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.

Simple Notification Service
 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

chọn Confirm subscription

Nhập url copy từ response vào và nhấn Confirm subscription

Confirm subscription

Khi đó trạng thái sẽ chuyển thành Confirmed.

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.

Tư vấn - Báo giá
Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
Mọi thông tin tư vấn và báo giá đều miễn phí.

    「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
    Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
    Tư vấn - Báo giá
    Mở rộng quy mô doanh nghiệp của bạn với ONETECH!
    Hãy liên hệ với chúng tôi để được cung cấp các dịch vụ phát triển phần mềm chất lượng cao với chi phí hợp lý nhất. Các kỹ sư của chúng tôi sẽ giúp bạn phát triển một giải pháp phù hợp để vượt lên đối thủ cạnh tranh của mình.
    Mọi thông tin tư vấn và báo giá đều miễn phí.

      「Chính sách bảo mật」Nếu bạn đồng ý với những điều trên, vui lòng nhấp vào nút "Gửi"
      Một email trả lời tự động sẽ được gửi đến địa chỉ email bạn đã nhập, vì vậy hãy kiểm tra điều đó.
      liên hệ