But, today they pointed out that emails from our web site are all getting dumped into the same case. We have a link like this on our web site:
The result is we get numerous emails with this same subject line; and my email to case handler puts them all into the same case. Not what we want!
What to do? Answer: have a list of commonly expected subject lines.
Where to put this list? In the code? No! Answer: Salesforce Custom Settings
I don't know about others but I found the documentation hard to understand:
http://www.salesforce.com/us/developer/docs/apexcode/index.htm
https://help.salesforce.com/apex/htviewhelpdoc?id=cs_add_data.htm&language=en
I found this blog more useful:
http://cloudnow.wordpress.com/2011/04/20/custom-settings-how-and-why/
But I'm still not sure about how best to use Custom Settings. Yet, I did get them to work for this common subject line problem.
As per documentation;
- create a new Custom Setting object called EmailToCase__c
- create a field in this object called CommonSubjects__c
- click Manage on the object
- click New (this was the weird part. What do you do?) The edit screen has two inputs "Name" and "CommonSubjects". Eventually I realized this is Name and Value. I entered: Name = WebContactUsForm Value = CommonSubjects: Inquiry from link on Carmanah Technologies web site
- Repeat step 4 for any other common subjects.
The EmailToCase__c object now has a text field. To skip common subject lines we iterate over all EmailToCase__c objects and test the incoming subject line to one of the settings.
In the CaseEmailInBoundUtilities class' processInboundEmail method insert the following code just before searching for matching subject lines:
In the CaseEmailInBoundUtilities class' processInboundEmail method insert the following code just before searching for matching subject lines:
// try to match subject String mainSubject = extractMainSubject(email.subject); if(mainSubject!=null) { Boolean proceedToTestForMatch = true; MapeToCaseSettings = EmailToCase__c.getAll(); List subjectLines = new List (); subjectLines.addAll(eToCaseSettings.keySet()); for (String key : subjectLines) { EmailToCase__c eToC = eToCaseSettings.get(key); if(eToC.CommonSubjects__c.equals(mainSubject)) { System.debug('Matched common subject line. Name: ' +eToC.Name + ' Subject: '+ eToC.CommonSubjects__c ); proceedToTestForMatch = false; } } if(proceedToTestForMatch .... continue to rest of method that searches for Cases with matching subject line.
For the record here is the complete method
public Messaging.InboundEmailResult processInboundEmail(Messaging.InboundEmail email) { Messaging.InboundEmailResult result = new Messaging.InboundEmailresult(); result.success = true; this.inboundEmail = email; String caseNumber = extractRef(email.subject); if(caseNumber != null) { if(TRACE)system.debug(Logginglevel.ERROR,'CaseEmailInBoundUtilities. extracted case number: "' + caseNumber + '"'); this.theCase = locateByCaseNumberAsString(caseNumber); if(this.theCase == null) { // TODO email error message to SysAdmin system.debug(Logginglevel.ERROR,'CaseEmailInBoundUtilities. Create a new case. Could not find case number: "' + caseNumber + '"'); } } else { // try to match subject String mainSubject = extractMainSubject(email.subject); if(mainSubject!=null) { Boolean proceedToTestForMatch = true; MapeToCaseSettings = EmailToCase__c.getAll(); List subjectLines = new List (); subjectLines.addAll(eToCaseSettings.keySet()); for (String key : subjectLines) { EmailToCase__c eToC = eToCaseSettings.get(key); if(eToC.CommonSubjects__c.equals(mainSubject)) { System.debug('Matched common subject line. Name: ' +eToC.Name + ' Subject: '+ eToC.CommonSubjects__c ); proceedToTestForMatch = false; } } // Only try to match non-trivial subject lines. Otherwise too many different issues can me merged into one case. if(proceedToTestForMatch && mainSubject.length() > 15) { // Only match subjects on cases Created in the last 5 days. Case[] matchingCases = [Select Id, CaseNumber, Subject, Description from Case where Subject = :mainSubject and CreatedDate = LAST_N_DAYS:5]; if(matchingCases.size() == 1) { this.theCase = matchingCases[0]; } else { system.debug(Logginglevel.ERROR,'CaseEmailInBoundUtilities. Create a new case because we found '+matchingCases.size() + ' cases with the subject: "' + mainSubject + '"'); } } } } if(this.theCase == null) { // else create a new Case this.theCase = new Case(); theCase.SuppliedEmail = email.fromAddress; theCase.SuppliedName = email.fromName; theCase.Status = 'New'; theCase.Priority = 'Low'; theCase.OwnerId = this.defaultCaseOwnerId; theCase.Origin = 'Email'; String extractedSubject = extractMainSubject(email.subject); theCase.Subject = extractedSubject; theCase.Description = email.plainTextBody; Contact[] contacts = [SELECT Id, Name, AccountId, Email FROM Contact WHERE Email = :email.fromAddress]; if(contacts.size() >0) { Contact theContact = contacts[0]; theCase.ContactId = theContact.Id; theCase.AccountId = theContact.AccountId; if(contacts.size() > 1) { // Could-Should create a new Case here to get CS to resolve this.... theCase.Description = 'Note: there is more than on Contact with this email address. Fix this. ' + theCase.Description; } } insertSObject(this.theCase); } createEmailMessage(theCase,email); handleAttachments(theCase, email); return result; }
Hey Bryan, I think your post on the inbound email handler code is pretty awesome. I've made some adjustments to things, but was running into a similar issue where the inbound emails were being added to the same case. Basically, everyone sending an inbound email is using a template in Outlook, so the email subjects are identical. I was trying to amend my inbound email handler with the above code and was running into unexpected token issues. I'm not a coder by any means and much more of a button-click admin, but I am trying to learn some code. Anyways, I think either your code is outdated for the new API or there are errors in it. I was updating it and ran into the unexpected token "subjectLines.addAll" I had alread updated the first part of the code as below.
ReplyDeleteMap eToCaseSettings = EmailToCase__c.getAll();
List subjectLines = new List
subjectLines.addAll(eToCaseSettings.keySet());
for (String key : subjectLines) {
EmailToCase__c eToC = eToCaseSettings.get(key);
if(eToC.CommonSubjects__c.equals(mainSubject)) {
System.debug('Matched common subject line. Name: ' +eToC.Name + ' Subject: '+ eToC.CommonSubjects__c );
proceedToTestForMatch = false;
}
}
Can you let me know why is wrong with the code in regards to the Keyset line? I'm assuming that the code below might need to be updated as well, I was just adjusting things from the top down until it reached an error. Correct me if I'm wrong, but I had changed the first two lines after reading some documentation and it seems that this is how the lines should be.
Thanks for the feedback. I think the line "List subjectLines = new List" needs to be "List subjectLines = new List()". Note the ().
Delete