Tuesday, June 11, 2013

POP3 Email listener using Java Mail API in webMethods

webMethods provides an email port listener to retrieve emails from the inbox and execute a service with the email message contents. However for POP3, when the Integration Server picks up the message, it deletes the message from the email server. The below Java service would get emails from a POP3 Inbox and convert it to IData message structure with out deleting the messages from the Inbox.

// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String emailHostName = IDataUtil.getString( pipelineCursor, "emailHostName" );
final String userName = IDataUtil.getString( pipelineCursor, "userName" );
final String password = IDataUtil.getString( pipelineCursor, "password" );
String port = IDataUtil.getString( pipelineCursor, "port" );
pipelineCursor.destroy();
    
try {
   
 Properties props=new Properties(); 
 props.put("mail.pop3.host" , emailHostName);
 props.put("mail.pop3.user" , userName);
 // Start SSL connection
 props.put("mail.pop3.socketFactory" , port );
 props.put("mail.pop3.socketFactory.class" , "javax.net.ssl.SSLSocketFactory" );
 props.put("mail.pop3.port" , port);
     
 Session session=Session.getInstance(props,new Authenticator() {
           @Override
    protected PasswordAuthentication getPasswordAuthentication() {
                  return new PasswordAuthentication( userName , password);
    }
  });
   
 Store store=session.getStore("pop3");
 store.connect(userName, password);
  
 Folder inbox=store.getFolder("INBOX");
 if (inbox == null) {
          System.out.println("No INBOX");
   System.exit(1);
 }
    
 //inbox.open(Folder.READ_ONLY);
 inbox.open(Folder.READ_WRITE);    
 Flags seen = new Flags(Flags.Flag.SEEN);
 FlagTerm unseenFlagTerm = new FlagTerm(seen, false);    
   
 Message[] messages = inbox.search(unseenFlagTerm);
  
 IDataUtil.put( pipelineCursor, "InboxLength", messages.length);
 ArrayList<IData> outputDoc=new ArrayList<IData>();
    
 for(int i=0;i<messages.length;i++){
         Message aMessage=messages[i];
  Object messagecontentObject= aMessage.getContent();
  
  String textMessage = null;     
  String messageUID=extractMessageID(aMessage);
  IData emailMessageResults = IDataFactory.create();
  IDataCursor emailMessageResultsCursor = emailMessageResults.getCursor();
   
  if (messagecontentObject instanceof Multipart){
             //Found Email with Attachment Retrieve the Multipart object from the message
  IDataUtil.put( emailMessageResultsCursor, "messageUID", messageUID );
  IDataUtil.put( emailMessageResultsCursor, "senderEmailAddress", new String(aMessage.getFrom()[0].toString()));
  IDataUtil.put( emailMessageResultsCursor, "subject", aMessage.getSubject());
  Multipart multipart= (Multipart) aMessage.getContent();
  ArrayList<IData> attachmentsInfoList=new ArrayList<IData>();
      
  // Loop over the parts of the email
  for (int partsCount = 0; partsCount < multipart.getCount(); partsCount++){
           BodyPart part = multipart.getBodyPart(partsCount);
       
   IData attachmentsResults=IDataFactory.create();
   IDataCursor attachmentsResultsCursor=attachmentsResults.getCursor();
       
   if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {  
   String attachmentName=null;
        if(part.getFileName()!=null){
         attachmentName = part.getFileName(); 
         
         InputStream attachmentInputStream = part.getInputStream();         
         
         //Convert the input stream from Attachment to byte[].
         ByteArrayOutputStream buffer = new ByteArrayOutputStream();         
         int nRead;
         byte[] data = new byte[16384];
         while ((nRead = attachmentInputStream.read(data, 0, data.length)) != -1) {
           buffer.write(data, 0, nRead);
           data=buffer.toByteArray();
         }
         buffer.flush();         
         
         //convert the byte[] to a base64 string.
         byte[] x=org.apache.commons.codec.binary.Base64.encodeBase64(data);
         String fileData=new String(x);
         
         String fileType=part.getContentType();         
         int fileTypeEndPos=fileType.indexOf(";");
         fileType=fileType.substring(0,fileTypeEndPos);
         
         //Populate the attachments results doc.
         IDataUtil.put( attachmentsResultsCursor, "fileName", attachmentName );
         IDataUtil.put( attachmentsResultsCursor, "fileData", fileData);
         IDataUtil.put( attachmentsResultsCursor, "fileType", fileType);
         attachmentsResultsCursor.destroy();
         attachmentsInfoList.add(attachmentsResults); 
        }
        else{
         // Unidentified attachment content type, get the part as an input byte array.
         Reader r = new InputStreamReader((InputStream) part.getContent());
         StringWriter sw = new StringWriter();
         char[] buffer = new char[1024];
         for (int n; (n = r.read(buffer)) != -1; )  
             sw.write(buffer, 0, n);
         textMessage= sw.toString();
  
         IDataUtil.put( attachmentsResultsCursor, "fileName", "No Name for attachment - Could be an attached email");
         IDataUtil.put( attachmentsResultsCursor, "fileData", textMessage);         
         attachmentsResultsCursor.destroy();
         attachmentsInfoList.add(attachmentsResults); 
        }
        
                      } else {
                       
                       //Extract inline images or other attachments                       
                       if((!part.getContentType().contains("text/html"))){
                          String attachmentName = part.getFileName();
           InputStream attachmentInputStream = part.getInputStream();         
           
           //Convert the input stream from Attachment to byte[].
           ByteArrayOutputStream buffer = new ByteArrayOutputStream();         
           int nRead;
           byte[] data = new byte[16384];
           while ((nRead = attachmentInputStream.read(data, 0, data.length)) != -1) {
             buffer.write(data, 0, nRead);
             data=buffer.toByteArray();
           }
           buffer.flush();         
           
           //convert the byte[] to a base64 string.
           byte[] x=org.apache.commons.codec.binary.Base64.encodeBase64(data);
           String fileData=new String(x);
           String fileType=part.getContentType();         
           int fileTypeEndPos=fileType.indexOf(";");
           fileType=fileType.substring(0,fileTypeEndPos);
           
           //Populate the attachments results doc.
           IDataUtil.put( attachmentsResultsCursor, "fileName", attachmentName );
           IDataUtil.put( attachmentsResultsCursor, "fileData", fileData);
           IDataUtil.put( attachmentsResultsCursor, "fileType", fileType);
           attachmentsResultsCursor.destroy();
           attachmentsInfoList.add(attachmentsResults); 
                        }
                       
                       //Handle email body for inline attachments.
                       else if( part.getContentType().contains("multipart/related")){
                        InputStreamReader is = new InputStreamReader(part.getInputStream());
          StringBuilder sb=new StringBuilder();
          BufferedReader br = new BufferedReader(is);
          String read = br.readLine();
    
          while(read != null) {
              sb.append(read);
              read =br.readLine();  
          }
          
          String unmodifiedBody=sb.toString();
          
          int htmlTagStartPos=unmodifiedBody.indexOf("<html");
          int htmlTagEndPos=unmodifiedBody.indexOf("</html>")+7;        
          String modifiedEmailBody=unmodifiedBody.substring(htmlTagStartPos,htmlTagEndPos);
          
          IDataUtil.put( emailMessageResultsCursor, "body", modifiedEmailBody);
                       }
                       // Extract email body for mails with attachment files. 
                       else{
                        textMessage = part.getContent() != null ? part.getContent().toString() : "";
                           IDataUtil.put( emailMessageResultsCursor, "body", textMessage);
                       }                                                                                 
                      }
      }
       IDataUtil.put( emailMessageResultsCursor, "emailSentDate", formatDateTime(aMessage.getSentDate()));
       IDataUtil.put( emailMessageResultsCursor, "attachmentExists", "Y" );
       IDataUtil.put( emailMessageResultsCursor, "attachmentInfo", attachmentsInfoList.toArray(new IData[attachmentsInfoList.size()]));
       outputDoc.add(emailMessageResults);      
      }
      else{
          // Email with no attachment.
         textMessage = aMessage.getContent() != null ? aMessage.getContent().toString() : "";
         IDataUtil.put( emailMessageResultsCursor, "messageUID", messageUID );
                  IDataUtil.put( emailMessageResultsCursor, "senderEmailAddress", new String(aMessage.getFrom()[0].toString()));
                  IDataUtil.put( emailMessageResultsCursor, "subject", aMessage.getSubject());
                  textMessage=aMessage.getContent().toString();
                  IDataUtil.put( emailMessageResultsCursor, "body", textMessage);
                  IDataUtil.put( emailMessageResultsCursor, "emailSentDate", formatDateTime(aMessage.getSentDate()));
                  IDataUtil.put( emailMessageResultsCursor, "attachmentExists", "N" );
   
                  IData attachmentsResults=IDataFactory.create();
                  IDataCursor attachmentsResultsCursor=attachmentsResults.getCursor();
                  IDataUtil.put( attachmentsResultsCursor, "fileName", "");
                  IDataUtil.put( attachmentsResultsCursor, "fileData", "");
                  IDataUtil.put( attachmentsResultsCursor, "fileType", "");
                  attachmentsResultsCursor.destroy();
                  
                  IDataUtil.put(emailMessageResultsCursor, "attachmentInfo", attachmentsResults);
        
                  outputDoc.add(emailMessageResults);
      }
      aMessage.setFlag(Flags.Flag.SEEN, true); // This is not supported for POP3.
    }
    inbox.close(false);
    store.close();    
    IDataUtil.put( pipelineCursor, "messageContents", outputDoc.toArray(new IData[outputDoc.size()]));    
  } catch (NoSuchProviderException e) {
   IDataUtil.put( pipelineCursor, "errrorMessage", e.toString() );
  } catch (MessagingException e) {
   IDataUtil.put( pipelineCursor, "errrorMessage", e.toString() );
  } catch (IOException e) {
   IDataUtil.put( pipelineCursor, "errrorMessage", e.toString() );
  }


Shared Code:
         private static String formatDateTime(Date date){
  
  String format="MM-dd-yyyy HH:mm:ss";  
  SimpleDateFormat sdf=new SimpleDateFormat(format);
  return sdf.format(date);
  }
  
  private static String extractMessageID(Message aMessage) throws MessagingException{
  
   // Extract message ID in proper format from the message.
   String messageUID=null;
   Enumeration headers = aMessage.getAllHeaders();                  
      while (headers.hasMoreElements()) {
          Header h = (Header) headers.nextElement();                                  
          String mID = h.getName();                
          if(mID.contains("Message-ID")){
           messageUID=h.getValue();                       
          }
      }
   
   int messageUIDLength=messageUID.length();   
   messageUID=messageUID.substring(1, messageUIDLength-1);   
   int specialCharPos=messageUID.indexOf("@");   
   messageUID=messageUID.substring(0, specialCharPos);   
   return messageUID;
  } 

No comments:

Post a Comment