23

I've stumbled upon a problem at the final stage of a new feature I was building (as always)

I need to pass in a custom string into a salesforce template, however there doesnt seem to be a way of doing this through the standard methods.

I'm passing in a contact ID, to email the correct user and name to personailse the email. But I need a string to be passed to the template which is completely unrelated to the contact record, and need to be dynamic. So I cant just put it in the template.

Is there a way? I know i cant pass in a custom object as it needs to be a contact, user or lead id to email a user.

Can you help?

Here is the code if you need to see it:

public static void sendSingleMail(id objId, ID templateId, string fromaddress) {

    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setReplyTo(fromaddress);
    mail.setTemplateId(templateId);
    mail.setTargetObjectId(objId);
    mail.saveAsActivity = false;
    mail.setReplyTo(fromaddress);
    mail.setSenderDisplayName(fromaddress);

    ErrLogger.logger('Email being sent to :');
    ErrLogger.logger('objId found:  ' + objId);
    ErrLogger.logger('templateId found:  ' + templateId);
    ErrLogger.logger('fromaddress found:  ' + fromaddress);

    Messaging.sendEmail(new Messaging.SingleEmailmessage[] {mail});
}
23

I've done something similar in the past, but it requires that you manually do the template merge field lifting. Here is an example of how you could do it below.

Since you are manually doing the merging in the template, you can put any kind of merge field into your template that you'd like. In this example, I'm pretending there is a custom merge field {!myCustomString} in the email template for your custom string you want to insert.

I've also assumed below that you have a merge field for first name {!Contact.FirstName} in the subject and in the body of the template. If you have other fields, you would need to include the fields in the contact query and then to the string replace for each of those fields.

public static void sendSingleMail(Id contactId, Id templateId, String fromAddress, String myCustomString){

    // grab the email template
    EmailTemplate emailTemplate = [select Id, Subject, HtmlValue, Body from EmailTemplate where Id =: teamplateId];

    // grab the contact fields we need. This assumes we are emailing a contact.
    Contact c = [Select Id, FirstName FROM Contact WHERE Id=: contactId];

    // process the merge fields
    String subject = emailTemplate.Subject;
    subject = subject.replace('{!Contact.FirstName}', c.FirstName);

    String htmlBody = emailTemplate.HtmlValue;
    htmlBody = htmlBody.replace('{!Contact.FirstName}', c.FirstName);
    htmlBody = htmlBody.replace('{!myCustomString}', myCustomString);

    String plainBody = emailTemplate.Body;
    plainBody = plainBody.replace('{!Contact.FirstName}', c.FirstName);
    plainBody = plainBody.replace('{!myCustomString}', myCustomString);

        //build the email message
    Messaging.Singleemailmessage email = new Messaging.Singleemailmessage();

    email.setReplyTo(fromaddress);
    email.setSenderDisplayName(fromaddress);
    email.setTargetObjectId(objId);
    email.setSaveAsActivity(true);

    email.setSubject(subject);
    email.setHtmlBody(htmlBody);
    email.setPlainTextBody(plainBody);

    Messaging.sendEmail(new Messaging.SingleEmailmessage[] {email});
}
  • Nice, can I just ask if this is the only way to send a list of objects in a mail from APEX? i.e. by making the list as an HTML string and inserting it thusly? – Marc Mar 15 '13 at 13:07
8

I would recommend you take a look at Visualforce Components.

<apex:component controller="DynamicContent">{!dynamicContent}</apex:component>

public with sharing class DynamicContent {
    public String getDynamicContent()
    {
        return 'Something dynamic ' + System.today();
    }
}

Then in your Visualforce Email Template reference the new component via...

<c:DynamicContent/>

You can also pass parameters to the component, if you need context from the target record.

3

I provided my process before on this answer: Using APEX to assemble HTML Letterhead Emails

using regular expressions and a Map <\String,String> you can build your own mail merge process that works pretty well.

2

You could use a Visualforce email template. That way you have an Apex controller that can set just about anything you like.

  • Technically speaking only custom components in a VF template can use controllers - the template itself can't have a controller. – ca_peterson Sep 5 '13 at 20:03
1

This is a bit crufty, but could work:

  1. Add a custom field on Contact called something like Custom_Email_Note__c
  2. In your code, set c.Custom_Email_Note__c = 'Your custom message'; and Update c;
  3. Send the email using the code in your question (which could now pull that string from Contact)
  4. Clear the field (c.Custom_Email_Note__c = '';) and update again.
  • Sounds good, but the relationship from the contact to the string is a one to many. So I wont be able to insert many strings in one field, and only picking the correct value. Nice hack though if someone wants a single string like that. – c14kaa Sep 7 '12 at 13:32
1

I know it's a old post - but if anyone looks for an answer to populate dynamically computed data, please check my blog post titled 'Dynamically populating custom HTML email template content in force.com with custom dynamic data using Apex' on how to accomplish this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.