read custom metadata and send out emails


public class EmailToCaseNotifier {

    public static void processFirstIncomingEmails(List<EmailMessage> newMessages) {
        if (newMessages == null || newMessages.isEmpty()) return;

        // Step 1: Identify cases
        Set<Id> caseIds = new Set<Id>();
        Map<Id, EmailMessage> firstMessages = new Map<Id, EmailMessage>(); // ParentId -> EmailMessage

        for (EmailMessage em : newMessages) {
            if (em.ParentId != null && em.Incoming) {
                if (!firstMessages.containsKey(em.ParentId)) {
                    firstMessages.put(em.ParentId, em);
                }
                caseIds.add(em.ParentId);
            }
        }

        if (caseIds.isEmpty()) return;

        // Step 2: Filter to only those cases where this is the first incoming email
        Map<Id, Integer> existingIncomingCounts = new Map<Id, Integer>();
        for (AggregateResult ar : [
            SELECT ParentId, COUNT(Id) cnt
            FROM EmailMessage
            WHERE ParentId IN :caseIds AND Incoming = true
            GROUP BY ParentId
        ]) {
            existingIncomingCounts.put((Id)ar.get('ParentId'), (Integer)ar.get('cnt'));
        }

        List<Id> eligibleCaseIds = new List<Id>();
        for (Id caseId : caseIds) {
            Integer count = existingIncomingCounts.get(caseId);
            if (count == 1) {
                eligibleCaseIds.add(caseId);
            }
        }

        if (eligibleCaseIds.isEmpty()) return;

        Map<Id, Case> caseMap = new Map<Id, Case>(
            [SELECT Id, CaseNumber, RecordType.DeveloperName FROM Case WHERE Id IN :eligibleCaseIds]
        );

        // Step 3: Extract addresses from EmailMessages
        Map<Id, Set<String>> caseIdToMatchedEmails = new Map<Id, Set<String>>();
        for (Id caseId : eligibleCaseIds) {
            EmailMessage em = firstMessages.get(caseId);
            if (em == null) continue;

            Set<String> addresses = new Set<String>();
            for (String addr : new List<String>{ em.ToAddress, em.CcAddress }) {
                if (addr != null) {
                    for (String e : addr.split(',')) {
                        String email = e.trim().toLowerCase();
                        if (!String.isBlank(email)) {
                            addresses.add(email);
                        }
                    }
                }
            }
            if (!addresses.isEmpty()) {
                caseIdToMatchedEmails.put(caseId, addresses);
            }
        }

        // Step 4: Load metadata
        Map<String, EmailToCaseMetadata__mdt> metadataByEmail = new Map<String, EmailToCaseMetadata__mdt>();
        Set<String> templateNames = new Set<String>();
        Set<String> potentialQueueNames = new Set<String>();

        for (EmailToCaseMetadata__mdt meta : [
            SELECT Email__c, Priority__c, CaseNotCreatedSendEmail__c,
                   CaseNotCreatedSendEmailTo__c, CaseNotCreatedEmailTemplate__c,
                   Case_Record_Type_Api_Name__c
            FROM EmailToCaseMetadata__mdt
        ]) {
            metadataByEmail.put(meta.Email__c.toLowerCase(), meta);
            if (!String.isBlank(meta.CaseNotCreatedSendEmailTo__c) &&
                !meta.CaseNotCreatedSendEmailTo__c.contains('@')) {
                potentialQueueNames.add(meta.CaseNotCreatedSendEmailTo__c);
            }
            if (!String.isBlank(meta.CaseNotCreatedEmailTemplate__c)) {
                templateNames.add(meta.CaseNotCreatedEmailTemplate__c);
            }
        }

        // Step 5: Email templates
        Map<String, Id> templateNameToId = new Map<String, Id>();
        for (EmailTemplate tmpl : [
            SELECT Id, DeveloperName FROM EmailTemplate WHERE DeveloperName IN :templateNames
        ]) {
            templateNameToId.put(tmpl.DeveloperName, tmpl.Id);
        }

        // Step 6: Queues and users
        Map<String, Id> queueNameToId = new Map<String, Id>();
        for (Group g : [
            SELECT Id, Name FROM Group WHERE Name IN :potentialQueueNames AND Type = 'Queue'
        ]) {
            queueNameToId.put(g.Name, g.Id);
        }

        Map<String, List<String>> queueNameToEmails = new Map<String, List<String>>();
        if (!queueNameToId.isEmpty()) {
            Map<Id, List<Id>> groupIdToUserIds = new Map<Id, List<Id>>();
            for (GroupMember gm : [
                SELECT GroupId, UserOrGroupId FROM GroupMember WHERE GroupId IN :queueNameToId.values()
            ]) {
                if (!groupIdToUserIds.containsKey(gm.GroupId)) {
                    groupIdToUserIds.put(gm.GroupId, new List<Id>());
                }
                groupIdToUserIds.get(gm.GroupId).add(gm.UserOrGroupId);
            }

            Set<Id> userIds = new Set<Id>();
            for (List<Id> ids : groupIdToUserIds.values()) userIds.addAll(ids);

            Map<Id, String> userIdToEmail = new Map<Id, String>();
            for (User u : [SELECT Id, Email FROM User WHERE Id IN :userIds]) {
                userIdToEmail.put(u.Id, u.Email);
            }

            for (String queueName : queueNameToId.keySet()) {
                List<Id> uids = groupIdToUserIds.get(queueNameToId.get(queueName));
                List<String> emails = new List<String>();
                if (uids != null) {
                    for (Id uid : uids) {
                        if (userIdToEmail.containsKey(uid)) {
                            emails.add(userIdToEmail.get(uid));
                        }
                    }
                }
                queueNameToEmails.put(queueName, emails);
            }
        }

        // Step 7: Send notifications
        List<Messaging.SingleEmailMessage> emailsToSend = new List<Messaging.SingleEmailMessage>();

        for (Id caseId : eligibleCaseIds) {
            Case c = caseMap.get(caseId);
            if (c == null) continue;

            Set<String> matchedEmails = caseIdToMatchedEmails.get(caseId);
            if (matchedEmails == null || matchedEmails.isEmpty()) continue;

            for (String email : matchedEmails) {
                EmailToCaseMetadata__mdt meta = metadataByEmail.get(email);
                if (meta == null || !meta.CaseNotCreatedSendEmail__c) continue;

                if (String.isBlank(meta.Case_Record_Type_Api_Name__c)) continue;
                if (meta.Case_Record_Type_Api_Name__c == c.RecordType.DeveloperName) continue;

                List<String> recipients = new List<String>();
                String toField = meta.CaseNotCreatedSendEmailTo__c;

                if (!String.isBlank(toField)) {
                    if (toField.contains('@')) {
                        recipients.add(toField);
                    } else if (queueNameToEmails.containsKey(toField)) {
                        recipients.addAll(queueNameToEmails.get(toField));
                    }
                }

                if (recipients.isEmpty()) continue;

                Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
                msg.setToAddresses(recipients);
                msg.setTargetObjectId(UserInfo.getUserId());
                msg.setWhatId(c.Id);

                if (!String.isBlank(meta.CaseNotCreatedEmailTemplate__c) &&
                    templateNameToId.containsKey(meta.CaseNotCreatedEmailTemplate__c)) {
                    msg.setTemplateId(templateNameToId.get(meta.CaseNotCreatedEmailTemplate__c));
                } else {
                    msg.setSubject('Missed Case Notification for ' + email);
                    msg.setPlainTextBody('A case was created, but not using the expected record type "' +
                        meta.Case_Record_Type_Api_Name__c + '" for email: ' + email +
                        '. Please review case ' + c.CaseNumber);
                }

                emailsToSend.add(msg);
            }
        }

        if (!emailsToSend.isEmpty()) {
            Messaging.sendEmail(emailsToSend);
        }
    }
}
read custom metadata and send out emails read custom metadata and send out emails Reviewed by dasfrogpractice on 05:50 Rating: 5

No comments:

Theme images by mariusFM77. Powered by Blogger.
Youtube Channel Image
Dasfrog Subscribe To watch more Salesforce Training
Subscribe