Hướng dẫn gửi mail thông qua Microsoft Graph API
Back To Blogscom.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.office365.com, 587; timeout -1
sử dụng lệnh: telnet smtp.office365.com
thì kết quả chỉ nhận được timeout.
Vậy nên mình đã nghiên cứu một phương pháp mới sử dụng Microsoft Graph API và chia sẻ cho mọi người. Nó sẽ bao gồm các bước:
- Đăng ký tài khoản azure.
- Tạo ứng dụng.
- Cấp quyền gửi mail.
- Mã nguồn gọi API.
Đăng ký tài khoản auzre
Bạn sẽ cần thực hiện các bước sau:
1. Hãy đảm bảo bạn đã có tài khoản office 365 doanh nghiệp. Bạn có thể đăng ký gói cơ bản.

2. Tiếp theo bạn có thể truy cập https://portal.azure.com và tạo tài khoản, sau khi tạo tài khoản xong bạn có thể thấy giao diện:

Hãy dành sự chú ý đến ô tìm kiếm.
Tạo ứng dụng
3. Tiếp theo bạn hãy vào Azure Active Directory > App registrations
bằng cách nhập vào ô tìm kiếm App registrations và chọn kết quả đầu tiên mà bạn tìm được:

Kết quả bạn nhận được một giao diện mới có nút New registration
:

4. Tiếp theo bạn hãy đăng ký một ứng dụng bằng cách nhấn vào nút New registration
một giao diện sẽ hiện ra và bạn có thể điền các thông tin cần thiết, ví dụ:

Sau đó nhấn nút Register
bạn sẽ nhận được một giao diện kết quả với nút Add a certificate or secret
như sau:

5. Tiếp theo hãy nhấn vào nút Add a certificate or secret
để mở giao diện tạo khoá bí mật.

6. Tiếp theo bạn hãy nhấn vào nút New client secret
để điền thông tin.

Sau đó nhấn nút Add
để tạo khoá bí mật.
Bạn hãy sao chép khoá bí mật trong cột value và lưu vào đâu đó vì khoá bí mật này chỉ xuất hiện duy nhất 1 lần:

Sau đó bạn hãy quay trở lại ứng dụng bằng cách nhấn vào menu item Overview
:

Tổng kết lại sau bước tạo ứng dụng bạn đã có:
- Mã ứng dụng (TENANT_ID): Là giá trị của trường
Directory (tenant) ID
được lấy ở màn hình chi tiết ứng dụng. - Mã khách (CLIENT_ID): Là giá trị của trường
Application (client) ID
được lấy ở màn hình chi tiết ứng dụng. - Khoá bí mật (CLIENT_SECRET): Là khoá chỉ xuất hiện 1 lần mà bạn đã lưu.
3. Cấp quyền gửi mail.
Bây giờ bạn hãy quay lại office 365 admin center, ở menu bạn hãy nhấn vào nút Hiển thị tất cả
:

Bạn sẽ thấy có thêm các menu mới hiện ra, trong đó có menu Exchange
:

Bạn hãy click vào menu này, giao diện danh sách các tài khoản sẽ được hiện ra. Bạn hãy chọn một tài khoản mà bạn muốn dùng để gửi email để cấu hình.
Khi giao diện cấu hình hiển thị bạn hãy chọn vào mục Thư
để thấy giao diện cấu hình thư như sau:

Tiếp theo bạn hãy nhấn vào nút Quản lý ứng dụng email
. Bạn có thể chọn toàn bộ các ứng dụng:

4. Mã nguồn gọi API.
Sau khi đã cấu hình xong mọi thứ, giờ là lúc bạn có thể sử dụng thư viện ezyhttp-client để gọi API gửi mail với mã nguồn như sau:
import com.tvd12.ezyfox.util.EzyMapBuilder; import com.tvd12.ezyhttp.client.HttpClient; import com.tvd12.ezyhttp.client.request.PostRequest; import com.tvd12.ezyhttp.client.request.RequestEntity; import com.tvd12.ezyhttp.core.response.ResponseEntity; import java.util.Map; public class GraphEmailSender { private static final String TENANT_ID = "Thay bằng directory id của bạn"; private static final String CLIENT_ID = "Thay bằng application id của bạn"; private static final String CLIENT_SECRET = "Thay bằng khoá bí mật của bạn"; private static final String SENDER_EMAIL = "Thay bằng email mà bạn đã cấu hình"; private static final String RECIPIENT_EMAIL = "Thay bằng email của người nhận"; public static void main(String[] args) { try { String accessToken = getAccessToken(); sendEmail(accessToken); } catch (Exception e) { e.printStackTrace(); } } private static String getAccessToken() throws Exception { Map<String, Object> form = EzyMapBuilder .mapBuilder() .put("client_id", CLIENT_ID) .put("scope", "https://graph.microsoft.com/.default") .put("client_secret", CLIENT_SECRET) .put("grant_type", "client_credentials") .toMap(); RequestEntity entity = RequestEntity.builder() .contentType("application/x-www-form-urlencoded") .body(form) .build(); String url = "https://login.microsoftonline.com/" + TENANT_ID + "/oauth2/v2.0/token"; PostRequest request = new PostRequest() .setURL(url) .setEntity(entity); Map<String, Object> response = HttpClient.builder() .build() .call(request); return (String) response.get("access_token"); } private static void sendEmail(String accessToken) throws Exception { Map<String, Object> emailBody = EzyMapBuilder .mapBuilder() .put("message", EzyMapBuilder .mapBuilder() .put("subject", "Test email from Microsoft Graph API (EzyHttp)") .put("body", EzyMapBuilder .mapBuilder() .put("contentType", "Text") .put("content", "Hello, this is a test email sent via Microsoft Graph API using EzyHttp.") .toMap()) .put("toRecipients", new Object[] { EzyMapBuilder .mapBuilder() .put("emailAddress", EzyMapBuilder .mapBuilder() .put("address", RECIPIENT_EMAIL) .build()) .toMap() }) .toMap()) .toMap(); RequestEntity entity = RequestEntity.builder() .header("Authorization", "Bearer " + accessToken) .header("Content-Type", "application/json") .body(emailBody) .build(); String url = "https://graph.microsoft.com/v1.0/users/" + SENDER_EMAIL + "/sendMail"; PostRequest request = new PostRequest() .setEntity(entity) .setURL(url); ResponseEntity response = HttpClient.builder().build().request(request); System.out.println("Status: " + response.getStatus()); System.out.println("Response: " + response.getBody()); } }
Khi bạn nhận được Status: 202
nghĩa là thành công.
Tổng kết
Vì nhiều lý do mà Microsoft hạn chế việc gửi email thông qua smtp, vậy nên phương án sử dụng Microsoft Graph API là một giải pháp thay thế. Tuy nhiên các bước cấu hình tương đối phức tạp, nằm rải rác ở nhiều giao diện khác nhau, khi tích hợp thì có nhiều lỗi khó hiểu. Hy vọng bài viết này sẽ giúp công việc tích hợp của bạn sẽ trở nên đơn giản hơn.