Subversion Repositories SmartDukaan

Rev

Rev 4142 | Rev 4206 | 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;
16
import in.shop2020.thrift.clients.CRMClient;
17
import in.shop2020.thrift.clients.UserClient;
18
 
19
import java.io.IOException;
20
import java.text.ParseException;
21
import java.util.Date;
3408 mandeep.dh 22
import java.util.List;
3339 mandeep.dh 23
import java.util.regex.Matcher;
24
import java.util.regex.Pattern;
25
 
26
import javax.mail.Message;
27
import javax.mail.MessagingException;
3368 mandeep.dh 28
import javax.mail.Multipart;
29
import javax.mail.Part;
3339 mandeep.dh 30
 
3546 mandeep.dh 31
import net.htmlparser.jericho.Source;
32
 
3339 mandeep.dh 33
import org.apache.commons.logging.Log;
34
import org.apache.commons.logging.LogFactory;
35
import org.apache.thrift.TException;
36
import org.apache.thrift.transport.TTransportException;
37
 
38
/**
39
 * @author mandeep
40
 * 
41
 */
42
public class CRMEmailProcessor {
3368 mandeep.dh 43
    private static final int DESCRIPTION_MAX_WIDTH = 1900;
3369 mandeep.dh 44
    private static final String MAILOR_DAEMON_EMAIL_ID = "mailer-daemon@googlemail.com";
3339 mandeep.dh 45
    private static final Log log                   = LogFactory
46
                                                           .getLog(CRMEmailProcessor.class);
47
    private Client           client;
48
 
49
    public void processEmail(Message message) throws MessagingException,
50
            IOException, TException, UserContextException {
3369 mandeep.dh 51
        // Ignoring mails from Mailor daemon
52
        if (MAILOR_DAEMON_EMAIL_ID.equals(parseEmailId(message.getFrom()[0].toString()))) {
53
            return;
54
        }
55
 
4142 mandeep.dh 56
        // Try parsing the ticket Id from email with subject like Saholic#123 ...
3339 mandeep.dh 57
        Long ticketId = parseTicketId(message);
58
 
59
        if (ticketId != null) {
60
            log.info("Response for Ticket: " + ticketId + ": " + message);
61
            updateTicket(ticketId, message);
62
        } else {
63
            log.info("Mail not recognized as CRM ticket response with subject: "
64
                    + message.getSubject());
65
            log.info("Creating ticket for the same");
66
            createTicket(message);
67
        }
68
    }
69
 
4142 mandeep.dh 70
    // Parses regex like ^.*Saholic#(\d+).*
3339 mandeep.dh 71
    private Long parseTicketId(Message message) throws MessagingException {
72
        Long ticketId = null;
73
        String subject = message.getSubject();
74
        if (subject != null) {
75
            Pattern p = Pattern.compile("^.*"
76
                    + CRMConstants.CRM_SUBJECT_PREFIX_FOR_TICKET_ID
77
                    + "(\\d+).*$");
78
            Matcher m = p.matcher(subject);
79
            if (m.matches()) {
80
                ticketId = Long.parseLong(m.group(1));
81
            }
82
        }
83
 
84
        return ticketId;
85
    }
86
 
87
    public Date getLastProcessedTimestamp() throws ParseException, TException {
3373 mandeep.dh 88
        client = new CRMClient().getClient();
3339 mandeep.dh 89
        return new Date(client.getLastEmailProcessedTimestamp());
90
    }
91
 
92
    public void updateLastProcessedTimestamp(Date date) throws TException {
3340 mandeep.dh 93
        client = new CRMClient().getClient();
3339 mandeep.dh 94
        client.updateLastEmailProcessedTimestamp(date.getTime());
95
    }
96
 
97
    private void updateTicket(Long ticketId, Message message) {
98
        try {
3390 mandeep.dh 99
            SearchFilter searchFilter = new SearchFilter();
100
            searchFilter.setTicketId(ticketId);
3373 mandeep.dh 101
            client = new CRMClient().getClient();
3408 mandeep.dh 102
            List<Ticket> tickets = client.getTickets(searchFilter);
103
            if (tickets == null || tickets.isEmpty()) {
104
                log.error("Invalid TicketId: " + ticketId);
105
                log.error("Not processing message with subject: " + message.getSubject());
106
                return;
107
            }
108
 
109
            Ticket ticket = tickets.get(0);
3339 mandeep.dh 110
            Activity activity = new Activity();
111
            activity.setTicketId(ticketId);
112
            activity.setTicketAssigneeId(ticket.getAssigneeId());
113
            activity.setTicketCategory(ticket.getCategory());
114
            activity.setTicketDescription(ticket.getDescription());
115
            activity.setTicketPriority(ticket.getPriority());
116
            activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);
117
            activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
3398 mandeep.dh 118
            activity.setIsRead(false);
3339 mandeep.dh 119
 
120
            if (ticket.isSetCustomerId()) {
121
                activity.setCustomerId(ticket.getCustomerId());
122
            }
123
 
124
            activity.setDescription(convertMessageToText(message));
3368 mandeep.dh 125
 
126
            if (TicketStatus.CLOSED.equals(ticket.getStatus())) {
127
                ticket.setStatus(TicketStatus.REOPEN);
128
            }
129
 
4196 mandeep.dh 130
            activity.setTicketStatus(ticket.getStatus());
131
 
3373 mandeep.dh 132
            client = new CRMClient().getClient();
3339 mandeep.dh 133
            client.updateTicket(ticket, activity);
134
        } catch (TTransportException e) {
135
            log.error("Could not update ticket " + ticketId + " with mail "
136
                    + message, e);
137
        } catch (TException e) {
138
            log.error("Could not update ticket " + ticketId + " with mail "
139
                    + message, e);
140
        } catch (MessagingException e) {
141
            log.error("Could not update ticket " + ticketId + " with mail "
142
                    + message, e);
143
        } catch (IOException e) {
144
            log.error("Could not update ticket " + ticketId + " with mail "
145
                    + message, e);
146
        }
147
    }
