Pikmail: Emails to Pictures Using Kotlin

Pikmail: Emails to Pictures Using Kotlin

This post is 100% based on Kotlin.

There is a common scenario where software developers need to display the user’s profile picture, but they only have access to the user’s email address.

I’ll show you how to convert an email address into a profile picture by writing a library and deploying it as a web service in Heroku.

Why the Pikmail API?

Let’s talk about a possible real use case. Suppose that you have a database with all the employees info including their email address. Furthermore, the company’s email system is based on Google Gmail.

You may want to write an application to display all the employees email list with their profile pictures.

This is where Pikmail API comes to the rescue.

General Architecture

The Pikmail API is conformed by the following main components,

  • A Picassa Endpoint: This is what actually does the “magic” under the hood. It provides a profile picture URL from a registered email address.
  • The Pikmail library: This is a standalone Java/Kotlin library that pretty much wraps the required code for consuming and parsing the Picassa endpoint. This is used to obtain the profile picture URL.
  • The Pikmail API: A REST web service that uses the Pikmail library for mapping an email address to a real profile picture. It receives an email address as parameter and redirects the request to the URL if found, otherwise it returns a HTTP 404 error.

This general diagram could be implemented in any programming language. I’ll talk about how I implemented this general architecture using Kotlin, how I deployed it into Heroku, and how it’s being used by over eight thousand users daily.

Let’s talk a little deeper about each of these components and how they are implemented.

Picassa Endpoint

Google’s Picassa has its own API. Through this API, you can consume Picassa users’ data. For example, this is how I use it in Pikmail.

This endpoint provides basic user information. Along with it comes the user’s profile picture associated with the email. This is where Pikmail gets the profile picture from.

Pikmail Library

The Pikmail library internally uses Retrofit which is compatible with Java. You can use to request and parse the above Picassa Endpoint along with RxJava for asynchronous usage.

This library is written in Kotlin. This means that it is 100% interoperable with Java.

It can be used synchronously or asynchronously. Use the synchronous option when blocking is safe to use, as with web servers. Use it asynchronously when blocking is not safe to use, as with an Android main thread.

Synchronous

Asynchronous

Spek (a Detour)

We used Spek for testing this library.

Spek is a Kotlin Specification Framework for the JVM. It also works with Android. However, in this case we used it for JVM since the Pikmail library is independent of the Android framework and can be used in any JVM project.

This framework allow us to write more readable tests for both developers and product owners as specification tests.

For example, to test for an invalide address,

This makes your tests are more readable and friendly. As you can see, it is easier to interpret this test as, “Given a Pikmail object, if you get a profile for a invalid Gmail address, throw a ProfileNotFoundException”.

Spek uses given(), on(), and it() to define a specification test.

given()
It is used to define the context under test. In this case we are testing the Pikmail object. Just after the given() declaration, we could initialize all the required objects and dependencies for the Pikmail object.

In this case Pikmail is a Kotlin object that behaves as a Singleton and doesn’t need to be manually initialized, so we can leave this block empty.

on()
It is used to express the method or desired functionally that we want to test under the parent context. Since we declare it inside the given() context, we could test methods from the Pikmail object to declare or initialize parameters for these methods (e.g., invalidGmailAddress and testObservable).
it()
It is used to validate or assert our expected method behavior. In this case we are expecting an exception if the email is invalid or not found.

For more information about how to configure and use Spek, please take a look at the Official Documentation.

Pikmail API

Finally let’s talk about the Pikmail API module. It is a web service that responds to one endpoint.

This module uses the Pikmail library. It also uses Ktor which, according to its website, “is a framework for building servers and clients in connected systems using powerful Kotlin programming language.”

This web service is pretty simple,

  • Have a Main.kt file/class to initialize the web
  • Specify port by the PORTenvironment variable
  • Or default to the 8080 port.

Ktor is strongly based on Kotlin’s coroutines. This means that you can use along with Netty to take the maximum advantage of the asynchronicity of the Kotlin’s coroutines in the server side.

Here’s the code,

In this code, we are routing just one endpoint for the Pikmail API, the one in the line 11. Here we take the email as a path parameter and we also accept size as a query parameter for resizing the profile picture.

With these two parameter we make use of the Pikmail library for requesting and resizing the profile picture associated with the email address. If the email doesn’t not exist or is invalid, the Pikmail library throws a ProfilePictureNotFound exception. Otherwise we just redirect the request to the profile picture URL provided by the library.

For any other request that doesn’t match with the unique endpoint, we redirect them to the Pikmail API landing page. The landing page is composed by only static HTML file located in the ./static directory. We dispatch this directory using the Ktor’s static keyword.

Here some advantages of using this API,

  • It’s totally free and Open Source.
  • You can find the source code here.
  • No authentication needed, just the desired email address to map.

You don’t need to write a wrapper for consuming the endpoint and parsing the JSON response.

Deploying Pikmail API on Heroku

The Pikmail API is deployed in Heroku. Heroku allows Java for deploying web applications. This means that it also supports Kotlin out of the box.

But it needs some specific configuration for deploying Ktor in Heroku,

  • Use mainClassNamevariable to tell Ktor about our main server engine class, in this case Netty.
  • Enable coroutines.
  • Add the required gradle dependencies: Netty, Pikmail Library, and the Coroutines library, among others.
  • Create a packaging gradle tasks to 1) indicate what is our main class in the .jar file and 2) for packaging the dependencies along with our pikmail-api.jar application.

In order to deploy our application in the heroku server, we need to add a file to indicate what command will start out Pikmail API service. Do this through Heroku’s Procfile with the next command on it web: java $JAVA_OPTS -jar pikmail-api.jar.

With this, we are ready to commit and push our changes to the Heroku’s server to deploy our Pikmail API.

Using the Pikmail API

It’s pretty simple to use the Pikmail API in a frontend application: simply render the avatar image in HTLM format,

If you are writing an Android application, you can do the same using another library for fetching the image through a URL. For example, for Picasso,

Then you’ll get something like this,

Finally…

Here you have a useful web service entirely written in Kotlin that can be used in any kind of application for resolving profile pictures through email addresses.

If you have any questions, you can reach me at [email protected]

Focus Mode

Contact Request

Close

We will call you right away. All information is kept private