2

I am having some difficulty with APEX and restricting it to run on a specific Record type.

Requirement: We recently implanting a technical solution whereby Chatters Post and Comments would automatically publish to Request Comments.

Functionality: The solution works as expected – Chatter Post and Comments post to Requests Comments, I have isolated the Apex class to only run on the record type ‘UK_Pricing_Query’ on the Process.

Challenge: We have set the Apex Class to only run on 1 Record Type via the Process Builder and this works – to some extent. Chatter Posts will only be copied to the Requests comments on that record type, however when a user comments on a chatter post this transfers to the request comments regardless of what record type it is.

The Chatter post itself doesn’t copy to the request comments (That’s the process builder criteria kicking in) but if a user comments on a post it will copy across. I believe we are going to have to define the Record type within either the Apex Trigger or the Class – this is where my knowledge drops out. Could anyone potentially offer some assistance?

Trigger:

trigger CaseCommentSyncFeedCommentBeforeTrigger on FeedComment (before insert) {
CaseFeedCommentSyncUtils.caseFeedCommentToCaseComment(trigger.new);
}

APEX Class:

/**
    @param COMMENTINSERT Used to indicate feed item to case comment action
    @param FEEDREMOVAL Used to indicate removal of a duplicate feed item action
    @description This class handles all logic for syncing Feed Items and Feed Comments from a Case record feed
                 to a Case Comment;
*/
global class CaseFeedCommentSyncUtils {

    global static String COMMENTINSERT = 'FeedItem2Case';
    global static String FEEDREMOVAL = 'CaseCommentFeedItemDeletion';
    final static String FROMCHATTER = 'Comment Made From Chatter';

    /**
        @description The class contains Invocable variables to used as sync parameters in conjunction with process builder.
    */
    global class SyncParameter{
        @InvocableVariable(Label = 'Sync Type'
                          Description = 'Indicates Feed sync or feed item removal'
                           Required = true)
        global String syncType;

        @InvocableVariable(Label = 'Feed Body'
                          Description = 'Body of the chatter post')
        global String feedBody;

        @InvocableVariable( Label = 'CreatedById'
                            Description = 'Record Id of the User that created the new record')
        global String createdById;

         @InvocableVariable(Label = 'Parent Id'
                          Description = 'Id of parent record, feed item or case comment'
                           Required = true)
        global String parentId;

    }

    /**
        @param syncParam List of type SyncParameter. 
        @description This method takes a list of type SyncParameter and determines the correct action that needs
                     to be taken based on SyncParameter.syncType. CaseComment records will be inserted or 
                     duplicate feed items will be removed.
    */
    @InvocableMethod
    global static void chatterFeedToCaseComment(List<SyncParameter> syncParams){
        //if syncType if Case Comment insertion, create case comment object
        if(syncParams[0].syncType == COMMENTINSERT){
            String feedBody = syncParams[0].feedBody;
            String parentId = syncParams[0].parentId;
            CaseComment cc = feedBody != null && parentId != null ? 
                new CaseComment(CommentBody = feedBody.stripHtmlTags() + + '\n\n ' + FROMCHATTER, ParentId = parentId) : null;

            if(cc != null){
                try{
                    insert cc;
                }catch(Exception caseCommentInsEx){
                    system.debug(LoggingLevel.ERROR, 'Case Comment Insert Error: ' + caseCommentInsEx.getMessage());
                }
            }
        }
        //if syncType is duplicate feed item removal find all duplicate feed items from case feed and delete
        else if(syncParams[0].syncType == FEEDREMOVAL){
            List<Id> delFeedIds = new List<Id>();
            ConnectApi.FeedElementPage feedPage = 
            Connectapi.ChatterFeeds.getFeedElementsFromFeed(null, ConnectApi.feedtype.Record, syncParams[0].parentId);

            system.debug(LoggingLevel.ERROR, 'Feed Page for Case: ' + feedPage);

            if(feedPage != null){
                for(ConnectApi.FeedElement elem : feedPage.elements){
                    if(elem.capabilities != null){
                        if(elem.capabilities.caseComment != null){
                            String caseCommentTxt = elem.capabilities.caseComment.text != null ? elem.capabilities.caseComment.text : '';

                            if(caseCommentTxt.contains(FROMCHATTER)){
                                String currPageUrl = elem.capabilities.chatterLikes.page.currentPageUrl;
                                List<String> urlSplit = currPageUrl.split('/');
                                delFeedIds.add(urlSplit[6]);
                            }                    
                        }
                    }
                }

            try{
                List<database.DeleteResult> delRes = !delFeedIds.isEmpty() ? Database.delete(delFeedIds) : null;
            }catch(DMLException feedDelEx){
                system.debug(LoggingLevel.ERROR, 'error during feed item deletion: ' + feedDelEx.getMessage());
            }
          }
        }
    }

    /**
        @param feedcomments A list of type Feed Comments
        @description This method takes a list of feed comments and creates a corresponding case comment if the
                     feed comment is part of a case feed.s
    */
    global static void caseFeedCommentToCaseComment(List<FeedComment> feedComments){
        List<CaseComment> caseComments = new List<CaseComment>();    
            for(FeedComment feedCom : feedComments){        
                String parentId = (String)feedCom.ParentId;

                if(parentId.startsWith('500')){
                    CaseComment cc = new CaseComment(ParentId = feedCom.ParentId, CommentBody = 
                                                 feedCom.CommentBody + '\n\n' + FROMCHATTER);
                caseComments.add(cc);   
                }
            }

            try{
                List<Database.SaveResult> insRes = !caseComments.isEmpty() ? Database.insert(caseComments) : null;  
            }catch(DMLException commentInsEx){
                system.debug('Error during case comment insertion: ' + commentInsEx.getMessage());
            }     
    } 
}

