[SalesForce] How to Messaging.sendEmail() so that the email is properly shown on a record’s activity tab in Lightning Experience

This question is related to but different from How to use an Apex Email Service to store emails on a record EXACTLY as Salesforce does?

I want to send an Email using Messaging.sendEmail()

This Email should appear at the appropriate place in the activity tab, exactly as salesforce is placing them when sending using the LEX UI:

enter image description here

My current (halfway working) code looks like this

Messaging.SingleEmailMessage    m = new Messaging.SingleEmailMessage();
    m.setToAddresses(           new String[]{'heim@elastify.eu'} );
    m.setSubject(               'test' );
    m.setHtmlBody(              'whatever' );
ContentVersion                  cv = new ContentVersion();
    cv.Title                    = email.Subject+'.pdf';
    cv.PathOnClient             = cv.Title;
    cv.VersionData              = anyPdfBlobDoesNotMatterWhat;
    cv.SharingOption            = 'A'; // A : 'Allowed'
insert cv;
cv                              = [ SELECT Id, FileType, Title, ContentDocumentId FROM ContentVersion WHERE Id =: cv.Id];
ContentDocumentLink             cdl                     = new ContentDocumentLink();
    cdl.ContentDocumentId       = cv.ContentDocumentId;
    cdl.LinkedEntityId          = t.Id;
    cdl.ShareType               = 'I'; // I : 'Inferred' = The user’s permission is determined by the related record.
insert cdl;
Messaging.EmailFileAttachment   efa = new Messaging.EmailFileAttachment();
    efa.setFileName(cv.Title);
    efa.setBody( pdfBlob );
    efa.setContentType('application/pdf'); // does not work: (cv.FileType);
    efa.setInline(false);
m.setFileAttachments( new Messaging.EmailFileAttachment[]{ efa });

if(!(Test.isRunningTest())) {
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { m });
} 

Only that I can not link the sent email to a given Record, lets say there is an SObject MyObject__c record, queried with a given Id. The id is available as record.Id

How can I connect record or record.Id to the email sent above??

Assuming that again like here we have to magically and undocumented glue that together using junction task, following a recipe like:

  1. Create a wrapper/junction Task
  2. Link the EmailMessage somehow via ActivityId to the wrapper Task

Only that seems not to be possible. Again.

Any ideas?

Best Answer

To link the task/email to a record, use setWhatId (e.g. m.setWhatId(record.Id);). This should link the email automatically.

Sample Code:

Messaging.SingleEmailMessage m = new Messaging.SingleEmailMessage();
m.setWhatId([select id from account where name = 'Test Account' limit 1].id);
m.setSubject('test');
m.settoaddresses(new string[] { '<set-valid-email-here>' });
m.setsaveasactivity(true);
m.setplaintextbody('Hello world');
messaging.sendemail(new messaging.email[] { m });

Account details:

Sample of Email Details