148
 
149
    private void createTicket(Message message) throws MessagingException,
150
            IOException, TException, UserContextException {
151
        String description = convertMessageToText(message);
152
        Ticket ticket = new Ticket();
153
        ticket.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
154
        ticket.setCategory(TicketCategory.OTHER);
155
        String customerEmailId = parseEmailId(message.getFrom()[0].toString());
156
 
157
        in.shop2020.model.v1.user.UserContextService.Client userClient = new UserClient()
158
                .getClient();
159
        User user = userClient.getUserByEmail(customerEmailId);
160
 
161
        if (user == null || user.getUserId() == -1) {
162
            ticket.setCustomerEmailId(customerEmailId);
163
        } else {
164
            ticket.setCustomerId(user.getUserId());
165
        }
166
 
167
        ticket.setDescription(description);
168
        ticket.setPriority(TicketPriority.MEDIUM);
169
        ticket.setStatus(TicketStatus.OPEN);
170
 
171
        log.info("Creating activity!");
172
        Activity activity = new Activity();
173
        activity.setDescription(description);
174
        activity.setTicketCategory(ticket.getCategory());
175
        activity.setTicketDescription(ticket.getDescription());
176
        activity.setTicketPriority(ticket.getPriority());
177
        activity.setTicketStatus(ticket.getStatus());
178
        activity.setType(ActivityType.RECEIVED_EMAIL_FROM_CUSTOMER);
179
        activity.setCreatorId(CRMConstants.ADMIN_AGENT_ID);
3398 mandeep.dh 180
        activity.setIsRead(false);
3339 mandeep.dh 181
 
3373 mandeep.dh 182
        client = new CRMClient().getClient();
3339 mandeep.dh 183
        client.insertTicket(ticket, activity);
184
    }
185
 
186
    // parsing email Id from strings like
3368 mandeep.dh 187
    // "Pankaj Jain <ponkoj@hotmail.com>"
3339 mandeep.dh 188
    private String parseEmailId(String address) {
189
        Pattern p = Pattern.compile("^.*<(.+)>.*$");
190
        Matcher m = p.matcher(address);
191
        if (m.matches()) {
192
            address = m.group(1);
193
        }
194
 
195
        return address;
196
    }
197
 
198
    private String convertMessageToText(Message message)
199
            throws MessagingException, IOException {
3368 mandeep.dh 200
        String messageContent = getText(message);
3339 mandeep.dh 201
 
3368 mandeep.dh 202
        String content = "From: " + message.getFrom()[0].toString()
203
                + "\n\nSubject: " + message.getSubject() + "\n\nBody: "
204
                + messageContent;
3339 mandeep.dh 205
 
206
        if (content.length() > DESCRIPTION_MAX_WIDTH) {
207
            content = content.substring(0, DESCRIPTION_MAX_WIDTH);
3368 mandeep.dh 208
            content += "\n\nTHIS TEXT IS TRUNCATED. PLEASE VISIT INBOX TO SEE COMPLETE DETAILS.";
3339 mandeep.dh 209
        }
210
 
211
        return content;
212
    }
3368 mandeep.dh 213
 
214
    /**
215
     * Return the primary text content of the message.
216
     */
217
    private String getText(Part p) throws MessagingException, IOException {
218
        if (p.isMimeType("text/*")) {
219
            String s = (String) p.getContent();
3546 mandeep.dh 220
            if (p.isMimeType("text/html")) {
221
                return new Source(s).getTextExtractor().toString();
222
            }
223
            else {
224
                return s;
225
            }
3368 mandeep.dh 226
        }
227
 
228
        if (p.isMimeType("multipart/alternative")) {
229
            // prefer plain text over html text
230
            Multipart mp = (Multipart) p.getContent();
231
            String text = null;
232
            for (int i = 0; i < mp.getCount(); i++) {
233
                Part bp = mp.getBodyPart(i);
234
                if (bp.isMimeType("text/html")) {
235
                    if (text == null)
236
                        text = getText(bp);
237
                    continue;
238
                } else if (bp.isMimeType("text/plain")) {
239
                    String s = getText(bp);
240
                    if (s != null)
241
                        return s;
242
                } else {
243
                    return getText(bp);
244
                }
245
            }
246
            return text;
247
        } else if (p.isMimeType("multipart/*")) {
248
            Multipart mp = (Multipart) p.getContent();
249
            for (int i = 0; i < mp.getCount(); i++) {
250
                String s = getText(mp.getBodyPart(i));
251
                if (s != null)
252
                    return s;
253
            }
254
        }
255
 
256
        return null;
257
    }
3339 mandeep.dh 258
}