This is going to be a short blog for a requirement I came across, But didn't find any blogs out there addressing this. So lets get right to it, I need to notify all the case team members when a case comment is logged, be it contact, users etc.
Here's what we'll need
Helper Class:
This Class helps to send the email out to all the case team members when ever a Case Comment is created/Edited Trigger Associated: CommentEmail Scenario: 1)Case has contacts and/or Users as Case Team Members 2)Send Email only if Case Comment is Public Sorry for the long Block of code, But this is a tested working piece of code to cover possible scenarios,There are a couple of Helper Methods at the bottom
Well that was a lot of code to go through, But hopefully it helped you. Remember, The test class is still pending Check it out here.. Let me know if any clarifications are required. Happy Coding !
Here's what we'll need
- Trigger on Case Comment
- A Helper Class (To keep the trigger clean)
- Test Class ( Don't forget to test your code)
To make things look clean we'll keep most of the code to the helper class,
Trigger :
You could put in additional filters, checks etc in the trigger to suit your needs
trigger CommentEmail on CaseComment (after insert,after update) { CaseCommentEmailHelper Obj = new CaseCommentEmailHelper(); Obj.SendCaseCommentEmail(Trigger.new); }
Helper Class:
This Class helps to send the email out to all the case team members when ever a Case Comment is created/Edited Trigger Associated: CommentEmail Scenario: 1)Case has contacts and/or Users as Case Team Members 2)Send Email only if Case Comment is Public Sorry for the long Block of code, But this is a tested working piece of code to cover possible scenarios,There are a couple of Helper Methods at the bottom
public class CaseCommentEmailHelper { public void SendCaseCommentEmail(List<CaseComment> newTrigger) { system.debug('Entered Case Comment'); Set<id> parentCaseIds = new Set<id>(); Set<id> CommentedUsers = new Set<id>(); // To set the reply-to Address set<id> ContactMembers = new Set<id>(); Set<id> UserMembers = new set<id>(); List<CaseComment> isValidComment = new List<CaseComment>(); for(CaseComment CC :newTrigger) { if(CC.IsPublished==true)//Only if comment is public, send out emails { isValidComment.add(CC); parentCaseIds.add(CC.ParentId); CommentedUsers.add(CC.LastModifiedById); } } if(isValidComment.size()>0) { Map<id,Case> CaseObjs = new Map<id,Case>([select Id,Description, Owner.Email,CaseNumber,Subject from Case where id in:parentCaseIds]);// Query all case related Data Map<id,List<id>> CaseToUserCaseTeamMembersMap = new Map<id,List<id>>();// Query Case Team Members Map<id,List<id>> CaseToContactCaseTeamMembersMap = new Map<id,List<id>>(); // We Maintain 2 maps, Case => User Case Members and // Case => Contact Case Members Map to reduce further loops ahead for(CaseTeamMember CTMember: [SELECT Id,MemberId,ParentId FROM CaseTeamMember WHERE ParentId in:parentCaseIds]) { if(!isContactID(CTMember.MemberID)) { if(CaseToUserCaseTeamMembersMap.get(CTMember.ParentID)!=null) CaseToUserCaseTeamMembersMap.get(CTMember.ParentID).add(CTMember.MemberID); //Add to the list of User Members else CaseToUserCaseTeamMembersMap.put(CTMember.ParentID,new id[]{CTMember.MemberID}); //Create a new List for the case and add the memeber to it UserMembers.add(CTMember.MemberID); } else if(isContactID(CTMember.MemberID)) { if(CaseToContactCaseTeamMembersMap.get(CTMember.ParentID)!=null) CaseToContactCaseTeamMembersMap.get(CTMember.ParentID).add(CTMember.MemberID); //Add to the list of Contact Members else CaseToContactCaseTeamMembersMap.put(CTMember.ParentID,new id[]{CTMember.MemberID}); //Create a new List for the case and add the memeber to it ContactMembers.add(CTMember.MemberID); } } /* Now we have the required Data to map and send emails out, There are 2 scenarios, The Case team can consist of Users and Contacts, We send out Emails to Contacts only if their Email is not Blank */ Map<id,User> UserObjs; Map<id,Contact> ContactObjs; if((CommentedUsers.size() > 0) || (!CaseToUserCaseTeamMembersMap.isEmpty())) UserObjs = new Map<id,User>([select id,Email from User where ID in: CommentedUsers OR ID in:UserMembers]); //Query all User Required Data if(!CaseToContactCaseTeamMembersMap.isEmpty()) ContactObjs = new Map<id,Contact>([select id,Email from Contact where ID in: ContactMembers AND Email!=NULL AND Email!='']); for(CaseComment CC :newTrigger) { List<String> toAddresses = new List<String>(); // Add Users in case Team to email list if((!CaseToUserCaseTeamMembersMap.isEmpty())&&CaseToUserCaseTeamMembersMap.get(CC.ParentId).size()>0) toAddresses.addall(getUserEmailList(UserObjs,CaseToUserCaseTeamMembersMap.get(CC.ParentId))); //Add Contacts in Case Team to Email List if((!CaseToContactCaseTeamMembersMap.isEmpty())&& CaseToContactCaseTeamMembersMap.get(CC.ParentId).size()>0) toAddresses.addall(getContactEmailList(ContactObjs,CaseToContactCaseTeamMembersMap.get(CC.ParentId))); if(toAddresses.size()>0) SendCommentEmail(toAddresses,UserObjs.get(CC.LastModifiedById).Email,CaseObjs.get(CC.parentId),CC.CommentBody); } } } //=============== Private Methods =================== private List<String> getUserEmailList(Map<id,User> UserObjs,List<ID>UserIds) { List<String> UserEmailList = new List<String>(); if(UserIds!=null && UserObjs!=null) { for(Id userId :UserIDs) { if(UserObjs.get(userId)!=null) UserEmailList.add(UserObjs.get(userId).Email); } } return UserEmailList; } private List<String> getContactEmailList(Map<id,Contact> ContactObjs,List<ID>ContactIds) { List<String> ContactEmailList = new List<String>(); if(ContactIds!=null && ContactObjs!=null) { for(Id ContactId :ContactIds) { if(ContactObjs.get(ContactId)!=null) ContactEmailList.add(ContactObjs.get(ContactId).Email); } } return ContactEmailList; } private void SendCommentEmail(List<String> toAddresses,string replyTo,Case CurrentCase,string CommentBody) { String CaseLink =System.URL.getSalesforceBaseUrl().toExternalForm().remove('-api' )+'/'+CurrentCase.Id; string TXTEmailBody =(String.isNotBlank(CurrentCase.Description)?'Description: '+CurrentCase.Description:'') +'\n\nCase Comment: '+CommentBody +'\n\n Case Link: '+CaseLink +'\n\n Thank You!'; string Subject ='Case #'+CurrentCase.CaseNumber+': ' + (String.isNotBlank(CurrentCase.Subject)?CurrentCase.Subject:'') +' has been updated.'; // Send Email Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses(toAddresses); mail.setReplyTo(replyTo); mail.setSubject(Subject); mail.setUseSignature(false); mail.setPlainTextBody(TXTEmailBody); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } private boolean isContactID(id IdInQuestion) { return (IdInQuestion.getSObjectType()== Contact.sObjectType); } }
Well that was a lot of code to go through, But hopefully it helped you. Remember, The test class is still pending Check it out here.. Let me know if any clarifications are required. Happy Coding !