Implementing Email Notifications for Salesforce Ideas

Implementing Email Notifications for Salesforce Ideas

salesforce ideas

Engaging customers to guide your company’s roadmap is an excellent way to gain insights and to show the people you do business with that they’re valued. Implementing Salesforce Ideas is a great first step, especially given the ease of doing so with Communities. Unfortunately, there is not strong support for notifications about updates to Ideas, contrary to the long standing convention that you’ll receive a notification when someone writes a comment on your post. Customers may feel like their votes don’t matter if your team doesn’t have the resources to manually manage ideas and promptly reply to feedback. Moreover, when you provide updates people remain engaged and will submit ideas in the future.

At Internet Creations, we implemented two triggers to send notifications when a new comment is added to an idea or when its status changes. Both internal users and external customers are kept in the loop about ideas that they promoted or commented on. Although seemingly straight forward, we encountered obstacles as we were writing our pair of triggers on Idea and IdeaComment.

1) Including details of the idea in the email notification

To provide context at a glance, notification emails should include information about the idea. Unfortunately, email templates do not support the Idea object with setWhatId (Documentation). Without the ability to directly apply templates to ideas and their comments, we developed a workaround where we create a template with idea merge fields, pull its markup into Apex, and then replace merge fields with the idea record data. The resulting text can then directly be used for the HTML body of the email. Using the code below in a utility method which takes in the template markup, the Idea, and potentially the IdeaComment, we have recreated merge functionality and overcome the limitation of templates.

function mergeIdeaFields(Idea MyIdea, IdeaComment MyComment, String TemplateText)

If(MyIdea != null)
     TemplateText = TemplateText.replace('{!Idea.Id}', MyIdea.Id)
     .replace('{!Idea.Title}', MyIdea.Title == null ? '' : MyIdea.Title)
     .replace('{!Idea.Status}', MyIdea.Status == null ? '' : MyIdea.Status)
     .replace('{!Idea.LastModifiedBy}', MyIdea.LastModifiedBy.Name == null ? '' : MyIdea.LastModifiedBy.Name)

if(MyComment != null)
     TemplateText = TemplateText.replace('{!IdeaComment.Id}', MyComment.Id)
     .replace('{!IdeaComment.CommentBody}', MyComment.CommentBody == null ? '' : MyComment.CommentBody)
     .replace('{!IdeaComment.CreatorName}', MyComment.CreatorName == null ? '' : MyComment.CreatorName)

2) Daily limits on outbound email

From a coding perspective, it would be easiest to simply send a single email message with each recipient copied. Even if we BCCed to avoid the obvious issue of exposing customer emails to other customers, it would quickly exhaust platform limits on outbound messages sent through Apex, typically 1000 unique recipients per day. However, emails sent to users, including community users, do not consume email limits. To leverage this, instead of constructing a string list of email addresses for a single message, we create a message for each recipient and set their Id as the TargetObjectId.

So, instead of:

String[] ToAddresses = new String[]{};
for(User u : users.values()){
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

We have:

Messaging.SingleEmailMessage[] messages = new Messaging.SingleEmailMessage[]{};
for(User u : users.values()){
     Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

3) Specifying the email From address

With the above, we have scalable solutions for both dynamic text and platform limits, but we now face the issue of ensuring that emails are sent from an address that both represents the organization as a whole and where replies can be easily discarded without generating bounces. Your IT department can likely create a black hole email address for you, or if you use Email to Case Premium then you can leverage the Contact Substitution feature and its email service address. You can then create an Organization Wide Address with Display Name, such as “Neat Widgets Inc. Community”, and the black hole as the email address.

Putting It All Together:

//build list of recipients
User[] Recipients = New User[]{}
//Add idea creator to Recipients
//Query IdeaVote and add all idea promoters to Recipients
//Query IdeaComment and add all commenters to Recipients 

//remove running user

//"merge" fields into template
String EmailSubject = mergeIdeaFields(Idea, IdeaComment, TemplateSubject);
String EmailBody = mergeIdeaFields(Idea, IdeaComment, TemplateBody);

//create list of outbound emails
Messaging.SingleEmailMessage[] messages = new Messaging.SingleEmailMessage[]{};

//for each user, create a template, set the text
for(User u : Recipients.values()){

     Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

//send the list of messages

At Internet Creations, we have noticed an increase in activity around ideas since we implemented email notifications for Salesforce Ideas. Our customers, as well as our employees, are more engaged and continue to submit new feature requests for our apps, including Simple Survey for Salesforce, Case Flags, and Case Merge Premium.

We’ve implemented this solution for several of our customers as well and they’ve experienced an increase in adoption of the Salesforce Ideas product. If you have a Certified Salesforce Developer on your team, they can review the above points as a starting point to build your own custom solution. Of course, if you’re interested in having the Internet Creations team roll this out for you, feel free to get in touch with us.

Chris Caputo
Latest posts by Chris Caputo (see all)
Chris Caputo
Chris Caputo
Chris is a Salesforce Developer for Internet Creations.