Building G Suite Add-ons with your favorite tech stack

Posted by Jon Harmer, Product Manager and Steven Bazyl, Developer Advocate for G Suite

Let’s talk about the basics of G Suite Add-ons. G Suite Add-ons simplify how users get things done in G Suite by bringing in functionality from other applications where you need them. They provide a persistent sidebar for quick access, and they are context-aware -- meaning they can react to what you’re doing in context. For example, a CRM add-on can automatically surface details about a sales opportunity in response to an email based on the recipients or even the contents of the message itself.

Up until recently, G Suite Add-ons leaned on Apps Script to build Add-ons, but choice is always a good thing, and in some cases you may want to use another scripting language.. So let’s talk about how to build Add-ons using additional runtimes:

First, additional runtimes don't add any new capabilities to what you can build. What it does give you is more choice and flexibility in how you build Add-ons. We’ve heard feedback from developers that they would also like the option to use the tools and ecosystems they’ve already learned and invested in. And while there have always been ways to bridge Apps Script and other backends that expose APIs over HTTP/S, it isn't the cleanest of workarounds. .

So let’s look at a side by side comparison of what it looks like to build an Add-on with alternate runtimes:

function homePage() {
let card = CardService.newCardBuilder()
.addSection(CardService.newCardSection()
.addWidget(CardService.newTextParagraph()
.setText("Hello world"))
).build();
return [card];
}

Here’s the hello world equivalent of an Add-on in Apps Script. Since Apps Script is more akin to a serverless framework like GCF, the code is straightforward -- a function that takes an event and returns the UI to render.

// Hello world Node.js
const express = require('express');
const app = express();
app.use(express.json());

app.post('/home', (req, res) => {
let card = {
sections: [{
widgets: [{
textParagraph: {
text: 'Hello world'
}
}]
}]
};
res.json({
action: {
navigations: [{
pushCard: card
}]
}
});
}

This is the equivalent in NodeJS using express, a popular web server framework. It shows a little bit more of the underlying mechanics -- working with the HTTP request/response directly, starting the server, and so on.

The biggest difference is the card markup -- instead of using CardService, which under the covers builds a protobuf, we're using the JSON representation of the same thing.

function getCurrentMessage(event) {
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}

Another area where things differ is accessing Google APis. In Apps Script, the clients are available in the global context -- the APIs mostly 'just work'. Moving to Node requires a little more effort, but not much.

Apps Script is super easy here. In fact, normally we wouldn't bother with setting the token when using more permissive scopes as it's done for us by Apps Script. We're doing it here to take advantage of the per-message scope that the add-on framework provides.

const { google } = require('googleapis');
const { OAuth2Client } = require('google-auth-library');
const gmail = google.gmail({ version: 'v1' });

async function fetchMessage(event) {
const accessToken = event.gmail.accessToken;
const auth = new OAuth2Client();
auth.setCredentials({access_token: accessToken});

const messageId = event.gmail.messageId;
const res = await gmail.users.messages.get({
id: messageId,
userId: 'me',
headers: { 'X-Goog-Gmail-Access-Token': event.gmail.accessToken },
auth
});
return res.data;
}

The NodeJS version is very similar -- a little extra code to import the libraries, but otherwise the same -- extract the message ID and token from the request, set the credentials, then call the API to get the message contents.

Your Add-on, Your way

One of the biggest wins for alternate runtimes is the testability that comes with using your favorite IDE, language, and framework--all of which helps you make developing add-ons more approachable.

Both Apps Script and alternate runtimes for G Suite Add-ons have important places in building Add-ons. If you’re getting into building Add-ons or if you want to prototype more complex ones, Apps Script is a good choice.. If you write and maintain systems as your full time job, though, alternate runtimes allow you to use those tools to build your Add-on, letting you leverage work, code and processes that you’re already using. With alternate runtimes for G Suite Add-ons, we want to make it possible for you to extend G Suite in a way that fits your needs using whatever tools you're most comfortable with.

And don't just take our word for it, hear from one of our early access partners. Shailesh Matariya, CTO at Gfacility has this to say about alternate runtimes: "We're really happy to use alternate runtimes in G Suite Add-ons. The results have been great and it's much easier to maintain the code. Historically, it would take 4-5 seconds to load data in our Add-on, whereas with alternate runtimes it's closer to 1 second, and that time and efficiency really adds up. Not to mention performance, we're seeing about a 50% performance increase and thanks to this our users are able to manage their workflows with just a few clicks, without having to jump to another system and deal with the hassle of constant updates."

Next Steps

Read the developer documentation for Alternate Runtimes and sign up for the early access program.