Quellcode durchsuchen

邮件拉取脚本

ControlDream vor 1 Jahr
Ursprung
Commit
3f43dcc179

+ 19 - 0
pom.xml

@@ -92,6 +92,25 @@
             <version>3.3.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 3 - 3
src/main/resources/application-dev.yml

@@ -1,9 +1,9 @@
 # spring配置
 spring:
   datasource:
-    url: jdbc:mysql://36.134.91.96:12333/bytesailing_mail?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
-    username: root
-    password: Fjhx@pwd123
+    url: jdbc:mysql://110.41.2.116:23063/bytesailing_mail?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
+    username: bytesailing_db_user
+    password: kfG-A93-w7h-qX8
 
 mail:
   # 至少要等待多少秒才会开启下一轮邮件同步

+ 20 - 0
src/test/java/test/pulling/TestMapper.java

@@ -0,0 +1,20 @@
+package test.pulling;
+
+import com.fjhx.email.entity.dto.MailboxInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface TestMapper {
+
+    @Select("select count(1) from enterprise_message")
+    Integer emailCount();
+
+    List<MailboxInfo> getMailboxInfoList();
+
+    @Select("select count(1) from enterprise_message where uid = #{uid} and folder_id = #{folderId}")
+    boolean uidIsExist(Long uid, Long folderId);
+
+}

+ 58 - 0
src/test/java/test/pulling/TestMapper.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="test.pulling.TestMapper">
+
+    <resultMap id="getMailboxInfoListByUserIdResultMap"
+               autoMapping="true"
+               type="com.fjhx.email.entity.dto.MailboxInfo">
+
+        <id column="id" property="id"/>
+        <result column="type" property="type"/>
+        <result column="mail_user" property="mailUser"/>
+        <result column="mail_password" property="mailPassword"/>
+        <result column="receive_host" property="receiveHost"/>
+        <result column="receive_port" property="receivePort"/>
+        <result column="receive_protocol" property="receiveProtocol"/>
+        <result column="address_type" property="addressType"/>
+
+        <collection property="mailFolderInfoList"
+                    autoMapping="true"
+                    ofType="com.fjhx.email.entity.dto.MailFolderInfo"
+                    javaType="java.util.List">
+
+            <id column="folder_id" property="id"/>
+            <result column="folder_name" property="name"/>
+            <result column="last_uid" property="lastUid"/>
+            <result column="last_received_date" property="lastReceivedDate"/>
+
+        </collection>
+
+    </resultMap>
+
+    <select id="getMailboxInfoList" resultMap="getMailboxInfoListByUserIdResultMap">
+        SELECT 2                                                type,
+               em.id,
+               CONCAT(em.mail_user_prefix, '@', ed.domain_name) mail_user,
+               em.mail_password,
+               ed.receive_host,
+               ed.receive_port,
+               ed.receive_protocol,
+               ef.id                                            folder_id,
+               ef.NAME                                          folder_name,
+               ef.last_uid,
+               ef.last_received_date,
+               ed.type                                          address_type
+        FROM enterprise_domain ed
+                 INNER JOIN enterprise_mailbox em ON ed.id = em.domain_id
+                 INNER JOIN enterprise_folder ef ON em.id = ef.mailbox_id
+        WHERE ed.del_flag = 0
+          AND em.del_flag = 0
+          AND ef.del_flag = 0
+          AND em.STATUS = 1
+          AND em.sync_status = 1
+          AND ef.sync_status = 1
+          AND em.tenant_id = 'ehsd'
+        GROUP BY em.id
+    </select>
+
+</mapper>

+ 225 - 0
src/test/java/test/pulling/TestSy.java

