这次提供一些基础调用方式API
下一篇文章,我会使用6.10.0版本,这个版本不像之前的6.x.x非常慢。
里面会带有 reply回复接口
PS:
getMailFolders 接口返回的属性中,包含了未读邮件数量unreadItemCount
一 POM文件
<!-- office 365 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.11.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.microsoft.graph</groupId>
<artifactId>microsoft-graph</artifactId>
<version>5.77.0</version>
</dependency>
<!-- office 365 -->
二 Domain
import com.microsoft.graph.models.FileAttachment;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class MessageVo {
private String messageId;
private List<String> recipients;
private String subject;
private String body;
private List<FileAttachment> attachments=new ArrayList<>();
}
三 Service / Impl
service
package com.xxx.mail.service;
import com.microsoft.graph.models.*;
import com.microsoft.graph.requests.MailFolderCollectionPage;
import com.microsoft.graph.requests.MessageCollectionPage;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface IMailOffice365Service {
/**
* 用户信息
*
* @param email
* @return
*/
User getUser(String email);
/**
* 邮件文件夹
* 可显示未读邮件数量
* @param email 邮箱
* @return
*/
MailFolderCollectionPage getMailFolders(String email);
/**
* 邮件列表
*
* @param email
* @return
*/
MessageCollectionPage getFolderMails(String email, String folderId, int page, int size);
MessageCollectionPage getMails(String email,int page,int size);
/**
* 邮件
*
* @param email
* @param messageId
* @return
*/
Message getMailById(String email, String messageId);
/**
* 多个邮件
*
* @param email
* @param messageIds
* @return
*/
List<Message> getMailByIds(String email, List<String> messageIds);
/**
* 带有图片的邮件
*
* @param message
* @return
*/
Message getMailByIdWithAttachment(Message message);
/**
* 发送邮件
*
* @param sender
* @param recipient
* @param subject
* @param body
* @throws Exception
*/
Message sendMail(String sender , String recipient , String subject, String body) throws Exception;
/**
* 发送邮件和附件(多个收件人)
*
* @param sender
* @param recipients
* @param subject
* @param body
* @throws Exception
*/
Message sendMail(String sender , List<String> recipients , String subject, String body) throws Exception;
/**
*
* @param sender
* @param recipients
* @param subject
* @param body
* @param files
* @return
* @throws Exception
*/
Message sendMail(String sender , List<String> recipients , String subject, String body, List<FileAttachment> files) throws Exception;
/**
*
* 回复
*
* @param messageId
* @param sender
* @param recipient
* @param subject
* @param body
* @throws Exception
*/
Message replyMail(String messageId, String sender, String recipient, String subject, String body) throws Exception;
/**
*
* 回复
*
* @param messageId
* @param sender
* @param recipients
* @param subject
* @param body
* @throws Exception
*/
Message replyMail(String messageId, String sender, List<String> recipients, String subject, String body) throws Exception;
/**
*
* 回复带附件
*
* @param messageId
* @param sender
* @param recipients
* @param subject
* @param body
* @throws Exception
*/
Message replyMail(String messageId, String sender, List<String> recipients, String subject, String body, List<FileAttachment> files) throws Exception;
/**
* 添加附件
* @param message
* @param files
* @return
*/
Message addAttarchment(Message message,List<FileAttachment> files);
/**
* 设置已读
* @param sender
* @param message
* @return
*/
Message setRead(String sender,Message message);
}
impl
package com.xxx.mail.service.impl;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.helka.mail.service.IMailOffice365Service;
import com.microsoft.graph.authentication.IAuthenticationProvider;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.models.*;
import com.microsoft.graph.requests.*;
import okhttp3.Request;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;
import java.util.List;
@Service("mailOffice365Util")
public class MailOffice365Impl implements IMailOffice365Service {
@Value("${mailOffice365.clientId}")
private String clientId;
@Value("${mailOffice365.tenantId}")
private String tenantId;
@Value("${mailOffice365.clientSecret}")
private String clientSecret;
@Value("${mailOffice365.graphUserScopes}")
private String graphUserScopes;
private IAuthenticationProvider authProvider;
private GraphServiceClient<Request> graphClient;
@PostConstruct
public void init() {
auth();
graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
}
/**
* auth 授权
*/
private void auth() {
ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.tenantId(tenantId)
.clientSecret(clientSecret)
.build();
authProvider = new TokenCredentialAuthProvider(
Arrays.asList("https://graph.microsoft.com/.default")
, clientSecretCredential
);
}
/**
* 获取用户信息
*
* @param email 邮箱
* @return
*/
public User getUser(String email) {
User user = graphClient.users(email)
.buildRequest()
.select("displayName,mail,userPrincipalName")
.get();
return user;
}
/**
* 邮件文件夹
*
* @param email 邮箱
* @return
*/
@Override
public MailFolderCollectionPage getMailFolders(String email) {
MailFolderCollectionPage result = graphClient.users(email).mailFolders().buildRequest().get();
return result;
}
/**
* 获取文件夹邮件
*
* @param email 邮箱
* @return
*/
public MessageCollectionPage getFolderMails(String email, String folderId, int page, int size) {
MessageCollectionPage message = graphClient.users(email)
.mailFolders()
.byId(folderId)
.messages()
.buildRequest()
.select("id,from,isRead,receivedDateTime,subject")
.skip(page * size)
.top(size)
.orderBy("receivedDateTime DESC")
.get();
return message;
}
/**
* 获取邮件
*
* @param email 邮箱
* @return
*/
public MessageCollectionPage getMails(String email, int page, int size) {
MessageCollectionPage message = graphClient.users(email)
.messages()
.buildRequest()
.select("id,from,isRead,receivedDateTime,subject")
.skip(page * size)
.top(size)
.orderBy("receivedDateTime DESC")
.get();
return message;
}
/**
* 邮件详情
*
* @param email 邮箱
* @param messageId 邮件id
* @return
*/
@Override
public Message getMailById(String email, String messageId) {
Message message = graphClient.users(email)
// .mailFolders("inbox")
.messages()
.byId(messageId)
.buildRequest()
.select("id,from,isRead,receivedDateTime,subject,body,hasAttachments")
.expand("attachments")
.get();
//转换邮件中的图片
message = getMailByIdWithAttachment(message);
return message;
}
@Override
public List<Message> getMailByIds(String email, List<String> messageIds) {
List<Message> messages = new ArrayList<>();
if (!CollectionUtils.isEmpty(messageIds)) {
for (String messageId : messageIds) {
Message message = getMailById(email, messageId);
messages.add(message);
}
}
return messages;
}
/**
* 获取带有图片的邮件
*
* @param message 邮件
* @return
*/
@Override
public Message getMailByIdWithAttachment(Message message) {
//邮件内图片展示
String emailBody = message.body.content;
for (Attachment attachment : message.attachments.getCurrentPage()) {
if (attachment.isInline.booleanValue()) {
if ((attachment instanceof FileAttachment) && (attachment.contentType.contains("image"))) {
FileAttachment fileAttachment = (FileAttachment) attachment;
byte[] contentBytes = fileAttachment.contentBytes;
String imageContentIDToReplace = "cid:" + fileAttachment.contentId;
emailBody = emailBody.replace(imageContentIDToReplace,
String.format("data:image;base64,%s", Base64.getEncoder().encodeToString(contentBytes
)));
}
}
}
message.body.content = emailBody;
return message;
}
/**
* 发送邮件
*
* @param sender 发件人
* @param recipient 收件人
* @param subject 主题
* @param body 内容
* @throws Exception
*/
public Message sendMail(String sender, String recipient, String subject, String body) throws Exception {
List<String> recipients = List.of(recipient);
return sendMail(sender, recipients, subject, body, null);
}
/**
* 发送邮件(多个收件人)
*
* @param sender 发件人
* @param recipients 多收件人
* @param subject 主题
* @param body 内容
* @throws Exception
*/
public Message sendMail(String sender, List<String> recipients, String subject, String body) throws Exception {
return sendMail(sender, recipients, subject, body, null);
}
@Override
public Message sendMail(String sender, List<String> recipients, String subject, String body, List<FileAttachment> files) throws Exception {
// Ensure client isn't null
if (graphClient == null) {
throw new Exception("Graph has not been initialized for user auth");
}
// Create a new message
Message message = new Message();
message.subject = subject;
message.body = new ItemBody();
message.body.content = body;
message.body.contentType = BodyType.HTML;
//收件人
if (recipients != null && recipients.size() > 0) {
message.toRecipients = new ArrayList<>();
for (String item : recipients) {
Recipient toRecipient = new Recipient();
toRecipient.emailAddress = new EmailAddress();
toRecipient.emailAddress.address = item;
message.toRecipients.add(toRecipient);
}
}
//附件
message = addAttarchment(message, files);
// Send the message
graphClient
.users(sender)
.sendMail(UserSendMailParameterSet.newBuilder()
.withMessage(message)
.build())
.buildRequest()
.post();
return message;
}
public Message replyMail(String messageId, String sender, String recipient, String subject, String body) throws Exception {
List<String> recipients = List.of(recipient);
return replyMail(messageId, sender, recipients, subject, body, null);
}
public Message replyMail(String messageId, String sender, List<String> recipients, String subject, String body) throws Exception {
return replyMail(messageId, sender, recipients, subject, body, null);
}
@Override
public Message replyMail(String messageId, String sender, List<String> recipients, String subject, String body, List<FileAttachment> files) throws Exception {
Message message = new Message();
message.subject = subject;
message.body = new ItemBody();
message.body.content = body;
message.body.contentType = BodyType.HTML;
//附件
message = addAttarchment(message, files);
graphClient.users(sender)
.messages()
.byId(messageId)
.reply(MessageReplyParameterSet.newBuilder()
.withMessage(message)
// .withComment("helloasf")
.build())
.buildRequest()
.post();
return message;
}
@Override
public Message addAttarchment(Message message, List<FileAttachment> files) {
if (files != null && files.size() > 0) {
List<Attachment> attachmentList = new ArrayList<>();
for (FileAttachment file : files) {
FileAttachment attachment = new FileAttachment();
attachment.name = file.name;
attachment.oDataType = "#microsoft.graph.fileAttachment";
attachment.contentType = file.contentType;
attachment.contentBytes = file.contentBytes;
attachment.isInline = file.isInline;
attachment.contentId = file.contentId;
attachment.size = file.size;
attachmentList.add(attachment);
}
AttachmentCollectionResponse attachmentCollectionResponse = new AttachmentCollectionResponse();
attachmentCollectionResponse.value = attachmentList;
AttachmentCollectionPage attachmentCollectionPage = new AttachmentCollectionPage(attachmentCollectionResponse, null);
message.attachments = attachmentCollectionPage;
}
return message;
}
@Override
public Message setRead(String sender, Message message) {
if (!message.isRead) {
Message newMessage = new Message();
newMessage.isRead = true;
graphClient.users(sender)
.messages()
.byId(message.id)
.buildRequest()
.patch(newMessage);
}
return message;
}
}
四 调用
读取邮箱的权限,在第一篇中有说,不赘述了。
package com.xxx.mail.controller;
import com.xxx.common.core.domain.R;
import com.xxx.common.satoken.utils.LoginHelper;
import com.xxx.common.web.core.BaseController;
import com.xxx.mail.domain.MessageVo;
import com.xxx.mail.service.IMailOffice365Service;
import com.microsoft.graph.models.*;
import com.microsoft.graph.requests.MailFolderCollectionPage;
import com.microsoft.graph.requests.MessageCollectionPage;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mail365")
public class MailController extends BaseController {
@Autowired
IMailOffice365Service mailOffice365Service;
@GetMapping("/getUser")
public R<User> getUser() {
String account = LoginHelper.getLoginUser().getEmail();
User user = mailOffice365Service.getUser(account);
return R.ok(user);
}
@GetMapping("/getMailFolders")
public R<List<MailFolder>> getMailFolders() {
String account = LoginHelper.getLoginUser().getEmail();
MailFolderCollectionPage folder = mailOffice365Service.getMailFolders(account);
return R.ok(folder.getCurrentPage());
}
@GetMapping("/getFolderMails")
public R<List<Message>> getFolderMails(String folderId, int pageIndex) {
String account = LoginHelper.getLoginUser().getEmail();
MessageCollectionPage mails = mailOffice365Service.getFolderMails(account, folderId, pageIndex, 10);
return R.ok(mails.getCurrentPage());
}
@GetMapping("/getMails")
public R<List<Message>> getMails(int pageIndex) {
String account = LoginHelper.getLoginUser().getEmail();
MessageCollectionPage mails = mailOffice365Service.getMails(account, pageIndex, 10);
return R.ok(mails.getCurrentPage());
}
@GetMapping("/getMailById")
public R<Message> getMailById(String messageId) {
String account = LoginHelper.getLoginUser().getEmail();
Message mail = mailOffice365Service.getMailById(account, messageId);
//设置已读
mailOffice365Service.setRead(account,mail);
return R.ok(mail);
}
@GetMapping("/getMailByIds")
public R<List<Message>> getMailByIds(List<String> messageIds){
String account = LoginHelper.getLoginUser().getEmail();
List<Message> mails = mailOffice365Service.getMailByIds(account, messageIds);
for(Message mail : mails){
//设置已读
mailOffice365Service.setRead(account,mail);
}
return R.ok(mails);
}
@PostMapping("/sendMail")
public R<Message> sendMail(@RequestBody MessageVo req) throws Exception {
String account = LoginHelper.getLoginUser().getEmail();
mailOffice365Service.sendMail(
account
,req.getRecipients()
,req.getSubject()
,req.getBody()
,req.getAttachments()
);
return R.ok();
}
@PostMapping("/replyMail")
public R<Message> replyMail(@RequestBody MessageVo req) throws Exception {
String account = LoginHelper.getLoginUser().getEmail();
Message message = mailOffice365Service.replyMail(req.getMessageId()
, account
, req.getRecipients()
, req.getSubject()
, req.getBody()
, req.getAttachments());
return R.ok(message);
}
}