Check out the Salesforce API Explorer

In an attempt to make things easier for us developers, the Developer Relations group has created a nice little tool called the Salesforce API Explorer.

Screen Shot 2018-08-23 at 1.48.18 PM

What It Includes Now

The first thing you should know about this tool is that it is still in Developer Preview and the team that created it is actively seeking feedback on how it can be improved. You can submit feedback right from the Send us Feedback link at the top.

As of this writing, there are only the following two API’s featured here:

  • Force.com REST API
  • Marketing Cloud REST API

How You Can Help

Remember when I said this was still in Preview mode? Well, you can easily vote on which API’s will be included next by clicking the like button underneath the API’s listed in the “Which API’s would you like to see here next?” section. Please take the time to go through the list and vote for which ones you would like to see appear next. Come on. You can’t complain about a lack of good documentation without taking the time to be part of a solution.

Why It is So Cool

This Explorer tool is not only cool because of the fact that it will list all the API’s in one place in a nice readable way. But, it is VERY cool when you consider the nice “Try it now” feature that lets you see the results of executing any of the API calls against your developer org.  You just need to provide credentials for your org.

You will then select a Resource, such as Account and then an endpoint, such as FindAccountById. Not only does this show you all the documentation you need for that endpoint, but you can try it out by doing the following:

  1. Click Try it Now
  2. Enter any path parameters (if needed), such as the Account ID
  3. Click Execute
  4. A Live response appears on the right

Screen Shot 2018-08-23 at 6.35.09 PM.png

Boom! You don’t have to go into workbench. You can do everything you need right here in the explorer tool. Cool, right?

Considerations when Sending Outbound Emails Through Apex

email-outbound-imageIn a recent post, I went over things to consider when receiving emails using Apex code. In this post, I will go over some tips and considerations you should make when working with outbound emails in the real-world.

  • First off, in order to work with outbound messaging in your Sandbox (note that I said Sandbox and NOT Developer edition), you will first need to enable it since it is disabled by default in Sandboxes. You can do this by going to Setup | Email Administration | Deliverability  and changing the Access Level to All Email.
  • Even though you can create email templates using text or HTML, as long as you are NOT sending mass emails, consider using Visualforce instead to design a more robust and dynamic email template. I said the part about mass emails because Visualforce cannot be used in these particular situations. But assuming you are just dealing with single emails, then Visualforce can be a great alternative. Refer to this doc for more info on how to use them.
  • If you are a Sys Admin or you have permission to “Manage Public Templates”, then you can access the email templates by going to Setup | Communication Templates | Email Templates. Otherwise you can access the ones you have access to by going to Setup |My Setttings | Email | Email Templates.
  • Outbound email message limits are based on Greenwich Mean time (GMT) and not necessarily your time zone (unless of course, you live in England). Also, the limits on mass emails vary by your Salesforce Edition. Checkout page 16 of this Limits Cheatsheet for more specific info.
  • Even though the limits clearly state that you can send up to 1000 emails per org per day, this only applies to non-Development or non-Trial orgs. Development and Trial orgs are restricted to a far lower number of 10-15 messages per day (depending on when your org was created).
  • Most code examples I have seen out there do not show how to use the reserveMassEmailCapacity and reserveSingleEmailCapacity methods from the Messaging class. They can be used to check whether you will exceed the org limit or if the org does not have the right permissions when trying to send either Mass or Single emails. Prior to Winter 14, these methods existed, but for some reason using them still resulted in an unhandled limit exception. Using them should result in a handled exception and this is a much better way of avoiding unexpected outcomes. For example, the following code should now work ok:
try {
    Messaging.reserveSingleEmailCapacity(numOfEmailsToSend);
} catch (Exception e) {
    //handle your exception gracefully
}

More about Receiving Emails Through Apex

The post I wrote once about Receiving and Sending Emails through Apex two years ago has continued to be the most popular post on this blog. So, for all of you that are obviously very interested in this subject, here are some more tips about working with Inbound Emails. In a follow-up post to this one, I will write more about what to consider when sending Outbound Emails.

Creating the Inbound Email Service Handler Class

For starters, the Force.com IDE provides a neat little template for creating an inbound email service handler class. This gives you a head start on creating your inbound email service. To use it just create a new Apex class and select the template drop down box (see image below).

InboundEmailClassTemplate

Using the template will get you a class file that looks like the following. This is a good starting point.

/**
* Email services are automated processes that use Apex classes
* to process the contents, headers, and attachments of inbound
* email.
*/
global class MyInboundHandler implements Messaging.InboundEmailHandler {

    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, 
       Messaging.InboundEnvelope envelope) {
          Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();

          return result;
    }
}

As you are filling in the code for this template, you may want to keep the following things in mind:

  • Be careful about creating new records in the database. Many simple code samples I have seen out there automatically create new contact or lead records when an email is received, but if you set something like this up you will quickly end up with a messy database and a lot of redundant records. A better alternative to just blindly creating a new record for each email is to have the logic in the email handler try to match the incoming email sender to an existing record. For example, you could try matching on the name and email address. But be careful here too, because the name on the email header may not exactly match what you have in your database. Probably the best way to ensure that duplication does not occur is to consider creating a task for a user in your org that sends them the email sender info so they can decide whether a new record should be created. Just something that should be discussed with your orgs decision makers before you start blindly creating an automated code solution.
  • The email body can be either HTML or plain text and the results are stored as different properties, so your code should account for this. For example, the following code extracts the email body, no matter which type it is:
