Chrome extension + Gmail Add-ons (pssss…. InboxSDK)

Shobhit Nigam
Codalyze
Published in
4 min readJan 18, 2021

So you want to make a Chrome web extension that lets the user interact with Gmail and serve a specific purpose? Then this article might be the best solution for you.
In this article I am going to take you on a tour of cooking a web extension that lets you add a customisable button on the Gmail thread toolbar, when clicked, it reads all the attachment received, and download them all for you.

Content

  1. Initialising Chrome Extension
  2. Initialising InboxSDK
  3. Loading InboxSDK and adding Thread toolbar button.
  4. Reading all attachments and downloading them.

Initialising Chrome Extension.

There are a lot of articles and videos on getting started with the Chrome extension, so how about starting with the official docs from here, or learning the basics of Chrome extension from a 25-minute video by “Traversy Media”. Now this all would be enough for moving forward, but in case you want to learn more about the backend working of extension, I would suggest you to watch another descriptive 27-minute video by “An Object Is A”.
By now your working directory would look like

basic chrome extension directory

Where your manifest.json should look like.

{
"name": "EXTENSION_NAME",
"description": "EXTENSION_DESCRIPTION",
"version": "0.0.1",
"manifest_version": 2,
"icons": {
"16": "./logos/logo_16.png",
"32": "./logos/logo_32.png",
"48": "./logos/logo_48.png",
"128": "./logos/logo_128.png"
},
"options_page": "./options.html",
"browser_action": {
"default_popup": "popup.html"
},
"permissions": [
"tabs",
"storage",
"https://www.google.com/*",
"https://mail.google.com/",
"https://inbox.google.com/"
],
"web_accessible_resources": ["*.png"]
}

Initialising InboxSDK

Before that…

Q. What the hell is InboxSDK?
A. InboxSDK is basically a Javascript library that interact with both Gmail and Inbox by Google. It provides all of the necessary APIs to create full-fledged applications directly inside Gmail and Inbox.
To know more how about a visit to it.

To initialise, get our app ID by registering here, After we are done with that let us save its SDK from here into our directory as inboxsdk.js and add “content_scripts” in manifest.json.
where script.js is going to have our own code.

"content_scripts": [
{
"matches": ["https://mail.google.com/*", "https://inbox.google.com/*"],
"js": ["inboxsdk.js", "script.js"]
}
],

Loading InboxSDK and adding Thread toolbar button.

That is going to be pretty easy, just copy and paste the following code into your script.js file. Don’t forget to provide the iconUrl.

InboxSDK.load(2, 'YOUR_APP_ID_HERE').then(function (sdk) {
// the SDK has been loaded, now add a thread button
sdk.Toolbars.registerThreadButton({
title: "TOOLTIP_TEXT_GOES_HERE",
iconUrl: chrome.runtime.getURL("logos/logo_128.png"),
positions: ["THREAD"],
listSection: sdk.Toolbars.SectionNames.OTHER,
onClick: (event) => getAttachments(event, sdk),
});
});

Note: iconUrl key in above code is able to accept the logo value because of the presence of "web_accessible_resources”:["*.png] in manifest.json file, which allows the web to access all the png files. READ MORE (optional)

Refresh your extension from chrome://extensions, open any mail in Gmail, and BOOYAH… there it is.

Icon added on message toolbar

This icon button can be used for any specific purpose but we are going to deal with reading the attachments and their content.
And as always you can read more about the API's endpoint from official docs.

Reading all attachments and downloading them.

  • Let's define the getAttachments function, which will register a message view handler, which first will check if the message view is expanded and is loaded or not.
const getAttachments = async (sdk) => {
let unRegister = await sdk.Conversations.registerMessageViewHandler(
async (messageView) => {
let items = messageView.getFileAttachmentCardViews();
if (messageView.getViewState() === "EXPANDED") {
if (messageView.isLoaded() && items.length) {
.........
.........
}
}
);
unRegister();
};
  • If the defining condition is satisfied. Open a modal that says “Attachments are being read” and later loop through the attachments.
          // Open "getting attachment" modal
let attachment_read_modal = sdk.Widgets.showModalView({
title: "Please Wait...",
el: "<div>Attachments are being read</div>",
});
          // Loop through each attachment and download them.
for (let item of items) {
try {
.........
.........
} catch (error) {
errorModal(sdk, error);
console.log(error);
}
}
// Close "getting attachment" modal
attachment_read_modal.close();
  • In the final step, let's finish up our code by going through each individual attachment, fetching its data using regular expression, and fetch & blob web APIs. Later download it by using createObjectURL web API and DOM.
              // Fetching the individual file data
let attachment = item._attachmentCardImplementation._element;
let download_url = attachment.attributes.getNamedItem("download_url").textContent;
let re = /([^:]+):([^:]+):(.+)/;
let match = re.exec(download_url);
const contentType = match[1];
const name = decodeURI(match[2]);
const contentLink = match[3];
let response = await fetch(contentLink);
let blob = await response.blob();

// Download the file
let url = URL.createObjectURL(blob);
let link = document.createElement("a");
link.href = url;
link.setAttribute("download", name);
link.click();

And thats it, test the working using multiple console.log() and add more features according to your need. In the end, publish your chrome extension.

So how was it, pretty easy no. This article might be over but not the vast scope where this can be useful.

Huge Shout-out to Harishponna for his unsaid motivation to write this.

--

--

Shobhit Nigam
Codalyze
Writer for

Full Stack developer, who likes to solve genuine problems.