Build a Bulk Emailer for Salesforce with App Engine

Sometimes you just want to send a crapload of email from However, like every PaaS platform there are limits baked into the multi-tenant environment so you don't stomp on other tenants' resources. limits you to 2000 emails per day for each Salesforce license. So if you don't have a lot of Salesforce licenses or a different kind of license, you may be out of luck if you want to send out large volumes. There are a few AppExchange products but they seem more targeted towards marketing purposes.

Google App Engine may be a good solution in this case. With Google App Engine quotas you get 7,000 Mail API calls per day free and can bump that up as high as 1.7M with a paid account.

Here's how to roll your own basic bulk emailer using Google App Engine. Take a look at the video below, but it essentially queries for records, uses the Google Mail Java API to send out individual emails and then send an administrator a notification via Jabber (Google Talk). You can schedule your application (essentially a Servlet) to run on a timed basis using the cron service.

All of this code is at this GitHub repo.

Most of the important code is in the MailServlet class.

package com.jeffdouglas.emailer;

[removed imports]

 * - a simple, schedulable servlet for sending mail
 * with
 * @author Jeff Douglas
 * @version 1.0
 * @see
 * for more details on using Mail with App Engine

public class MailServlet extends HttpServlet {

  private static final Logger logger = Logger.getLogger(ConnectionManager.class.getName());
  private String jabberRecipient = "";

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
  throws IOException {

  String mailerMsg = "No contact found to email!!";
  QueryResult result = null;

  // get a reference to the salesforce connection
  PartnerConnection connection = ConnectionManager.getConnectionManager().getConnection();

  try {
  // query for contacts based upon some criteria -- emailNotSent boolean
  result = connection.query("Select Id, FirstName, LastName, Email " +
    "FROM Contact Where Email = '' Limit 1");
  } catch (ConnectionException e) {
  } catch (NullPointerException npe) {

  // if records were returned then send out email
  if (result != null) {

   for (SObject contact : result.getRecords()) {

  // construct the 'name' for the email recipient
  String contactName = contact.getField("FirstName").toString() + " " + 
   contact.getField("LastName").toString();"Sending emil to " + contactName + " at " + 

  /// send the email
  mailerMsg = sendMail(contact.getField("Email").toString(), contactName);

  // send a jabber notification of the status
  sendJabberNotification(jabberRecipient, mailerMsg);


   // TODO - make a call back into salesforce and update these records
   // as having their emails sent. Implementation is up to you.

  } else {
   logger.warning("No results returned from salesforce");



 * Sends an email
 * @param toAddress the email address of the recipient
 * @param toName the name that appears for the recipeint in their email client 
 * @return A String representing the status of the email sent 
  private String sendMail(String toAddress, String toName) {

 String msg = "Email sent successfully to " + toAddress;
 Properties props = new Properties();
 Session session = Session.getDefaultInstance(props, null); 

 String messageBody = "This is the body of my email";

 try {

   Message emailMessage = new MimeMessage(session);
   // must be the email address of an administrator for the application. see docs
   emailMessage.setFrom(new InternetAddress("","Jeff Douglas"));
  new InternetAddress(toAddress, toName));
   emailMessage.setSubject("My Email Subject");

 } catch (AddressException e) {
   msg = e.toString();
 } catch (MessagingException e) {
   msg = e.toString();
 } catch (UnsupportedEncodingException e) {
   msg = e.toString();

 return msg;

 * Sends a message to any XMPP-compatible chat messaging service (google talk). 
 * See
 * for more detils
 * @param recipient the jid of the jabber recipient of the notification
 * @param msgBody the body of the message to be sent 
  private void sendJabberNotification(String recipient, String msgBody) {

 JID jid = new JID(recipient); msg = new MessageBuilder()

 boolean messageSent = false;
 XMPPService xmpp = XMPPServiceFactory.getXMPPService();

 if (xmpp.getPresence(jid).isAvailable()) {
   SendResponse status = xmpp.sendMessage(msg);
   messageSent = (status.getStatusMap().get(jid) == SendResponse.Status.SUCCESS);
 }"Jabber notifiation sent: " + messageSent);