So it turns out that writing blog articles isn’t as easy as I initially thought. There are so many attractive activities and distractions over the weekend! The weather on Sunday morning was cloudy, so a perfect opportunity to smash through all of my certificate maintenance exams – yay!

screen-shot-2016-11-27-at-3-23-48-pm

Alright – back to the purpose of this blog post. Salesforce has an in-the-box solution to convert inbound emails to cases. We utilize this to receive customer enquiries every day.

What about outbound emails? The most efficient way we have discovered is:

  1. Create a Salesforce case
  2. Attach the case to a contact and an account
  3. Send an email from this case

Pretty slow hey? Wouldn’t it be nicer if you could send an email and have the case automatically created with predefined values?

 

Fortunately, there is a solution – visualforce page + apex controller + list view button.

Firstly , we start with the controller, what we going to use is simply the standard singleEmailMessage class to handle to actual email sending.

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

We can quickly build the class constructor like so:

public class EmailController {
  public String subject { get; set; }
  public String body { get; set; }
  public String addr { get; set;}
  public String origin {get; set;}
  public String fromaddr {get; set;}
  public String cc {get; set;}
  public String bcc {get; set;}
  public String parentid {get; set;}
  public Attachment attachment {get;set;}

  // Create a constructor that populates the Account object
  public EmailController() {
  attachment = new Attachment();
  fromaddr = 'xxxxx@';
  origin = 'xxxxx@';
}

Once the constructor is ready, we then start building the sendEmail() method.

public PageReference sendEmail() {
  // create a case, and attach an email to it.
  parentid = createCase(findEmail(addr), origin, subject, body);
  if (parentid == null){return null;}

  // Define the email
  Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
  if (attachment.body != null){
    attachment.OwnerId = UserInfo.getUserId();
    attachment.IsPrivate = false;
    List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>;
    Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
    efa.setBody(attachment.body);
    efa.setFileName(attachment.Name);
    fileAttachments.add(efa);
    email.setFileAttachments(fileAttachments);
  }
String[] toAddresses = addr.split(':', 0);

  // add thread id to body
  ID orgId = UserInfo.getOrganizationId();
  String orgIdString = (string) orgId;
  string shortParentid = parentid.left(parentid.length()-3);
  string shortOrgId = orgIdString.left(orgIdString.length()-3);
  String thread_id =
  'ref:_' +
  shortOrgId.left(5) +
  shortOrgId.right(11).replace('0','') +
  '._' +
  shortParentid.left(5) + shortParentid.right(10).left(5).replace('0','') +
  shortParentid.right(5) +
  ':ref';

  subject += ' [ ' + thread_id + ' ]';
  body += '\n\n'+ thread_id;

  email.setSubject( subject );
  email.setToAddresses( toAddresses );
  email.setPlainTextBody( body );
  email.setReplyTo( fromaddr);
  email.setSaveAsActivity(False); 

  if (!String.isEmpty(cc) &amp;&amp; validateEmail(cc)){
    String[] ccAddresses = cc.split(':', 0);
    email.setBccAddresses(ccAddresses);
  }

  // Sends the email
  Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); 

  // Create EmailMesage and attach to the case
  EmailMessage em = new EmailMessage ();
  em.ParentId = parentid;
  em.Subject = subject;
  em.TextBody = body;
  em.ToAddress = addr;
  em.FromAddress = fromaddr;
  if (!String.isEmpty(bcc) && validateEmail(bcc)){
    em.BccAddress = bcc;
  }
  if (!String.isEmpty(cc) && validateEmail(cc)){
    em.CcAddress = cc;
  }
  em.BccAddress = bcc;
  insert em;

  if(attachment.body != null){
    attachment.ParentId = em.id;
    insert attachment;
  }

  // redirect to the case
  PageReference reference=new PageReference('/'+parentid);
  reference.setRedirect(true);
  return reference;
}

There is nothing special about this method, apart from the fact that we are generating a “fake” thread id for this email because apex does not provide a native method to calculate thread id from case number (can’t believe they don’t provide it). With this thread id, customer responses to this email will be attached back to the same case.

  ID orgId = UserInfo.getOrganizationId();
  String orgIdString = (string) orgId;
  string shortParentid = parentid.left(parentid.length()-3);
  string shortOrgId = orgIdString.left(orgIdString.length()-3);
  String thread_id =
  'ref:_' +
  shortOrgId.left(5) +
  shortOrgId.right(11).replace('0','') +
  '._' +
  shortParentid.left(5) + shortParentid.right(10).left(5).replace('0','') +
  shortParentid.right(5) +
  ':ref';

 

Now the controller is complete, next step is to write a visualforce page to allow users to enter some basic information including the recipient’s email address and the body of the email.

I am not going deep into the HTML code, as this isn’t quite a difficult task and everyone is different in how they style a page.

Below is the final page I had for our instance, I used the Google material design to improve the page appearance which did attract positive feedback from end-users.

screen-shot-2016-11-27-at-2-48-01-pm

 

What’s next ? Test class? Nah, let’s skip that in this article and go straight into the button. We need to find a way to allow users to open this page, I really didn’t expect them to remember a long long page URL.

The solution is actually very simple, the only tricky part is how do we allow service cloud users open this page in a service console view.

Interestingly enough, although Salesforce doesn’t provide us with a helper method to generate thread id, it does provide a handy javascript method (above) to take care of the console issue for us.

screen-shot-2016-11-27-at-3-17-40-pm

And there you go, we have a good-looking button in the case list view where a user can click and send direct emails to customers without having to create a case first.

screen-shot-2016-11-27-at-2-47-53-pm

Advertisements