If you're a Gmail user, you've probably seen small buttons appearing on your emails, prompting you to track a package, RSVP for an event, or confirm a flight. Now that so much of our email consists of transactional actions, it's great to be able to quickly take action on a "work item" in your inbox without ever leaving your Gmail tab.
What you might not know is that Google has opened up these actions to everyone who sends email. Inspired by this post, we decided to implement these email actions for Meldium (some of our automated notifications require users to take an action). We wanted to share some of the technical and UX details about how we did this, and how developers can add this technology to their own apps.
Providing the right user experience
In that Google Apps Developer blog post, Google suggests you use a "One-Click Action" to validate email addresses. Given the existing email activation flow in our app, we opted to use email actions for a different purpose: approving access requests. Through our service, administrators can create an internal "app store" for their team: they can connect various apps and shared credentials to their organization and make them available for colleagues to request. For example, as an admin I can add a Namecheap account to my organization, and my teammates will see it on their Meldium home screens as an app they can request. Requests show up in my inbox with links I can use to approve them. Since nothing interactive happens after you click the "approve" link, this is a great candidate for replacement with a One-Click Action. Administrators who get many app requests from Meldium can thus approve them without ever leaving Gmail.
Sending your first test email
Unfortunately, getting email actions set up isn't quite as easy as the original blog post suggests. Google uses a number of security measures to validate email senders and make sure that only valid actions are making their way into users' inboxes. Above all, senders need to be whitelisted by Google to use this feature.
Luckily, you can test email actions without being whitelisted, but your message has to meet a number of requirements:
- The To: and From: addresses have to be the same (i.e. the sender and receiver both need to be firstname.lastname@example.org).
- The message must be correctly authenticated with DKIM or SPF.
- The DKIM / SPF authentication must match the sender / receiver's domain.
- The schema.org markup within the email must be formatted correctly.
To meet these requirements, you'll almost certainly need your own Google Apps domain - we'll discuss how to set this up shortly. The easiest way to get started is to send a sample email using script.google.com to make sure your email is formatted correctly and get some instant gratification before descending into the complexity of DKIM.
Using one-click actions in Rails
Adding the GMail schema markup to your emails is the easiest part of getting this working. Assuming that you use Rails' standard ActionMailer to send emails, you just have to make a couple of changes to your app configuration to embed the metadata that Google needs to add one-click actions.
We're using this helper to generate the LD+JSON script tag - there's nothing specific to Meldium in here, and you should be able to use this for any "ConfirmAction":
Next, we added some code to the email to invoke the helper with a URL for approval:
And finally, a small change to our email layout to include the helper data if present:
Creating single-use URLs for actions
One thing we glossed over in the previous section is how we created the URLs used for one-click approval. Google provides some helpful guidelines on this; the tokens should:
- Be tied to a specific user account
- Be tied to a specific action
- Be single-use
- Not be guessable
- Be revokable
Remember that the user hitting your URL won't be signed in or have any other session state from your web app - all you'll have is the security token to go on. To meet these requirements, we added a new table to Meldium to track email action tokens that we've issued. Here's what that table looks like:
The ActiveRecord model for the token is fairly simple - it sets up some associations and validations and gives us logic for generating cryptographically strong random tokens and consuming them just once:
Importantly, that code checks to see if the user to whom the token has been issued is still allowed to take the action, by checking their status in Meldium. Given how long a token could sit in a user's inbox, it's essential to check that the user still has the appropriate access level.
Finally, we have a thin controller that actually looks up the token for a request and executes it (if it hasn't already been used):
An alternative approach would be to generate a secret for each approval target and user, then compute a cryptographic hash on those values to produce a one-time use token without actually having a token table in your database. While this might be more space efficient for some apps, it is less explicit and relies on getting your cryptography right (which is a hard thing to do even for experts). We prefer generating and tracking purely random tokens as a more foolproof technique.
Sending an email using Mailgun
The last step in getting email actions working end-to-end is to make sure your transactional email provider is signing emails correctly. We use Mailgun to send emails programmatically, and setting up the right configuration was pretty simple.
All of the Meldium transactional email comes from a dedicated domain: the sender is email@example.com. Most email providers advise that you use different domains for transactional / bulk / corporate email, to keep their email "reputations" separate. We added app.meldium.com as a domain in Mailgun and were instructed to add a DNS record to enable SPF for the domain:
Set up this record with your DNS provider (we like DNSimple) and wait a couple of hours for the DNS gnomes to do their thing, then use Mailgun's API to test your configuration by sending an email to your GMail or Google Apps account. If you hit "Show Original" on the message, you should see the raw email headers. Look for the "Authentication-Results" header in the email - you want it to look something like this:
Received-SPF: pass (google.com: domain of firstname.lastname@example.org designates 22.214.171.124 as permitted sender) client-ip=126.96.36.199;Authentication-Results: mx.google.com; spf=pass (google.com: domain of email@example.com designates 188.8.131.52 as permitted sender) firstname.lastname@example.org
If you see the spf=pass and dkim=pass flags then you're (likely) in business. If not, double-check your DNS settings; you can use Mailgun's own configuration UI to check for the correct setup. Third-party tools like DKIM Check are useful for debugging these problems, though DKIM / SPF setup can be intimidating and difficult to get right.
Getting it to production & getting feedback
All new email actions require Google’s approval before your end users will see them. The approval process is simple, once you’ve got emails correctly signed and sent with the right metadata. Just fill out a short questionnaire and send a sample email to the GMail team, and they’ll work with you to understand your use-case and get your app whitelisted. In our case it took about a week between the approval request and our emails going out to customers, so you’ll want to plan ahead a little bit.
We’ve seen positive results from the moment we launched email actions. Before we even had a chance to tell our customers about this new capability, 10% of all approvals were coming from this new channel. We had users contact us to let us know how “awesome” the experience was (their word, not ours). We obsess over giving our customers the best possible user experience, and finding new ways to delight them is one of the most important things we do. Given these results, we plan on continuing to experiment with email actions to improve our end-to-end product experience.
What are you planning to do with Actions in the Inbox? We think the example of using those convenient buttons to confirm your email is a solid one, but there are much more interesting things to be done with this new way to engage your user base. Leave a note in the comments describing how you’re using (or you plan to use) email actions in your Rails app!