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;
Map 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;
}
}
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;
Map 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;
}
}
// 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