1

I have a custom object named 'comments' with which i made a 'action'.it is having a trigger handler class

 public void onAfterInsert(Comments__c[] newComments){

        if(newComments.size()>0){
            for(Comments__c comRec:newComments){
                FeedItem post = new FeedItem();
                post.ParentId = comRec.case__c; 
                post.IsRichText = true;
                post.body =  comRec.Case_Comments__c;  
                feedItemInsertList.add(post);
                try{
                    if(feedItemInsertList.size()>0){
                        insert post;
                    }
                }
                catch(Exception e){
                    system.debug(e.getMessage());
                } 
            } 

the 'case comments' field is a rich text but when i add a image to it in case feed it is creating a comment but I was not able to view the image in feed but in detail page the image is available. It was throwing an error

System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Referenced file id is invalid, not accessible, or does not exist: [RawBody]

1 Answer 1

3

In case if image has been added to Rich Text Area field, its body will be stored as ContentReference record. If you look at rich field, format will be like:

<img alt="User-added image" src="https://......."></img>

Where src attribute contains link to image.

We can define PageReference and get its content by:

string richTxt = '<img alt="User-added image" src="https://c.naxx.content.force.com/servlet/rtaImage?..."></img>';
String imgRef = richTxt.substringBetween('src="', '"');
PageReference pageRef = new PageReference(imgRef);

Then insert ContentVersion record:

ContentVersion cVersion = new ContentVersion (title = 'title', VersionData = pageRef.getContent(), PathOnClient = 'my.png');
insert cVersion;

As you can see there is constant name, reason of that - ContentReference doesn't have name, I think using attachment will be better option

And create Feed:

FeedItem fItem = new FeedItem(RelatedRecordId = cVersion.id, type = 'ContentPost', parentId = '50036000000rxec');
insert fItem;

One more thing I want to mention here is - it's not allowed to insert ContentReference and Feed in single context, queueable can be used here.

Assuming everything above, we can implement following triggerHandler method:

@future(callout=true)
public static void ProceedWithComments(set<id> caseIds) {

    list<Case> cases = [select id, Case_Comments__c from Case where id in :caseIds];

    map<id, ContentVersion> caseIdToContentMap = new map<id, ContentVersion> ();

    for (Case cs :cases){
        String imgRef = cs.Case_Comments__c.substringBetween('src="', '"').replace('amp;','');

        if (String.isNotBlank(imgRef)){
            PageReference pageRef = new PageReference(imgRef);
            ContentVersion cVersion = new ContentVersion (title = 'From Case', VersionData = pageRef.getContent(), PathOnClient = 'my.png');
            caseIdToContentMap.put(cs.id, cVersion);
        }
    }

    insert caseIdToContentMap.values();

    System.enqueueJob(new QueueableFeedInsert(caseIdToContentMap));

} 

Queueable class:

public with sharing class QueueableFeedInsert implements Queueable {

    private map <id, ContentVersion> caseIdToContentMap;

    public QueueableFeedInsert(map<id, ContentVersion> caseIdToContentMap) {
        this.caseIdToContentMap = caseIdToContentMap;
    }

    public void execute(QueueableContext context) {

        list<FeedItem> feedToInsert = new list<FeedItem>();

        for (Id csId :caseIdToContentMap.keySet()){
            feedToInsert.add(new FeedItem(RelatedRecordId = caseIdToContentMap.get(csid).id, type = 'ContentPost', parentId = csid));
        }

        insert feedToInsert;

    }
}

You must log in to answer this question.

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