Accessing POP3 & IMAP From AppEngine

A quick note about accessing IMAP and POP3 servers from AppEngine: you need to include the JavaMail libraries and import everything from javax.mail and javax.mail.internet.

If you need to streamline the amount of JARs bundled with your application, you can also select individual protocol provider JARs.

Here’s example code to extract emails from a POP3 store:

    Properties properties = new Properties();
    properties.put("mail.host", host);
    properties.put("mail.store.protocol", "pop3s");
    properties.put("mail.pop3s.auth", "true");
    properties.put("mail.pop3s.port", port);
    Session session = Session.getDefaultInstance(properties);
    Store store = session.getStore();
    //With a POP3 store available, connect to the given account.
    store.connect(host, user, password);
    //Open up the inbox folder, and give ourselves read/write privilegese.
    Folder folder = store.getFolder("inbox");
    folder.open(Folder.READ_WRITE);
    //Collect messages.
    Message[] messages = folder.getMessages();
    System.out.println(messages.length);
    for (int i = 0; i < messages.length; i++) {
        //Extract message.
        MimeMessage message = (MimeMessage)messages[i];

From here, you can extract the from address and the subject line from the MimeMessage. Remember that the Sockets API requires that you have billing enabled on your application.

A Simple index.yaml File

The App Engine SDK developer server can automatically create datastore indexes for your application – just run the datastore querying code within the dev server. But sometimes that isn’t possible.

In that case, you can hand-write your index settings. Here is an example of a simple index.yaml file. It indexes all entities with a kind of Fact, on the property Approved and sorts on the property Add_date in descending order.

indexes:

- kind: Fact
  ancestor: no
  properties:
  - name: Approved
  - name: Add_date
    direction: desc

index.yaml goes in the root directory of your application.

Sending Mail With Golang

Previously I published a Java code example using the low level Mail API to send a message to the registered admins of an application. Here’s sample code for a Golang application to send mail to app admins. C stands for an appengine.Context reference.

If you want to send mail to an arbitrary user, and not an admin, you can uncomment the To line and change SendToAdmins() to Send().

application_id := appengine.AppID(c)
separation_point := strings.Index(application_id, ":")
if separation_point > -1 {
    application_id = application_id[separation_point:]
}

//Create the message struct
msg := &mail.Message{
    Sender:  "donotreply@" + application_id + ".appspotmail.com",
    //To:    []string{"To-User <[email protected]>"},
    Subject: subject,
    Body:    email_body,
}
c.Infof("Sending message: %v", msg)

//Send an email to admins
err := mail.SendToAdmins(c, msg)
if err != nil {
    c.Errorf("Unable to send email: %v", err)
}

Writing To The Blobstore Using The Files API

A short code snippet showing how to write data to the Blobstore using the experimental Files API.

FileService file_service = FileServiceFactory.getFileService();
AppEngineFile file = file_service.createNewBlobFile(mime_type, filename);
FileWriteChannel write_channel = file_service.openWriteChannel(file, true);
ByteBuffer buffer = ByteBuffer.wrap(byte_array);
write_channel.write(buffer);
write_channel.closeFinally();

 

TaskTooLargeError

Google App Engine has an upper limit on how much data you can put into a task – a maximum of 100 KB. This includes everything within an individual task such as parameters, payload, the request URL, etc.

To get around this error, store any large pieces of information within an entity in the datastore. You can then pass the entity’s ID as a task parameter and pull out the entity’s data during task processing.

Geolocation With App Engine

One of the best parts of hosting with App Engine is the free geolocation service it provides. Every incoming request has special AppEngine location headers added to it.

For instance, here’s how to find out the user’s city (req is the servlet’s HttpServletRequest object):

 String city = req.getHeader("X-AppEngine-City");

Other geolocation information is available as well: the user’s country (X-AppEngine-Country), the region of that country (X-AppEngine-Region), and the nearest city’s latitude and longitude (X-AppEngine-CityLatLong).

Mapping Favicon.ico In A Golang Application

One of the most annoying issues about configuring a Go based app is correctly mapping every file to its proper path.

For instance, beginners at Go frequently declare their first handler like so:

http.HandleFunc("/", handler)

And declare a simple app.yaml, similar to the one below:

application: application_id
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app

Unfortunately this will cause all requests to be routed to your Go application code, even if you have static files in your application’s root directory.

To map favicon.ico (or any static file in the app’s root directory) so AppEngine will serve it, replace the handlers section in app.yaml to properly indicate where it is and the url it maps to:

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico
- url: /.*
  script: _go_app

Sending Mail With The Java Low Level API

Code example on how to send mail using the Java low level API. This code generates the appropriate From address based on your application’s ID.

MailService.Message message = new MailService.Message();
message.setSubject(subject);
message.setTextBody(body);
String application_id = SystemProperty.applicationId.get();
String sender = "donotreply@" + application_id + ".appspotmail.com";
message.setSender(sender);
MailServiceFactory.getMailService().sendToAdmins(message);

Google Compute Engine

Google’s Compute Engine just released into General Availability, and I’ve been testing it out the last couple of days.

The one thing that blows me away is how reliably fast even the low-end instances are. I provisioned and set up a f1-micro instance – it runs great and quite consistently. That’s in sharp contrast to Amazon’s micro instance which is limited to “bursty” processing; there are spikes where processing goes quickly, then the CPU gets throttled and the instance grinds to a near-halt.

I’m considering building a mail app on top of GCE – so far, everything looks great. GCE even allows inbound SMTP connections (although unfortunately no outbound SMTP connections).

Configuring Nameservers For .IO Domains

I recently purchased a .IO domain name from nic.io, and immediately set about configuring it for Google App Engine. I was surprised to find out that nic.io doesn’t provide customizable DNS – you can’t set CNAMES, TXT or MX records. The only options provided are to set your own nameservers, or forward the domain to another web site.

Fortunately I have a spare GoDaddy account, and they offer free DNS services even for domains not hosted with them. Here’s how I configured nameservers for my .IO domain:

First, go to DNS Manager:

Select Off-site > Add Off-site:

Type in your .IO domain:

Copy the provided nameservers to your clipboard, and press finish:

Paste the nameservers into the nic.io administration page:

Wait 24 hours for the changes to propagate, and you’re done!