@@ -0,0 +1,225 @@
+package test.pulling;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson2.JSON;
+import com.fjhx.email.EmailSyncApplication;
+import com.fjhx.email.entity.dto.MailFolderInfo;
+import com.fjhx.email.entity.dto.MailInfo;
+import com.fjhx.email.entity.dto.MailboxInfo;
+import com.fjhx.email.utils.email.ImapUtil;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPMessage;
+import com.sun.mail.imap.IMAPStore;
+import com.sun.mail.util.MailConnectException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.mail.*;
+import javax.mail.internet.InternetAddress;
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = EmailSyncApplication.class)
+@MapperScan(basePackages = "test.pulling")
+public class TestSy {
+
+    @Autowired
+    private TestMapper testMapper;
+
+    @Test
+    public void syn() {
+        //获取所有企业邮箱列表
+        List<MailboxInfo> mailboxInfoList = testMapper.getMailboxInfoList();
+        log.info("邮箱数" + mailboxInfoList.size());
+
+        List<String> arr = new ArrayList<>();
+        for (MailboxInfo mailboxInfo : mailboxInfoList) {
+            String format = String.format("%s(%s)", mailboxInfo.getMailUser(), mailboxInfo.getId());
+            arr.add(format);
+        }
+//        String collect = arr.stream().collect(Collectors.joining("\r\n"));
+//        System.out.println(collect);
+
+
+        ExecutorService threadPool = Executors.newFixedThreadPool(mailboxInfoList.size());
+
+        // 开启抓取邮件任务
+        for (MailboxInfo mailbox : mailboxInfoList) {
+            //拉取指定id
+//            Long id = 1685827968359731201l;
+//            if (id.equals(mailbox.getId())) {
+//                synchronousMail(mailbox);
+//            }
+
+            List<Long> ids = Arrays.asList(
+                    1685828811683270658L
+            );
+
+            threadPool.submit(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (ids.contains(mailbox.getId())) {
+                            System.out.println(mailbox.getMailUser());
+                            synchronousMail(mailbox);
+                        }
+                    } catch (Exception e) {
+                        log.error("同步出错", e);
+                    }
+
+                }
+            });
+        }
+
+
+        threadPool.shutdown();
+        try {//等待直到所有任务完成
+            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+
+        log.info("同步完成");
+    }
+
+    /**
+     * 同步邮箱
+     */
+    public void synchronousMail(MailboxInfo mailboxInfo) {
+        IMAPStore store = null;
+
+        try {
+
+            // 获取邮件连接
+            store = ImapUtil.getStore(
+                    mailboxInfo.getReceiveHost(),
+                    mailboxInfo.getMailUser(),
+                    mailboxInfo.getMailPassword());
+
+            // 邮件文件夹
+            List<MailFolderInfo> mailFolderInfoList = mailboxInfo.getMailFolderInfoList();
+
+            // 分别拉取每个文件夹邮件
+            for (MailFolderInfo mailFolder : mailFolderInfoList) {
+
+                // 获取文件夹
+                IMAPFolder folder = (IMAPFolder) store.getFolder(mailFolder.getName());
+
+                // 只读方式打开收件箱
+                try {
+                    folder.open(Folder.READ_ONLY);
+                } catch (FolderNotFoundException folderNotFoundException) {
+                    continue;
+                }
+
+                try {
+                    // 获取文件夹邮件
+                    Message[] messages = folder.getMessages();
+                    if (messages == null || messages.length == 0) {
+                        continue;
+                    }
+
+                    // 拉取邮件
+                    List<MailInfo> mailInfoList = getMailInfoList(mailboxInfo, folder, mailFolder, messages);
+
+                } finally {
+                    ImapUtil.closeFolder(folder);
+                }
+            }
+
+        } catch (AuthenticationFailedException e) {
+            log.error("邮箱认证失败:{}", JSON.toJSONString(mailboxInfo), e);
+        } catch (MailConnectException e) {
+            log.error("邮件连接失败:{}", JSON.toJSONString(mailboxInfo), e);
+        } catch (Exception e) {
+            log.error("邮件同步出错,邮箱信息:{}", JSON.toJSONString(mailboxInfo), e);
+        } finally {
+            try {
+                ImapUtil.closeStore(store);
+            } catch (MessagingException e) {
+                log.error("email链接关闭失败:{}", mailboxInfo);
+            }
+        }
+
+    }
+
+
+    /**
+     * 拉取邮件
+     */
+    private List<MailInfo> getMailInfoList(MailboxInfo mailboxInfo, IMAPFolder folder, MailFolderInfo mailFolder, Message[] messages) throws Exception {
+        // 收件列表
+        List<MailInfo> mailInfoList = new ArrayList<>();
+
+        List<String> sqlList = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        for (int i = messages.length - 1; i >= 0; i--) {
+
+            // 邮件
+            IMAPMessage message = (IMAPMessage) messages[i];
+
+            // 邮件接收时间
+            Date receivedDate = message.getReceivedDate();
+
+            // 邮件信息
+            MailInfo mailInfo = new MailInfo();
+            mailInfo.setUid(folder.getUID(message));
+            mailInfo.setSubject(message.getSubject());
+            mailInfo.setSendDate(message.getSentDate());
+            mailInfo.setReceivedDate(receivedDate);
+
+            // 保存发件人信息
+            InternetAddress sender = (InternetAddress) message.getSender();
+            if (sender != null) {
+                mailInfo.setFromEmail(sender.getAddress());
+                mailInfo.setFromPersonalName(sender.getPersonal());
+            } else {
+                Address[] from = message.getFrom();
+                if (ObjectUtil.isNotEmpty(from)) {
+                    InternetAddress formItem = (InternetAddress) from[0];
+                    mailInfo.setFromEmail(formItem.getAddress());
+                    mailInfo.setFromPersonalName(formItem.getPersonal());
+                }
+            }
+
+            // 添加到邮件列表
+            mailInfoList.add(0, mailInfo);
+
+            String name = mailFolder.getName().replace("'", "\\'").replace("\r", "\\r").replace("\n", "\\n");
+            String subject = mailInfo.getSubject().replace("'", "\\'").replace("\r", "\\r").replace("\n", "\\n");
+            String fromEmail = mailInfo.getFromEmail().replace("'", "\\'").replace("\r", "\\r").replace("\n", "\\n");
+            String fromPersonalName = mailInfo.getFromPersonalName().replace("'", "\\'").replace("\r", "\\r").replace("\n", "\\n");
+
+            String sql = String.format("insert ignore into enterprise_message(uid,mailbox_id,folder_id,folder_name,subject,from_email,from_personal_name,send_date,received_date,sync_status,del_flag)" +
+                            "values(%s,%s,%s,'%s','%s','%s','%s','%s','%s',0,0);", mailInfo.getUid(), mailboxInfo.getId(), mailFolder.getId(), name, subject
+                    , fromEmail, fromPersonalName, sdf.format(mailInfo.getSendDate()), sdf.format(mailInfo.getReceivedDate()));
+            sqlList.add(sql);
+            log.info(String.format("邮箱%s(%s)还剩%s条邮件未拉取", mailboxInfo.getMailUser(), mailboxInfo.getId(), i));
+
+        }
+        String data = sqlList.stream().collect(Collectors.joining("\r\n"));
+        FileUtils.writeStringToFile(new File("C:\\Users\\ASUS\\Desktop\\邮件数据拉取\\" + mailboxInfo.getId() + "_" + mailboxInfo.getMailUser() + ".sql"), data, "UTF-8");
+
+        return mailInfoList;
+    }
+
+
+}