玩转exchange(查找邮件,修改邮件,发送邮件)

2022-03-28 00:00:00 邮件 发送邮件 玩转

背景:

每天早上需要发站会纪要,纪要内容为组员昨日的工作完成情况,工作完成情况需要从每个组员的exchange邮件中选择昨日发的日报邮件,提取信息,因组员很多,每天这种重复的复制粘贴操作很麻烦,就想到了用java写个程序来完成这个事。

概念:

exchage 与 outlook
Exchange是服务器端的软件,而Outlook是其客户端的软件。只是Outlook不仅仅可以作为Exchange的客户端,还可以接收其他支持Pop3等的邮件,当然,Exchange邮件接收方式也不仅仅局限于使用Outlook,你也可以使用Foxmail等其他软件,也可以通过Web方式使用OWA方式接收。(PS:在网上搜索API的时候千万不要搜outlook相关的api,因为是针对exchange服务端进行邮件的操作,而非outlook,虽然我们在客户端使用的outlook)

方法:

  • 使用微软的第三方库OfficeDev/ews-java-api 来实现exchange邮件相关操作,Github:https://github.com/OfficeDev/ews-java-api
  • 使用Jsoup库来实现对邮件里的html内容进行解析及替换,Github:https://github.com/jhy/jsoup

步骤:

  1. 连接exchange
  2. 查找自己邮件中的组员邮件,并保存
  3. 查找日报模板邮件,并在指定位置替换成组员邮件中的信息
  4. 发送邮件

代码:

  • domain
package outlook.meeting
 
class UserStandMeeting {
 
    static constraints = {
 
    }
 
    UserStandMeeting(List<String> yesterdayWork,List<String> todayWork,List<String> progress){
        this.yesterdayWork = yesterdayWork
        this.todayWork = todayWork
        this.progress = progress
    }
 
    //成员姓名
    String member
    //昨日工作列表
    List<String> yesterdayWork
    //今日工作列表
    List<String> todayWork
    //昨日工作进度
    List<String> progress
}
  • main函数
package outlook.meeting

import microsoft.exchange.webservices.data.core.ExchangeService
import microsoft.exchange.webservices.data.core.PropertySet
import microsoft.exchange.webservices.data.core.enumeration.property.BasePropertySet
import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName
import microsoft.exchange.webservices.data.core.enumeration.search.FolderTraversal
import microsoft.exchange.webservices.data.core.service.folder.Folder
import microsoft.exchange.webservices.data.core.service.item.EmailMessage
import microsoft.exchange.webservices.data.core.service.item.Item
import microsoft.exchange.webservices.data.core.service.schema.FolderSchema
import microsoft.exchange.webservices.data.credential.ExchangeCredentials
import microsoft.exchange.webservices.data.credential.WebCredentials
import microsoft.exchange.webservices.data.property.complex.MessageBody
import microsoft.exchange.webservices.data.search.FindFoldersResults
import microsoft.exchange.webservices.data.search.FolderView
import microsoft.exchange.webservices.data.search.ItemView
import microsoft.exchange.webservices.data.search.filter.SearchFilter
import org.apache.commons.lang3.StringUtils
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements

import java.text.SimpleDateFormat

class ReceiveMailByOnlineController {

    //你的exchange账号
    private static String EMAIL = "your exchange email"
    //local地址:打开outlook->右上方文件-> office账户->local地址会显示在用户账户下方
    private static String EMAIL_LOCAL = "your exchange local"
    //你的exchange账号密码
    private static String EMAIL_PASSWORD = "your exchange password"
    //收件人的exchange账号
    private static String EMAIL_TO = "to exchange email"
    //组员成员
    private static List<String> TEAM = Arrays.asList("xxx","xxx","xxx","xxx","xxx","xxx","xxx","xxx","xxx")
    //筛选条件,筛选邮件时会根据这个字段来进行条件筛选
    private static String FILTER_KEY = "日报"
    //模板筛选条件,筛选模板邮件时会根据这个字段来进行条件筛选
    private static String TEMPLATE_FOLDER_KEY = "站会纪要模板"

    static void main(String[] args) {
        //鉴权,获取连接
        ExchangeService service = anthAccount()
        //获取与保存数据
        List<UserStandMeeting> userStandMeetingList = new ArrayList<UserStandMeeting>()
        for(String member : TEAM){
            getMemberContent(service,member,userStandMeetingList)
        }
        //获取模板,替换数据并发送
        getTemplateContent(service,userStandMeetingList)
    }

    static ExchangeService anthAccount(){
        ExchangeService service = new ExchangeService()
        ExchangeCredentials credentials = new WebCredentials(EMAIL_LOCAL, EMAIL_PASSWORD)
        service.setCredentials(credentials)
        service.autodiscoverUrl(EMAIL)
        return service
    }

