Building Gmail/Chrome Extension with Vue.js and InboxSDK
Tags: vue, chrome, gmail, inboxsdk
Published: 2018-11-29 16:29:11

---
title: Building Gmail/Chrome Extension with Vue.js and InboxSDK
published: true
description: Building a Chrome extension with Vue.js that plugs into Gmail using InboxSDK
tags: Vue, Chrome, Gmail, InboxSDK
---

We’re going to create a small Chrome extension that uses [InboxSDK](https://www.inboxsdk.com) and [Pipl](https://pipl.com) to let you search email addresses for user information right in our Gmail. You can change this demo to use any Api that you like. For example you could:

- do a sentiment analysis using apis like [aylien](https://aylien.com/text-api/)
- check the spam score of your email with [spamcheck](https://spamcheck.postmarkapp.com/)

You can clone the demo's [git repository](https://github.com/mikeeus/vue-demo-inboxsdk) with:

```
git clone git@github.com:mikeeus/vue-demo-inboxsdk.git
```

### Create the Chrome Exenstion

Creating a Chrome extension is surprisingly simple. First we need a `manifest.json` file that will describe our extension. You can find the [Chrome manifest documentation here](https://developer.chrome.com/extensions/manifest)

```json
// manifest.json
{
  "manifest_version": 2,
  "name": "Vue Pipl Search",
  "version": "1.0",
  "permissions": [
    "https://mail.google.com/",
    "https://inbox.google.com/",
    "https://api.pipl.com/",
    "https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js",
    "https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"
  ],
  "content_scripts" : [
    {
      "matches": ["https://mail.google.com/*", "https://inbox.google.com/*"],
      "js": ["inboxsdk.js", "app.js"]
    }
  ],
  "web_accessible_resources": [
    "icon.png"
  ],
  "icons": {"128": "icon.png"}
}
```
We want to use the `2.0` version of the manifest. We'l call our extension "Vue Pipl Search" and make it version `1.0`.

Since we want our extension to work on Gmail, we're going to add `https://mail.google.com/` and `https://inbox.google.com/` to our permissions. We'll also add `pipl.com` and our `vue.js` and `axios.min.js` cdn links because we'll be using them in our app.

Next we'll add a `content_scripts` key which tells Chrome that we want to run the `inboxsdk.js` and our `app.js` scripts when the brower is on `mail.google.com` or `inbox.google.com`.

Lastly we'll declare `icon.png` in the `web_accessible_resources` array and as our `icon` for the extension. Declaring it as web accessible allows us to load it later on using InboxSDK.

### InboxSDK

Before we can use the InboxSDK we need an AppId which we [can get from here]( https://www.inboxsdk.com/register). And we'll include the `inboxsdk.js` file which we can [download from here](https://www.inboxsdk.com/build/inboxsdk.js).

Now let's create our `app.js` file which will use InboxSDK to add our extension to Gmail.


```javascript
// app.js

InboxSDK.loadScript('https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js')
InboxSDK.loadScript('https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js')

// Load InboxSDK 1.0 using our AppID
InboxSDK.load('1.0', 'INBOX_SDK_APP_ID').then(function(sdk){
  // the SDK has been loaded
  // We want to register a view handler on the Compose view
  sdk.Compose.registerComposeViewHandler(function(composeView){
    // a compose view has come into existence, do something with it!
    composeView.addButton({
      title: "Vue Pipl Search",
      iconUrl: chrome.extension.getURL('icon.png'),
      onClick: function(event) {
        sdk.Widgets.showModalView({
          title: 'Vue Pipl Search',
          'el': `<div id="vue-pipl-search"></div>`,
        });

        // new Vue(...)
      },
    });
  });
});
```

Once the updated version of InboxSDK is loaded with `InboxSDK.load` we can use `sdk.Compose` to register a view handler and add a button on the Compose email view that will launch our Vue component. Inside the popup we'll render a div with `id='vue-pipl-search'` that will be picked up by the Vue component.

### Vue Component

Now we can define our Vue component. We do this in the `onClick` handler so that it is defined after the `#vue-pipl-search` element exists on the page. Also we need a [sample Api key from Pipl](https://pipl.com/api/demo).

In order for the Vue component to get the email's recipients, we can use [InboxSDK's composeView](https://www.inboxsdk.com/docs/#ComposeView) methods. `composeView.getToRecipients()` will return an array of the recipients, so we can get the email address with `recipients[0].emailAddress`.

Putting this together we get the following.

```javascript
// app.js

InboxSDK.load('1.0', 'INBOX_SDK_APP_ID').then(function(sdk){
  sdk.Compose.registerComposeViewHandler(function(composeView){
    composeView.addButton({
      // ...
      onClick: function(event) {
        // ...

        const vuePiplSearch = new Vue({
          el: '#vue-pipl-search',
          template: `
            <div>
              <template v-if="recipients.length">
                <div v-if="person" style="text-align: center;">
                  <h2 style="text-align: center">
                    {{person.names[0].display}}
                  </h2>
                  <img :src="person.images[0].url" width="80px">
                  <p v-if="person.jobs[0]">{{person.jobs[0].title}}</p>
                </div>
                <div v-else>
                  Person was not found.
                </div>
              </template>
              <div v-else>
                Add an email recipient to search Pipl Api.
              </div>
            </div>
          `,

          data() {
            return {
              recipients: composeView.getToRecipients(),
              person: null
            }
          },

          created() {
            if (this.recipients.length) {
              this.loading = true

              axios.get(`https://api.pipl.com/search/v5/?email=${this.recipients[0].emailAddress}&key=[PIPL_SAMPLE_KEY]`)
                .then(res => {
                  if (res.status === 200) {
                    this.person = res.data.person;
                    this.loading = false
                  }
                })
            }
          }
        })
      },
    });
  });
});
```

When the component is created we check for recipients then make a request to Pipl. We store the result in the data property which will render in the template.

This is super simple, but we can expand on it to add error handling or support for multiple recipients.

If we want to use a different Api or have a different use case we can use methods like `composeView.getHTMLContent()` to get the email body and send that to an Api.

Check out [the docs for more ideas](https://www.inboxsdk.com/docs/#ComposeView).

### Loading Extension

To run our extension we need to load it. We can zip our project and load it that way, but for this tutorial we'll just load the unpacked folder. From [Chrome's extension page](chrome://extensions/) select 'Load Unpacked` at the top left and navigate to the extensions folder then select okay. This will add the extension to chrome.

![Loading unpacked extension](https://thepracticaldev.s3.amazonaws.com/i/hg35muq31qeyhpf92cqo.png)

Now if you navigate to `gmail.com` and compose an email, you'll see the Vue icon. 

![Icon in Gmail Compose View](https://thepracticaldev.s3.amazonaws.com/i/pkcd07guuv3tpqor61p5.png)

Add "clark.kent@example.com" as the email recipient and click on the icon. A modal should open up with our Vue component in it, hooray! It searches the Pipl Api and returns the person.

![Modal with Clark Kent](https://thepracticaldev.s3.amazonaws.com/i/46uz9f2ma0xu8gae22k2.png)

Magic! Now you can begin your PI career like a boss!

Don't forget to like if you enjoyed this tutorial. Leave a comment below if you have any questions. :)