function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Satish Kumar LalamSatish Kumar Lalam 

SOQL query returns no results Trigger but returns a row in Developer Console for ContentDocumentLink Object.

I have wrote a trigger on EmailMessage Object to get the attachments from email replies to case FeedItems. Below is my code Snippet. I am facing an issue with SOQL query on ContnentDocumentLink object. Where the the same query is working fine in Anonymous window but not in trigger. Could you please advise on this. Below is my Code Snippet. Kindly advice on this.

trigger emailToPostChatter on EmailMessage (After insert) {
List<FeedItem> itemList = new List<FeedItem>();
List<FeedItem> upItemList = new List<FeedItem>();
List<ContentVersion> conVersionList = new List<ContentVersion>();
List<FeedAttachment> atchList = new List<FeedAttachment>();
List<FeedAttachment> FeedAtchList = new List<FeedAttachment>();
List<ContentDocumentLink> contDocLinks = new List<ContentDocumentLink>();
Set<Id> EmailId = new Set<Id>();
for (EmailMessage email : trigger.new) {


FeedItem post = new FeedItem();
post.ParentId = email.ParentId;
post.Visibility = 'AllUsers';
post.Body = email.FromName + '\n' + email.TextBody;
system.debug('Body = '+post.Body);

insert post;

system.debug('EmailMessage Id= '+ email.Id);
system.debug('message.ContentDocumentIds = '+email.ContentDocumentIds);
system.debug('Post ID 1= '+ post.Id);
system.debug('message.HasAttachment = '+email.HasAttachment);
if(email.HasAttachment){
system.debug('EmailMessage Id inside If = '+ email.Id);
//emailToPostChatterHelper.InsertFeedAttachment(email.Id, Post.Id);
List<ContentDocumentLink> contDocLinks = [select Id, LinkedEntityId, ContentDocumentId from ContentDocumentLink where LinkedEntityId =: email.Id];
//List<ContentDocumentLink> contDocLinks2 = [SELECT Id, ContentDocumentId, ContentDocument.LatestPublishedVersion.VersionData FROM ContentDocumentLink WHERE LinkedEntityId = :email.Id];
system.debug('contDocLinks = '+contDocLinks);
//system.debug('contDocLinks2 = '+contDocLinks2);
system.debug('LinkedEntityId = '+email.Id);
system.debug('contDocLinks Size = '+contDocLinks.size());
if(contDocLinks.size()!=null){
for(ContentDocumentLink contD : contDocLinks){
ContentVersion contv = [select Id from ContentVersion where ContentDocumentId =:contD.ContentDocumentId];
system.debug('contv ='+contv);

FeedAttachment feedAttachment = new FeedAttachment();
feedAttachment.FeedEntityId = post.Id; //Id of FeedItem

feedAttachment.RecordId = contv.Id;
system.debug('feedAttachment.RecordId ='+feedAttachment.RecordId);
//feedAttachment.Title = 'FileName';
feedAttachment.Type = 'CONTENT';

insert feedAttachment;
}
}

}
}
}
SubratSubrat (Salesforce Developers) 
Hello satish ,

Please review this discussion for your reference which states that you can't run a query without filters against ContentDocumentLink.

You can't filter on ContentDocument fields if you're filtering by ContentDocumentId. You can only filter on ContentDocument fields if you're filtering by LinkedEntityId.

You can't filter on the related object fields. For example, you can't filter on the properties of the account to which a file is linked. You can filter on the properties of the file, such as the title field.

Most critically,

A SOQL query must filter on one of Id, ContentDocumentId, or LinkedEntityId > https://salesforce.stackexchange.com/questions/234279/how-to-query-contentdocumentlink-in-soql-and-then-upsert-records-in-data-loader

Thank you.
Satish Kumar LalamSatish Kumar Lalam
Hi Subrat,

We are actully following the same right?. we are filtering the soql with LinkedEntityId field. Actually I am a bit confused. Also wondering why the smae exact query able to retrun the expected data when we execute it from anonymous window.
Bryan Leaman 6Bryan Leaman 6
Your trigger runs "after insert" of the email message, but I believe the attachments cannot be related to the email record until after the insert of EmailMessage has completed, including your trigger, so the attachments aren't related yet. You might have to change the trigger to be after update. 

Or maybe you just need to process the EmailMessage's ContentDocumentIds property instead?
ContentDocumentIds
A string array of IDs for content documents such as files and attachments that are associated with an email. Each ID is linked to a ContentDocumentLink record, which represents the relationship between an email message and a content document record.
See: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_emailmessage.htm
Satish Kumar LalamSatish Kumar Lalam
Hi Bryan,

No use of ContentDocumentIds field as well. I have tried using it as well but Its returning null even though my mail contains multiple attachments.
Satish Kumar LalamSatish Kumar Lalam
Hi All,

For Inserting attachmnets from email seems like we need to call it from future method as the SOQL query on ContentDocumentLink object is not working in the same instance of trigger. I have tried calling the future method from trigger and it worked fine and yeah this still needs to be bulkfied.


trigger emailToPostChatter on EmailMessage (After insert) {

    Set<Id> EmailId = new Set<Id>();
    for (EmailMessage email : trigger.new) {
        
        
        FeedItem post = new FeedItem();
        post.ParentId = email.ParentId;
        post.Visibility = 'AllUsers';
        post.Body = email.FromName + '\n' + email.TextBody;
        system.debug('Body = '+post.Body);
        
        insert post;
        
        system.debug('EmailMessage Id= '+ email.Id);
        system.debug('message.ContentDocumentIds = '+email.ContentDocumentIds);
        system.debug('Post ID 1= '+ post.Id);
        system.debug('message.HasAttachment = '+email.HasAttachment);
        if(email.HasAttachment){
            system.debug('EmailMessage Id inside If = '+ email.Id);
            emailToPostChatterHelper.InsertFeedAttachment(email.Id, Post.Id);
           
                }
    }   
}


public class emailToPostChatterHelper {
    @future
    Public static void InsertFeedAttachment(Id emailId, Id postId){
              List<ContentDocumentLink> contDocLinks = [select Id, LinkedEntityId, ContentDocumentId from ContentDocumentLink where LinkedEntityId =: emailId];
            
            system.debug('contDocLinks = '+contDocLinks);
            system.debug('LinkedEntityId = '+emailId);
            system.debug('contDocLinks Size = '+contDocLinks.size());
            if(contDocLinks.size()!=null){
            for(ContentDocumentLink contD : contDocLinks){
                ContentVersion contv = [select Id from ContentVersion where ContentDocumentId =:contD.ContentDocumentId];
                system.debug('contv ='+contv);
                
                FeedAttachment feedAttachment = new FeedAttachment();
                feedAttachment.FeedEntityId = postId;                          //Id of FeedItem
                
                feedAttachment.RecordId = contv.Id;
                system.debug('feedAttachment.RecordId ='+feedAttachment.RecordId);
              
                  feedAttachment.Type = 'Content'; 
                
                insert feedAttachment;
                }
            }
        
    }

}