    //查找组员日报邮件
    static getMemberContent(ExchangeService service,String member,List<UserStandMeeting> userStandMeetingList){
        //查找文件
        FolderView view = new FolderView(10)
        view.traversal = FolderTraversal.Deep
        view.propertySet = new PropertySet(BasePropertySet.IdOnly)
        view.propertySet.add(FolderSchema.DisplayName)
        SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName,member)
        FindFoldersResults findFolderResults = service.findFolders(WellKnownFolderName.Root, searchFilter, view)
        for(Folder item : findFolderResults.getFolders()){
            for(Item i : item.findItems(new ItemView(10))){
                if(i.getSubject().contains(FILTER_KEY)){
                    EmailMessage emailMessage = EmailMessage.bind(service, i.getId())
                    Document doc = Jsoup.parse(emailMessage.getBody().text,"GBK")
                    println("小组成员:" + member)
                    userStandMeetingList.push(getTableData(doc,member))
                    return
                }
            }
        }
    }

    //获取模板邮件数据
    static getTemplateContent(ExchangeService service,List<UserStandMeeting> userStandMeetingList){
        //查找文件
        FolderView view = new FolderView(1)
        view.traversal = FolderTraversal.Deep
        view.propertySet = new PropertySet(BasePropertySet.IdOnly)
        view.propertySet.add(FolderSchema.DisplayName)
        SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName,TEMPLATE_FOLDER_KEY)
        FindFoldersResults findFolderResults = service.findFolders(WellKnownFolderName.Root, searchFilter, view)
        for(Folder item : findFolderResults.getFolders()){
            for(Item i : item.findItems(new ItemView(1))){
                EmailMessage emailMessage = EmailMessage.bind(service, i.getId())
                Document doc = Jsoup.parse(emailMessage.getBody().text,"GBK")
                String messageBody = replaceTableData(doc,userStandMeetingList)
                sendMail(service,messageBody)
                println("替换数据成功")
                return
            }
        }
    }

    //解析日报信息
    static getTableData(Document doc,String member){
        Elements elements = doc.getElementsByTag("table")
        UserStandMeeting userStandMeeting = new UserStandMeeting(new ArrayList<String>(),new ArrayList<String>(),new ArrayList<String>())
        userStandMeeting.member = member
        for(Element element:elements){
            if(element.text() !=null && !"".equals(element.text())){
                Elements es = element.select("tr")
                for(Element tdelement:es){
                    Elements tdes = tdelement.select("td")
                    //只筛选需要的数据(今日工作)
                    //针对个别组员邮件格式不规范写的兼容代码
                    if(tdes.size() == 5 && !"工作事项".equals(tdes[0].text()) && !"xxx".equals(member) && !"xxx".equals(member) ||
                            (tdes.size() == 6 && !"工作事项".equals(tdes[0].text()) && "xxx".equals(member)) ||
                            (tdes.size() == 6 && !"工作事项".equals(tdes[0].text()) && "xxx".equals(member))) {
                        if(StringUtils.isNotBlank(tdes[0].text())){
                            userStandMeeting.yesterdayWork.push(tdes[0].text())
                            userStandMeeting.progress.push(tdes[2].text())
                        }
                    }
                    //只筛选需要的数据(昨日工作)
                    //针对个别组员邮件格式不规范写的兼容代码
                    if((tdes.size() == 4 && !"工作事项".equals(tdes[0].text()) && !"xxx".equals(member)) && !"xxx".equals(member) ||
                            (tdes.size() == 5 && !"工作事项".equals(tdes[0].text()) && "xxx".equals(member)) ||
                            (tdes.size() == 5 && !"工作事项".equals(tdes[0].text()) && "xxx".equals(member))){
                        if(StringUtils.isNotBlank(tdes[0].text())){
                            userStandMeeting.todayWork.push(tdes[0].text())
                        }
                    }
                }
            }
        }
        return userStandMeeting
    }

    //替换模板数据
    static replaceTableData(Document doc,List<UserStandMeeting> userStandMeetingList){
        Elements elements = doc.getElementsByTag("table")
        for(Element element:elements){
            if(element.text() !=null && !"".equals(element.text())){
                Elements es = element.select("tr")
                for(Element tdelement:es){
                    Elements tdes = tdelement.select("td")
                    if(tdes.size() == 7 && tdes[0].text() != "姓名"){
                        for(UserStandMeeting u : userStandMeetingList){
                            if(u.member.equals(tdes[0].text())){
                                String yesterdayWork = ""
                                for(String s : u.yesterdayWork){
                                    yesterdayWork = yesterdayWork + s + "<br>"
                                }
                                tdes[1].html(yesterdayWork)
                                String progress = ""
                                for(String s : u.progress){
                                    progress = progress + s + "<br>"
                                }
                                tdes[2].html(progress)
                                String todayWork = ""
                                for(String s : u.todayWork){
                                    todayWork = todayWork + s + "<br>"
                                }
                                tdes[3].html(todayWork)
                            }
                        }
                    }
                }
            }
        }
        return new String(doc.html().getBytes("UTF-8"),"UTF-8")
    }


    //发送邮件
    static sendMail(ExchangeService service,String messageBody){
        EmailMessage email = new EmailMessage(service)
        email.toRecipients.add(EMAIL_TO)
        email.subject = formatDate()
        email.body = new MessageBody(messageBody)
        email.send()
        println("send success")
    }

    //时间格式化
    static formatDate(){
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD")
        return sdf.format(new Date()) + "站会纪要"
    }
}

    原文作者:coding_forever
    原文地址: https://blog.csdn.net/liuyuqin1991/article/details/86583927
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章