Subversion Repositories SmartDukaan

Rev

Rev 14898 | Rev 16348 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3339 mandeep.dh 1
/**
2
 * 
3
 */
4
package in.shop2020.util;
5
 
6
import in.shop2020.crm.Activity;
7
import in.shop2020.crm.ActivityType;
8
import in.shop2020.crm.CRMService.Client;
3390 mandeep.dh 9
import in.shop2020.crm.SearchFilter;
3339 mandeep.dh 10
import in.shop2020.crm.Ticket;
11
import in.shop2020.crm.TicketCategory;
12
import in.shop2020.crm.TicketPriority;
13
import in.shop2020.crm.TicketStatus;
14
import in.shop2020.model.v1.user.User;
15
import in.shop2020.model.v1.user.UserContextException;
4793 amar.kumar 16
import in.shop2020.serving.auth.CRMAuthorizingRealm;
3339 mandeep.dh 17
import in.shop2020.thrift.clients.CRMClient;
18
import in.shop2020.thrift.clients.UserClient;
4241 anupam.sin 19
import in.shop2020.util.CRMConstants;
20
import java.io.File;
21
import java.io.FileOutputStream;
3339 mandeep.dh 22
import java.io.IOException;
4241 anupam.sin 23
import java.io.InputStream;
3339 mandeep.dh 24
import java.text.ParseException;
14882 manish.sha 25
import java.util.ArrayList;
26
import java.util.Arrays;
11890 kshitij.so 27
import java.util.Calendar;
3339 mandeep.dh 28
import java.util.Date;
11890 kshitij.so 29
import java.util.GregorianCalendar;
3408 mandeep.dh 30
import java.util.List;
3339 mandeep.dh 31
import java.util.regex.Matcher;
32
import java.util.regex.Pattern;
33
 
14882 manish.sha 34
import javax.mail.Address;
4241 anupam.sin 35
import javax.mail.BodyPart;
3339 mandeep.dh 36
import javax.mail.Message;
14882 manish.sha 37
import javax.mail.Message.RecipientType;
3339 mandeep.dh 38
import javax.mail.MessagingException;
3368 mandeep.dh 39
import javax.mail.Multipart;
40
import javax.mail.Part;
3339 mandeep.dh 41
 
3546 mandeep.dh 42
import net.htmlparser.jericho.Source;
43
 
14882 manish.sha 44
import org.apache.commons.lang.xwork.StringUtils;
3339 mandeep.dh 45
import org.apache.commons.logging.Log;
46
import org.apache.commons.logging.LogFactory;
47
import org.apache.thrift.TException;
48
import org.apache.thrift.transport.TTransportException;
49
 
50
/**
51
 * @author mandeep
52
 * 
53
 */