String emailBody;       
if (email.plainTextBody != null){
    emailBody = email.plainTextBody;
} else {
    emailBody = email.htmlBody;
}
  • You may want to parse the body of the email and try to extract meaningful information from it, but just keep in mind that this can be very tricky if you are not 100% sure where and how the email is being originated. Obviously HTML content will be more difficult to parse than plain text, but you also do not know if the email client used to submit the email has embedded additional information or special formatting. The solution will depend on your exact circumstances and I only bring this up to make you realize that it might not be as straightforward as you think. Be sure to think this through carefully when designing your solution and try to do testing with all potential email clients.
  • Email attachments could be text or binary and each is handled differently, so you want your code to be able to accept both. For example, you might want to include code similar to the following, which inserts attachments to the Salesforce record, in this case a contact record. Now, of course, this assumes that you do not configure your email service to only accept one form or to always convert Text attachments to Binary (which is an option we will show later on). Also note that the body of a text attachment must be converted into a blob before it can be assigned to the Attachments body field.
if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) 
{
    for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) {         
        Attachment attachment = new Attachment();         
        attachment.ParentId = contact.Id;         
        attachment.Name = email.binaryAttachments[i].filename;Attach         
        attachment.Body = email.binaryAttachments[i].body;         
        insert attachment;     
    } 
} 
if (email.textAttachments != null && email.textAttachments.size() > 0) {
    for (integer i = 0 ; i < email.textAttachments.size() ; i++) {
        Attachment attachment = new Attachment();
        attachment.ParentId = contact.Id;
        attachment.Name = blob.valueOf(email.textAttachments[i].filename);
        attachment.Body = email.textAttachments[i].body;
        insert attachment;
     }
}

Configuring the Email Service

Once you have the code for your email handler, you will need to define the Email Service in your Salesforce Setup. You do this by going to Setup | Develop | Email Services and clicking New Email Service.

At this point, you will need to configure how your email receives incoming messages (see image below).

EmailServiceConfig1

You will of course specify the class handler you just created, but you will also need to keep in mind the following:

  • Most services are configured to accept all attachments, but you can specifically have it accept no attachments or only binary or only text attachments.
  • The Advanced security settings will restrict what emails are accepted by your service according to whether the sender uses certain protocols (specifically SPF, SenderId and DomainKeys). If you do not know for sure what protocol the sender will be using, you do not want to check this.
  • You likely do not want to specify that you accept email from a certain email address, unless your solution is so specific that you know in advance what email address will be sending incoming emails. Leave this blank to accept emails from any address.
  • Don’t forget to check the Active switch for your service.
  • While testing, you will likely want to use Bounce Message as the setting for the failure response settings, but don’t forget to go back and possibly change this after moving to production.
  • I suggest you enable error routing and specify an email address to receive error emails (certainly while testing and maybe even after moving to production).

The next step is to configure the email address that will accept incoming emails (although you can specify more than one). This is the email address that outside users will send email to. Unfortunately, you have no control over the domain name part of this address.  You only get to control what the part before the @ sign looks like. A typical generated email address will look something like the following (where I only got to specify the recievecontactemail part):

receivecontactemail@2fiwoie9n02fazrqxzvaars35bdrih1hxlzg6ij79u66vorcd8.d-dxwdeae.na14.apex.salesforce.com

Ugly, right?

Yeah, I know. If you just can’t see yourself giving this address to people or posting it somewhere, you might want to consider creating a forwarding address (with a much prettier and easier to remember name, like receivecontactemail@yourdomain.com) and then have that email address just forward all emails to the ugly looking one that Salesforce creates for you.

Testing your Email Service

As of Spring 09, Salesforce provides access to Email Logs, which contain info about email sent and received over the last 30 days. You access them through Setup | Monitor | Logs | Email Log Files. You will need to go in and specifically request a new log before it is generated (see image below).

EmailLogRequest

 

You will have to specify a start and end time and the period can be no longer than 7 days. Doing so will generate a CSV file that tells you information such as the email address of each sender and recipient, along with the date and time and any error codes encountered.

You may want to also consider creating a custom error log object. This can be used to store any exceptions or debug statements. For example, you could create a custom object named ErrorLog with text fields used to store the message and other info you may want to capture. Then, in your email handler class, you add try..catch statements that write to the log when an exception is captured.

That’s it for now. More about Outbound Messaging in a later post.

 

 

 

Heads Up: Problems consuming WSDL and Winter 15 release

Winter15If you work with WSDL to access the SOAP API, then you need to be aware of the fact that there is a serious problem involving the Winter 15 release. As of now, there are two issues that are causing problems.

The first issue has to do with consuming an enterprise or partner WSDL in .NET. If you generate your WSDL using the new Winter 15 (or version 32 of the API), you should get the following error when you try to instantiate the object:

 There was an error in serializing one of the headers in message loginRequest: ‘Unable to generate a temporary class’. Cannot convert ListViewRecordColumn[] to ListViewRecordColumn

This issue has been reported by multiple people on the forums. You can workaround it by doing a simple find and replace in your solution. You will want to do a find for all occurrences of [][] and replace with []. This should replace two occurrences in the Reference.cs class file. You can then recompile and your app should work.

The second problem has to do with consuming custom WSDL and this is a known issue that has been acknowledged. A permanent workaround may become available, but in the mean time, the fix involves doing another find and replace. You will need to replace all instances of ns1: and ns2: with tns:.

Hope this helps someone avoid all the hair pulling out that I went through recently.