I am wanting to isolate this to run on the UK_Pricing_Query Record Type.

2 Answers 2

3

It is good practice in trigger logic to separate filters from actions. A typical filter syntax will look like:

public static List<MyObject__c> hasMyRecordType(List<MyObject__c> records)
{
    List<MyObject__c> output = new List<MyObject__c>();
    for (MyObject__c record : records)
    {
        // evaluate if record should be in output
    }
    return output;
}

Before that loop, you can use describes to find the proper filter value.

Id myTypeId = SObjectType.MyObject__c.getRecordTypeInfosByDeveloperName().get('My_Type');
for (MyObject__c record : records)
{
    if (record.RecordTypeId == myTypeId)
    {
        output.add(record);
    }
}

Then you pass records through the filter before action.

MyService.myAction(MyFilters.hasMyRecordType(trigger.new));
3
  • Nice pattern here Commented Aug 5, 2019 at 12:41
  • 1
    You are going to have to either learn, use a different tool, or hire someone with this skill set. There is no one line fix.
    – Adrian Larson
    Commented Aug 5, 2019 at 14:57
  • 1
    @BrianMiller - check out Selector package for a wealth of filters.
    – cropredy
    Commented Aug 5, 2019 at 18:11
-1

Considering you don't know code, the easiest is to put on the trigger.

trigger CaseCommentSyncFeedCommentBeforeTrigger on FeedComment (before insert) {
    List<FeedComment> cmtList = new List<FeedComment>();
    for(FeedComment cmt: Trigger.new) {
        if(cmt.RecordType.Name == 'UK_Pricing_Query') {
            cmtList.add(cmt);
        }
    }
    CaseFeedCommentSyncUtils.caseFeedCommentToCaseComment(cmtList);
}

This is not the best structured code if you ask me about the design. But it can be the easiest one if you don't know how to code.

1
  • Hi Lance, Thank you for your response. I am getting hit with an error message here: Error: Compile Error: Variable does not exist: RecordType at line 4 column 16. I am wanting to define a Case Record Type. Commented Aug 5, 2019 at 13:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .