惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
N
News | PayPal Newsroom
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
博客园 - Franky
SecWiki News
SecWiki News
Recent Announcements
Recent Announcements
T
Troy Hunt's Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
S
Security Affairs
博客园 - 司徒正美
S
Schneier on Security
I
InfoQ
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
腾讯CDC
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
Cloudbric
Cloudbric
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
Vulnerabilities – Threatpost
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
Schneier on Security
Schneier on Security
O
OpenAI News
K
Kaspersky official blog

博客园 - 正怒月神

windows 安装 openclaw docker-compose 启动 elk linux mysql 备份 maven 打包时优先选择本地仓库 nginx 部署2个相同的vue minio 设置IP MapStruct-plus cannot find converter from jenkins pipeline 发布 jar并运行 MapperStruct 嵌套模型中 List<> 转 List<String> Easy es问题总结 Logstash docker发布 Docker 无法拉取 springmvc 多事务提交和回滚 springMvc 配置 UReport2 java 通过 microsoft graph 调用outlook(三) JPA Example 默认 join jackson.dataformat.xml 反序列化 对象中包含泛型 OR-TOOL 背包算法 解决JIRA、Confluence自动注销登录的问题
java 通过 microsoft graph 调用outlook(二)
正怒月神 · 2024-03-18 · via 博客园 - 正怒月神

这次提供一些基础调用方式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);
    }
 
}