We've implemented a custom Apex Email Service to extend the standard Email-to-Case functionality, and one area we're struggling to do efficiently is figure out the CaseId when all that is known is the ThreadId:
E.g., [ ref:_00DC0PxQg._500C0KoOZS:ref ]
Currently, we are querying the EmailMessage object for subject's containing this same ThreadId, but that seems horribly inefficient. In fact Salesforce Support has reached out to us, stating:
While doing routine checkup,our R&D team has informed that running a SOQL that is consuming significant database resources resulting in slow response times from a user perspective.
However, after a number of emails, we are still without a solution (Ms. Cleo is MIA).
Inefficient Existing Code We'd Like to Improve:
private Id getCaseIdFromEmailSubject(String subject) {
String queryWhere = '%' + this.emailThreadTaskReferenceId(subject) + '%';
List<EmailMessage> emails = [SELECT ParentId, Subject FROM EmailMessage WHERE Subject like :queryWhere];
if(emails.size() > 0){
//trap for IDs that are the same case insensitive, but not case sensitive.
for (EmailMessage em : emails){
//.equals() method is case sensitive whereas == is not case sensitive
if (this.emailThreadTaskReferenceId(subject).equals(this.emailThreadTaskReferenceId(em.Subject))){
return em.ParentId;
}
}
}
return null;
}
Are there any exposed system methods to determine a CaseId from a Thread_Id? I'd be curious to know how the standard Email-to-Case functionality achieves this, and if there is anything we can leverage.
I understand there is a newer field, Case.Thread_Id for use in email-templates, but this doesn't look to be available in SOQL, for our Email Service to be able to leverage it.
One way would be to add a field on the Case to store the Thread_Id, but we'd like to avoid needing to dirty the data model, and wasting an ExternalId (since I'd presume formula fields wouldn't add a whole lot of value, since they cannot be indexed and our Case table is ~ 4 million rows.)
There is a post on StackOverflow about this, but as it's a year old, I'm hoping maybe things have changed. The regex in the solution isn't reliable, as some cases are preceded with an underscore, while others are not (in an org with ~4 million cases). We'd obviously like a solution that doesn't involve maintaining logic branches in code as our org continues to scale. :)
tl;dr:
We know the CaseThreadId = [ ref:_00DC0PxQg._500C0KoOZS:ref ]
We need to know CaseId = 500C000000KoOZS