package com.yc.crm.schedule; import com.esotericsoftware.minlog.Log; import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; import com.yc.api.schedule.ScheduleUtils; import com.yc.crm.mail.entity.FoundationEntity; import com.yc.crm.mail.entity.T482102Entity; import com.yc.crm.mail.service.MailAccountIfc; import com.yc.crm.mail.service.MailServiceIfc; import com.yc.entity.AttachmentConfig; import com.yc.entity.DataSourceEntity; import com.yc.factory.FactoryBean; import com.yc.multiData.MultiDataSource; import com.yc.multiData.SpObserver; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.stereotype.Service; import javax.mail.*; import javax.mail.event.MessageCountEvent; import javax.mail.event.MessageCountListener; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; /** * 实时监听邮箱 */ @Slf4j @Service public class EmailSchedule implements ApplicationListener { @Autowired ThreadPoolTaskExecutor threadPoolExecutor; @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; @Autowired MailAccountIfc emailAccountIfc; @Autowired MailServiceIfc mailServiceIfc; @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { if (contextRefreshedEvent.getApplicationContext().getParent() == null) { return; } threadPoolTaskScheduler = (ThreadPoolTaskScheduler) FactoryBean.getBean("threadPoolTaskScheduler"); threadPoolExecutor = (ThreadPoolTaskExecutor) FactoryBean.getBean("threadPoolExecutor"); String isStartUpSchedule = AttachmentConfig.get("isStartUpSchedule");//只在设置了定时任务的服务器上运行 if ("1".equals(isStartUpSchedule)) { Map infoList = MultiDataSource.getDataSourceMaps(); for (Map.Entry entry : infoList.entrySet()) { DataSourceEntity dataSourceEntity = entry.getValue(); if (ScheduleUtils.isOnbusPlatform(dataSourceEntity) || dataSourceEntity.getDbId() == 1624) { //dbid=1624,巴士软件(佛山公司),不需要执行定时任务 continue; } // if (dataSourceEntity.getDbId() != 82) continue;//TODO 测试用 emailTask(dataSourceEntity); } } } private void emailTask(DataSourceEntity dataSourceEntity) { try { SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId()); List list = emailAccountIfc.getAccountList(); log.info(dataSourceEntity.getDbId()+"-加载邮箱数量:"+list.size()); for (T482102Entity t482102Entity : list) { threadPoolExecutor.execute(new checkEmailThread(t482102Entity,dataSourceEntity)); } } catch (Exception e) { System.out.println("取不到邮箱设置内容:dbid=" + dataSourceEntity.getDbId() + ":" + e.getMessage()); e.printStackTrace(); } finally { SpObserver.setDBtoInstance(); } } private class checkEmailThread implements Runnable { T482102Entity emailEntity; FoundationEntity foundation; DataSourceEntity dataSourceEntity; public checkEmailThread(T482102Entity t482102Entity, DataSourceEntity dataSourceEntity) { this.emailEntity = t482102Entity; this.dataSourceEntity = dataSourceEntity; foundation=new FoundationEntity(); foundation.setDbId(dataSourceEntity.getDbId()); foundation.setCompanyName(emailEntity.getCompanyName()); foundation.setCompanyId(emailEntity.getCompanyId()); foundation.setUserCode(emailEntity.getUserCode()); foundation.setUserName(emailEntity.getUserName()); } @Override public void run() { checkEmail(); } private void checkEmail() { try { String protocol = emailEntity.getReceiveProtocol().toLowerCase();//接收协议 imap pop3 String server = emailEntity.getReceiveHost();//"imap.qq.com"; Integer port = emailEntity.getReceivePort();//993 String user =emailEntity.getReceiveEmail();//邮箱 String pwd = emailEntity.getReceivePassword();//密码 Properties properties = new Properties(); properties.setProperty("mail.store.protocol", protocol); // IMAP over SSL if (protocol.contains("imap")) {//接收协议imap properties.setProperty("mail.imaps.host", server); properties.setProperty("mail.imaps.port", port + ""); } else if (protocol.contains("pop3")) {//接收协议pop3 properties.setProperty("mail.pop3.host", server); properties.setProperty("mail.pop3.port", port + ""); } else {//其他(再加) properties.setProperty("mail.imaps.host", server); properties.setProperty("mail.imaps.port", port + ""); } HashMap IAM = new HashMap(); //带上IMAP ID信息,由key和value组成,例如name,version,vendor,support-email等。 IAM.put("name", user); IAM.put("version", emailEntity.getDocVersion() + ""); IAM.put("vendor", emailEntity.getCompanyName()); IAM.put("support-email", emailEntity.getEmail()); //创建会话 Session session = Session.getInstance(properties, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user, pwd); } }); //存储对象 IMAPStore store = (IMAPStore) session.getStore(protocol);//imap协议或pop3协议类型(推荐你使用IMAP协议来存取服务器上的邮件。) //连接 store.connect(server, user, pwd); store.id(IAM);//163邮箱需要,不然会报:A3 NO SELECT Unsafe Login. Please contact kefu@188.com for help Folder folder = null; try { // 获得收件箱 folder = store.getFolder("INBOX"); // 以读写模式打开收件箱 folder.open(Folder.READ_WRITE); log.info(emailEntity.getEmail() + "已就绪接收新邮件...."); folder.addMessageCountListener(new MessageCountListener() { @Override public void messagesAdded(MessageCountEvent e) { //TODO 处理新邮件 try { SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId()); mailServiceIfc.setMailContent(e.getMessages(), emailEntity, foundation); }catch (Exception e1){ e1.printStackTrace(); }finally { SpObserver.setDBtoInstance(); } log.info(emailEntity.getEmail()+":Message Count Event Fired"); } @Override public void messagesRemoved(MessageCountEvent e) { // System.out.println(emailEntity.getEmail()+"Message Count Event Fired"); } }); /* folder.addMessageChangedListener(new MessageChangedListener() { @Override public void messageChanged(MessageChangedEvent e) { System.out.println(emailEntity.getEmail()+"Message Count Event Fired"); } });*/ // Check mail once in "freq" MILLIseconds int freq = 2000; boolean supportsIdle = false; try { if (folder instanceof IMAPFolder) { IMAPFolder f = (IMAPFolder) folder; f.idle(); supportsIdle = true; } } catch (FolderClosedException fex) { throw fex; } catch (MessagingException mex) { supportsIdle = false; } for (; ; ) { if (supportsIdle && folder instanceof IMAPFolder) { IMAPFolder f = (IMAPFolder) folder; f.idle(); // System.out.println(emailEntity.getEmail()+"IDLE done"); } else { Thread.sleep(freq); // sleep for freq milliseconds // This is to force the IMAP server to send us // EXISTS notifications. folder.getMessageCount(); } } } catch (FolderClosedException fe) { log.info("FolderClosedException......"); checkEmail(); } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (folder != null) { folder.close(false); } if (store != null) { store.close(); } } catch (MessagingException e) { throw e; } } }catch (Exception e){ e.printStackTrace(); } } } }