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
Abby StockerAbby Stocker 

Help adding code to create feed item from custom email functionality.

Hello! We have created custom email functionality on a custom object that acts almost exactly like email to case. The problem I am facing is that the email comes in and connects to the correct Delivery Exception record (custom object) but doesnt create a feed item like email to case does. The users would like to see the emails in the chatter feed of the record as well as the email message related list (email message related list is created) would the code look something like the following (I am still in the beginning stages of learning to code)?
FeedItem item = new Feeditem();
FeedItem post = new FeedItem();
post.ParentId = deliveryexceptionId;
post.Body = email.plainTextBody;
Insert Post;

Here is the class as it stands now:

global class DeliveryEmailHandler implements Messaging.InboundEmailHandler {
    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
            id deliveryexceptionId;
            string emailBody = email.plainTextBody;        
            string deliveryexceptionName ='';
            string emailSubject= email.subject;
            system.debug('email subject'+emailSubject);
            pattern regEx = Pattern.compile('(E[0-9]{8})');
            matcher deliveryexceptionMatcherSubject = regEx.matcher(emailSubject);
            if(deliveryexceptionMatcherSubject.find() && != null){
                deliveryexceptionName =;
                system.debug('Delivery Exception name found in subject');
            } else {
                // try body of email if not in subject
                matcher deliveryexceptionMatcherBody = regEx.matcher(emailBody);
                if(deliveryexceptionMatcherBody.find() && != null){
                    deliveryexceptionName =;
                    system.debug('Delivery Exception name found in body');
            // if matcher matches find delivery exception record
            If (deliveryexceptionName != ''){
                list<Delivery_Exception__c> deliveryexceptionList = [select id,name,account__c from Delivery_Exception__c where name = :deliveryexceptionName];
                if(!deliveryexceptionList.isEmpty() && deliveryexceptionList.size() == 1){
                    deliveryexceptionId = deliveryexceptionList[0].id;
            // attach to error delivery exception if no delivery exception record is found
            if(deliveryexceptionId == null){
                deliveryexceptionId = [select id from Delivery_Exception__c where external_id__c = 'ERROR' limit 1].Id;
            EmailMessage cEmailMessage = new EmailMessage();
            cEmailMessage.ToAddress =  String.join(email.toAddresses, ',');
            cEmailMessage.FromAddress = email.FromAddress;
            cEmailMessage.FromName = email.FromName;
            cEmailMessage.Subject = email.subject;
            cEmailMessage.status = '0';
            cEmailMessage.HtmlBody = email.htmlBody;
            //System.debug('htmlBody:>>>> ' + email.htmlBody );
            cEmailMessage.Incoming= True;
            cEmailMessage.TextBody = email.plainTextBody;
            cEmailMessage.relatedToId = deliveryexceptionId;
            cEmailMessage.Delivery_Exception__c = deliveryexceptionId;
            //cEmailMessage.validatedFromAddress = '';
            //System.debug('TextBody:>>>>> ' + email.plainTextBody);
            insert cEmailMessage;
            System.debug('Reply Email: ' + cEmailMessage ); 
            //Add Email Message Relation the from address
            list<emailMessageRelation> emailMessageRelations = new list<emailMessageRelation>();
            emailMessageRelations.add(new EmailMessageRelation(
                EmailMessageId =,
                RelationAddress = email.FromAddress,
                RelationType = 'FromAddress'));
            // as of 10-24-19 Salesforce required a relationship to be able to reply.
            // this code section can be removed when Salesforce support Org Wide Email Addresses to be used on custom objects
            // with the functionality supported on the case object.
            for(user u : [select id,email from user where Exception_Email_Functionality__c = true and isactive = true]){
                emailMessageRelations.add(new EmailMessageRelation(EmailMessageId =, RelationId =, RelationType = 'BccAddress'));    
            insert emailMessageRelations;
            // if email attachments are not null create files
            if(email.binaryAttachments != null) createContentDocumentLinks(email.binaryAttachments,, deliveryexceptionId);
        } catch(exception e){
            system.debug('exception processing delivery exception inbound email:'+e.getMessage());
        result.success = true;
        return result;
    public boolean createContentDocumentLinks(Messaging.InboundEmail.BinaryAttachment[] binAttachList, Id insertedEmailMessageId, Id deliveryexceptionId) {
        List<ContentVersion>cvList = new List<ContentVersion>();
        List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
        for (Messaging.InboundEmail.BinaryAttachment binAttach : binAttachList) {
            ContentVersion testContentInsert = new ContentVersion();
            testContentInsert.Title = binAttach.fileName;
            testContentInsert.VersionData = binAttach.body;
            testContentInsert.PathOnClient = '/' + binAttach.fileName ;
        insert cvList;
        cvList = [select id, ContentDocumentId from ContentVersion WHERE Id in :cvList];
        for (ContentVersion cv : cvList) {
            ContentDocumentLink cl = new ContentDocumentLink();
            cl.ContentDocumentId = cv.ContentDocumentId;
            cl.LinkedEntityId = insertedEmailMessageId;
            cl.ShareType = 'V';
            cl.Visibility = 'AllUsers';
            // add link to delivery exception also
            ContentDocumentLink clc = new ContentDocumentLink();
            clc.ContentDocumentId = cv.ContentDocumentId;
            clc.LinkedEntityId = deliveryexceptionId;
            clc.ShareType = 'V';
            clc.Visibility = 'AllUsers';
        insert cdlList;
        return true;

Michelle SotoMichelle Soto
Hi @Abby Stocker

We need to do same, and we don't find a solution for that.

We want to see the email in the feed of custom object but only appear in the activity section.

Could you able to solve the problem?