54
public class CRMEmailProcessor {
4241 anupam.sin 55
    private static final int DESCRIPTION_MAX_WIDTH = 1900;
3369 mandeep.dh 56
    private static final String MAILOR_DAEMON_EMAIL_ID = "mailer-daemon@googlemail.com";
3339 mandeep.dh 57
    private static final Log log                   = LogFactory
11890 kshitij.so 58
    .getLog(CRMEmailProcessor.class);
3339 mandeep.dh 59
    private Client           client;
11890 kshitij.so 60
    private String emailType="";
3339 mandeep.dh 61
 
4854 anupam.sin 62
    public void processEmail(Message message) throws Exception {
3369 mandeep.dh 63
        // Ignoring mails from Mailor daemon
64
        if (MAILOR_DAEMON_EMAIL_ID.equals(parseEmailId(message.getFrom()[0].toString()))) {
65
            return;
66
        }
67
 
4142 mandeep.dh 68
        // Try parsing the ticket Id from email with subject like Saholic#123 ...
3339 mandeep.dh 69
        Long ticketId = parseTicketId(message);
70
 
71
        if (ticketId != null) {
72
            log.info("Response for Ticket: " + ticketId + ": " + message);
73
            updateTicket(ticketId, message);
74
        } else {
75
            log.info("Mail not recognized as CRM ticket response with subject: "
76
                    + message.getSubject());
77
            log.info("Creating ticket for the same");
78
            createTicket(message);
79
        }
80
    }
81
 
4142 mandeep.dh 82
    // Parses regex like ^.*Saholic#(\d+).*
4241 anupam.sin 83
    private Long parseTicketId(Message message) throws MessagingException, IOException {
3339 mandeep.dh 84
        String subject = message.getSubject();
4241 anupam.sin 85
        if (subject == null) {
86
            return null;
3339 mandeep.dh 87
        }
4241 anupam.sin 88
        else if (subject.contains("Undelivered Mail")) {
89
            return extractTicketId(convertMessageToText(message));
90
        }
91
        else {
92
            return extractTicketId(subject);
93
        }
3339 mandeep.dh 94
    }
11890 kshitij.so 95
 
4241 anupam.sin 96
    private Long extractTicketId (String stringToSearch){
97
        Pattern p = Pattern.compile("(?s).*"
98
                + CRMConstants.CRM_SUBJECT_PREFIX_FOR_TICKET_ID
99
                + "(\\d+).*$");
100
        Matcher m = p.matcher(stringToSearch);
101
        if (m.matches()) {
102
            return Long.parseLong(m.group(1));
14882 manish.sha 103
        } else{
104
        	p = Pattern.compile("(?s).*"
105
                    + CRMConstants.PROFIT_MANDI_SUBJECT_PREFIX_FOR_TICKET_ID
106
                    + "(\\d+).*$");
107
        	m = p.matcher(stringToSearch);
108
        	if(m.matches()) {
109
        		return Long.parseLong(m.group(1));
110
        	}
4241 anupam.sin 111
        }
112
        return null;
113
    }
3339 mandeep.dh 114
 
115
    public Date getLastProcessedTimestamp() throws ParseException, TException {
3373 mandeep.dh 116
        client = new CRMClient().getClient();
3339 mandeep.dh 117
        return new Date(client.getLastEmailProcessedTimestamp());
118
    }
119
 
120
    public void updateLastProcessedTimestamp(Date date) throws TException {
3340 mandeep.dh 121
        client = new CRMClient().getClient();
3339 mandeep.dh 122
        client.updateLastEmailProcessedTimestamp(date.getTime());
123
    }
124
 
4854 anupam.sin 125
    private void updateTicket(Long ticketId, Message message) throws Exception {
3339 mandeep.dh 126
        try {
3390 mandeep.dh 127
            SearchFilter searchFilter = new SearchFilter();
128
            searchFilter.setTicketId(ticketId);
3373 mandeep.dh 129
            client = new CRMClient().getClient();
3408 mandeep.dh 130
            List<Ticket> tickets = client.getTickets(searchFilter);
131
            if (tickets == null || tickets.isEmpty()) {
132
                log.error("Invalid TicketId: " + ticketId);
133
                log.error("Not processing message with subject: " + message.getSubject());
134
                return;
135
            }
136
 
137
            Ticket ticket = tickets.get(0);
3339 mandeep.dh 138
            Activity activity = new Activity();
139
            activity.setTicketId(ticketId);
140
            activity.setTicketAssigneeId(ticket.getAssigneeId());
141
            activity.setTicketCategory(ticket.getCategory());
142
            activity.setTicketDescription(ticket.getDescription());
143
            activity.setTicketPriority(ticket.getPriority());
144
            activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);
145
            activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
3398 mandeep.dh 146
            activity.setIsRead(false);
3339 mandeep.dh 147
 
148
            if (ticket.isSetCustomerId()) {
149
                activity.setCustomerId(ticket.getCustomerId());
150
            }
151
 
4241 anupam.sin 152
            activity.setAttachments(getAttachment(message));
3339 mandeep.dh 153
            activity.setDescription(convertMessageToText(message));
3368 mandeep.dh 154
 
155
            if (TicketStatus.CLOSED.equals(ticket.getStatus())) {
156
                ticket.setStatus(TicketStatus.REOPEN);
4793 amar.kumar 157
                if(CRMAuthorizingRealm.getAgent(ticket.getAssigneeId()) == null){
11890 kshitij.so 158
                    ticket.setAssigneeId(1);
159
                    activity.setTicketAssigneeId(1);
4793 amar.kumar 160
                }
11890 kshitij.so 161
 
3368 mandeep.dh 162
            }
163
 
4196 mandeep.dh 164
            activity.setTicketStatus(ticket.getStatus());
165
 
3373 mandeep.dh 166
            client = new CRMClient().getClient();
3339 mandeep.dh 167
            client.updateTicket(ticket, activity);
4854 anupam.sin 168
        } catch (Exception e) {
3339 mandeep.dh 169
            log.error("Could not update ticket " + ticketId + " with mail "
170
                    + message, e);
4854 anupam.sin 171
            throw e;
3339 mandeep.dh 172
        }
173
    }
