Rev 16335 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/****/package in.shop2020.util;import in.shop2020.crm.Activity;import in.shop2020.crm.ActivityType;import in.shop2020.crm.CRMService.Client;import in.shop2020.crm.SearchFilter;import in.shop2020.crm.Ticket;import in.shop2020.crm.TicketCategory;import in.shop2020.crm.TicketPriority;import in.shop2020.crm.TicketStatus;import in.shop2020.model.v1.user.User;import in.shop2020.model.v1.user.UserContextException;import in.shop2020.serving.auth.CRMAuthorizingRealm;import in.shop2020.thrift.clients.CRMClient;import in.shop2020.thrift.clients.UserClient;import in.shop2020.util.CRMConstants;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.text.ParseException;import java.util.ArrayList;import java.util.Arrays;import java.util.Calendar;import java.util.Date;import java.util.GregorianCalendar;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.mail.Address;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.Message.RecipientType;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Part;import net.htmlparser.jericho.Source;import org.apache.commons.lang.xwork.StringUtils;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.thrift.TException;import org.apache.thrift.transport.TTransportException;/*** @author mandeep**/public class CRMEmailProcessor {private static final int DESCRIPTION_MAX_WIDTH = 1900;private static final String MAILOR_DAEMON_EMAIL_ID = "mailer-daemon@googlemail.com";private static final Log log = LogFactory.getLog(CRMEmailProcessor.class);private Client client;private String emailType="";public void processEmail(Message message) throws Exception {// Ignoring mails from Mailor daemonif (MAILOR_DAEMON_EMAIL_ID.equals(parseEmailId(message.getFrom()[0].toString()))) {return;}// Try parsing the ticket Id from email with subject like Saholic#123 ...Long ticketId = parseTicketId(message);if (ticketId != null) {log.info("Response for Ticket: " + ticketId + ": " + message);updateTicket(ticketId, message);} else {log.info("Mail not recognized as CRM ticket response with subject: "+ message.getSubject());log.info("Creating ticket for the same");createTicket(message);}}// Parses regex like ^.*Saholic#(\d+).*private Long parseTicketId(Message message) throws MessagingException, IOException {String subject = message.getSubject();if (subject == null) {return null;}else if (subject.contains("Undelivered Mail")) {return extractTicketId(convertMessageToText(message));}else {return extractTicketId(subject);}}private Long extractTicketId (String stringToSearch){Pattern p = Pattern.compile("(?s).*"+ CRMConstants.CRM_SUBJECT_PREFIX_FOR_TICKET_ID+ "(\\d+).*$");Matcher m = p.matcher(stringToSearch);if (m.matches()) {return Long.parseLong(m.group(1));} else{p = Pattern.compile("(?s).*"+ CRMConstants.PROFIT_MANDI_SUBJECT_PREFIX_FOR_TICKET_ID+ "(\\d+).*$");m = p.matcher(stringToSearch);if(m.matches()) {return Long.parseLong(m.group(1));}}return null;}public Date getLastProcessedTimestamp() throws ParseException, TException {client = new CRMClient().getClient();return new Date(client.getLastEmailProcessedTimestamp());}public void updateLastProcessedTimestamp(Date date) throws TException {client = new CRMClient().getClient();client.updateLastEmailProcessedTimestamp(date.getTime());}private void updateTicket(Long ticketId, Message message) throws Exception {try {SearchFilter searchFilter = new SearchFilter();searchFilter.setTicketId(ticketId);client = new CRMClient().getClient();List<Ticket> tickets = client.getTickets(searchFilter);if (tickets == null || tickets.isEmpty()) {log.error("Invalid TicketId: " + ticketId);log.error("Not processing message with subject: " + message.getSubject());return;}Ticket ticket = tickets.get(0);Activity activity = new Activity();activity.setTicketId(ticketId);activity.setTicketAssigneeId(ticket.getAssigneeId());activity.setTicketCategory(ticket.getCategory());activity.setTicketDescription(ticket.getDescription());activity.setTicketPriority(ticket.getPriority());activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);activity.setIsRead(false);if (ticket.isSetCustomerId()) {activity.setCustomerId(ticket.getCustomerId());}activity.setAttachments(getAttachment(message));activity.setDescription(convertMessageToText(message));if (TicketStatus.CLOSED.equals(ticket.getStatus())) {ticket.setStatus(TicketStatus.REOPEN);if(CRMAuthorizingRealm.getAgent(ticket.getAssigneeId()) == null){ticket.setAssigneeId(1);activity.setTicketAssigneeId(1);}}activity.setTicketStatus(ticket.getStatus());client = new CRMClient().getClient();client.updateTicket(ticket, activity);} catch (Exception e) {log.error("Could not update ticket " + ticketId + " with mail "+ message, e);throw e;}}private void createTicket(Message message) throws MessagingException,IOException, TException, UserContextException {String description = convertMessageToText(message);Ticket ticket = new Ticket();ticket.setCreatorId(CRMConstants.ADMIN_AGENT_ID);Address[] recipients = message.getRecipients(RecipientType.TO);List<String> emailToIds = new ArrayList<String>();for(Address address: recipients){emailToIds.add(address.toString());}if (getEmailType().equalsIgnoreCase("BulkEmail")){ticket.setCategory(TicketCategory.Bulk_Order_ENQUIRY);}else{if(emailToIds.contains("help@profitmandi.com")){ticket.setCategory(TicketCategory.PROFITMANDI_OTHER);} else {ticket.setCategory(TicketCategory.OTHER);}}String customerEmailId = parseEmailId(message.getFrom()[0].toString());in.shop2020.model.v1.user.UserContextService.Client userClient = new UserClient().getClient();User user = userClient.getUserByEmail(customerEmailId);if (user == null || user.getUserId() == -1) {ticket.setCustomerEmailId(customerEmailId);} else {ticket.setCustomerId(user.getUserId());}if(emailToIds.contains("help@profitmandi.com")){ticket.setCustomerEmailId(customerEmailId);if(user != null && user.getUserId() != -1)ticket.setCustomerId(user.getUserId());}ticket.setDescription(description);ticket.setPriority(TicketPriority.MEDIUM);ticket.setStatus(TicketStatus.OPEN);log.info("Creating activity!");Activity activity = new Activity();activity.setDescription(description);activity.setAttachments(getAttachment(message));activity.setTicketCategory(ticket.getCategory());activity.setTicketDescription(ticket.getDescription());activity.setTicketPriority(ticket.getPriority());activity.setTicketStatus(ticket.getStatus());activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);if(emailToIds.contains("help@profitmandi.com")){activity.setTicketAssigneeId(34);}activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);activity.setIsRead(false);client = new CRMClient().getClient();client.insertTicket(ticket, activity);}// parsing email Id from strings like// "Pankaj Jain <ponkoj@hotmail.com>"private String parseEmailId(String address) {Pattern p = Pattern.compile("^.*<(.+)>.*$");Matcher m = p.matcher(address);if (m.matches()) {address = m.group(1);}return address;}private String convertMessageToText(Message message)throws MessagingException, IOException {String messageContent = getText(message);String content = "From: " + message.getFrom()[0].toString()+ "\n\nSubject: " + message.getSubject() + "\n\nBody: "+ messageContent;if (content.length() > CRMConstants.DESCRIPTION_MAX_WIDTH) {content = content.substring(0, CRMConstants.DESCRIPTION_MAX_WIDTH);content += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";}return content;}/*** Return the primary text content of the message.*/private String getText(Part p) throws MessagingException, IOException {if (p.isMimeType("text/*")) {String s = (String) p.getContent();if (p.isMimeType("text/html")) {return new Source(s).getTextExtractor().toString();}else {return s;}}if (p.isMimeType("multipart/alternative")) {// prefer plain text over html textMultipart mp = (Multipart) p.getContent();String text = null;for (int i = 0; i < mp.getCount(); i++) {Part bp = mp.getBodyPart(i);if (bp.isMimeType("text/html")) {if (text == null)text = getText(bp);continue;} else if (bp.isMimeType("text/plain")) {String s = getText(bp);if (s != null)return s;} else {return getText(bp);}}return text;} else if (p.isMimeType("multipart/*")) {Multipart mp = (Multipart) p.getContent();for (int i = 0; i < mp.getCount(); i++) {String s = getText(mp.getBodyPart(i));if (s != null)return s;}}return null;}private String getAttachment(Part p) throws MessagingException, IOException {String listOfFiles = "";if (p.isMimeType("multipart/*")) {Multipart multipart = (Multipart) p.getContent();for (int x = 0; x < multipart.getCount(); x++) {BodyPart bodyPart = multipart.getBodyPart(x);if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {continue; // we want attachments only}String fileName = bodyPart.getFileName();fileName = fileName+"_"+getTimeInMilliseconds();InputStream is = bodyPart.getInputStream();File f = new File(CRMConstants.ATTACHMENTS_ARCHIVE_DIR + fileName);FileOutputStream fos = new FileOutputStream(f);byte[] buf = new byte[4096];int bytesRead;while((bytesRead = is.read(buf)) != -1) {fos.write(buf, 0, bytesRead);}fos.close();listOfFiles += fileName + ";";if (listOfFiles.length() > DESCRIPTION_MAX_WIDTH) {listOfFiles = listOfFiles.substring(0, DESCRIPTION_MAX_WIDTH);listOfFiles += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";}//end of if}//end for loop}//end ifreturn listOfFiles.isEmpty() ? null : listOfFiles;}//end getAttachmentpublic String getTimeInMilliseconds(){Calendar cal=GregorianCalendar.getInstance();return String.valueOf(cal.getTimeInMillis());}public void setEmailType(String emailType) {this.emailType = emailType;}public String getEmailType() {return emailType;}}//end Class