174
 
175
    private void createTicket(Message message) throws MessagingException,
11890 kshitij.so 176
    IOException, TException, UserContextException {
3339 mandeep.dh 177
        String description = convertMessageToText(message);
178
        Ticket ticket = new Ticket();
179
        ticket.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
14882 manish.sha 180
 
181
        Address[] recipients = message.getRecipients(RecipientType.TO);
182
    	List<String> emailToIds = new ArrayList<String>();
183
    	for(Address address: recipients){
184
    		emailToIds.add(address.toString());
185
    	}        
11890 kshitij.so 186
        if (getEmailType().equalsIgnoreCase("BulkEmail")){
187
            ticket.setCategory(TicketCategory.Bulk_Order_ENQUIRY);
188
        }
189
        else{
14882 manish.sha 190
        	if(emailToIds.contains("help@profitmandi.com")){
191
        		ticket.setCategory(TicketCategory.PROFITMANDI_OTHER);
16335 manish.sha 192
        		ticket.setAssigneeId(0);
14882 manish.sha 193
        	} else {
194
        		ticket.setCategory(TicketCategory.OTHER);
195
        	}
11890 kshitij.so 196
        }
3339 mandeep.dh 197
        String customerEmailId = parseEmailId(message.getFrom()[0].toString());
198
 
199
        in.shop2020.model.v1.user.UserContextService.Client userClient = new UserClient()
11890 kshitij.so 200
        .getClient();
3339 mandeep.dh 201
        User user = userClient.getUserByEmail(customerEmailId);
202
 
203
        if (user == null || user.getUserId() == -1) {
204
            ticket.setCustomerEmailId(customerEmailId);
205
        } else {
206
            ticket.setCustomerId(user.getUserId());
207
        }
208
 
14882 manish.sha 209
        if(emailToIds.contains("help@profitmandi.com")){
210
        	ticket.setCustomerEmailId(customerEmailId);
211
        	if(user != null && user.getUserId() != -1)
212
        		ticket.setCustomerId(user.getUserId());
213
        }
3339 mandeep.dh 214
        ticket.setDescription(description);
215
        ticket.setPriority(TicketPriority.MEDIUM);
216
        ticket.setStatus(TicketStatus.OPEN);
217
 
218
        log.info("Creating activity!");
219
        Activity activity = new Activity();
220
        activity.setDescription(description);
4241 anupam.sin 221
        activity.setAttachments(getAttachment(message));
3339 mandeep.dh 222
        activity.setTicketCategory(ticket.getCategory());
223
        activity.setTicketDescription(ticket.getDescription());
224
        activity.setTicketPriority(ticket.getPriority());
225
        activity.setTicketStatus(ticket.getStatus());
226
        activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);
14898 manish.sha 227
        if(emailToIds.contains("help@profitmandi.com")){
228
        	activity.setTicketAssigneeId(34);
229
        }
3339 mandeep.dh 230
        activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
3398 mandeep.dh 231
        activity.setIsRead(false);
3339 mandeep.dh 232
 
3373 mandeep.dh 233
        client = new CRMClient().getClient();
3339 mandeep.dh 234
        client.insertTicket(ticket, activity);
235
    }
236
 
237
    // parsing email Id from strings like
3368 mandeep.dh 238
    // "Pankaj Jain <ponkoj@hotmail.com>"
3339 mandeep.dh 239
    private String parseEmailId(String address) {
240
        Pattern p = Pattern.compile("^.*<(.+)>.*$");
241
        Matcher m = p.matcher(address);
242
        if (m.matches()) {
243
            address = m.group(1);
244
        }
245
 
246
        return address;
247
    }
248
 
249
    private String convertMessageToText(Message message)
11890 kshitij.so 250
    throws MessagingException, IOException {
3368 mandeep.dh 251
        String messageContent = getText(message);
3339 mandeep.dh 252
 
3368 mandeep.dh 253
        String content = "From: " + message.getFrom()[0].toString()
11890 kshitij.so 254
        + "\n\nSubject: " + message.getSubject() + "\n\nBody: "
255
        + messageContent;
3339 mandeep.dh 256
 
4206 mandeep.dh 257
        if (content.length() > CRMConstants.DESCRIPTION_MAX_WIDTH) {
258
            content = content.substring(0, CRMConstants.DESCRIPTION_MAX_WIDTH);
3368 mandeep.dh 259
            content += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";
3339 mandeep.dh 260
        }
261
 
262
        return content;
263
    }
3368 mandeep.dh 264
 
265
    /**
266
     * Return the primary text content of the message.
267
     */
268
    private String getText(Part p) throws MessagingException, IOException {
269
        if (p.isMimeType("text/*")) {
270
            String s = (String) p.getContent();
3546 mandeep.dh 271
            if (p.isMimeType("text/html")) {
272
                return new Source(s).getTextExtractor().toString();
273
            }
274
            else {
275
                return s;
276
            }
3368 mandeep.dh 277
        }
278
 
279
        if (p.isMimeType("multipart/alternative")) {
280
            // prefer plain text over html text
281
            Multipart mp = (Multipart) p.getContent();
282
            String text = null;
283
            for (int i = 0; i < mp.getCount(); i++) {
284
                Part bp = mp.getBodyPart(i);
285
                if (bp.isMimeType("text/html")) {
286
                    if (text == null)
287
                        text = getText(bp);
288
                    continue;
289
                } else if (bp.isMimeType("text/plain")) {
290
                    String s = getText(bp);
291
                    if (s != null)
292
                        return s;
293
                } else {
294
                    return getText(bp);
295
                }
296
            }
297
            return text;
298
        } else if (p.isMimeType("multipart/*")) {
299
            Multipart mp = (Multipart) p.getContent();
300
            for (int i = 0; i < mp.getCount(); i++) {
301
                String s = getText(mp.getBodyPart(i));
302
                if (s != null)
303
                    return s;
304
            }
305
        }
306
 
307
        return null;
308
    }
4241 anupam.sin 309
 
310
    private String getAttachment(Part p) throws MessagingException, IOException {
311
        String listOfFiles = "";
312
 
313
        if (p.isMimeType("multipart/*")) {
314
            Multipart multipart = (Multipart) p.getContent();
315
            for (int x = 0; x < multipart.getCount(); x++) {
316
                BodyPart bodyPart = multipart.getBodyPart(x);
317
 
318
                if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
319
                    continue; // we want attachments only
320
                }
321
 
322
                String fileName = bodyPart.getFileName();
11890 kshitij.so 323
                fileName = fileName+"_"+getTimeInMilliseconds();
4241 anupam.sin 324
                InputStream is = bodyPart.getInputStream();
325
                File f = new File(CRMConstants.ATTACHMENTS_ARCHIVE_DIR + fileName);
326
                FileOutputStream fos = new FileOutputStream(f);
327
                byte[] buf = new byte[4096];
328
                int bytesRead;
329
 
330
                while((bytesRead = is.read(buf)) != -1) {
331
                    fos.write(buf, 0, bytesRead);
332
                }
333
 
334
                fos.close();
335
                listOfFiles += fileName + ";";
336
 
337
                if (listOfFiles.length() > DESCRIPTION_MAX_WIDTH) {
338
                    listOfFiles = listOfFiles.substring(0, DESCRIPTION_MAX_WIDTH);
339
                    listOfFiles += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";
340
                }//end of if
341
            }//end for loop
342
        }//end if
343
 
344
        return listOfFiles.isEmpty() ? null : listOfFiles;
345
    }//end getAttachment
11890 kshitij.so 346
 
347
    public String getTimeInMilliseconds(){
348
        Calendar cal=GregorianCalendar.getInstance();
349
        return String.valueOf(cal.getTimeInMillis());
350
    }
351
 
352
    public void setEmailType(String emailType) {
353
        this.emailType = emailType;
354
    }
355
 
356
    public String getEmailType() {
357
        return emailType;
358
    }
4241 anupam.sin 359
}//end Class