loading...

Building Gmail/Chrome Extension with Vue.js and InboxSDK

mikeeus profile image Mikias Abera ・4 min read

We’re going to create a small Chrome extension that uses InboxSDK and Pipl 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
  • check the spam score of your email with spamcheck

You can clone the demo's git repository 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

// 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. And we'll include the inboxsdk.js file which we can download from here.

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

// 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.

In order for the Vue component to get the email's recipients, we can use InboxSDK's 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.

// 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.

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 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

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

Icon in Gmail Compose View

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

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. :)

Discussion

markdown guide
 

This sounds like an interesting concept. I've personally never heard of Pipl until now. But now that I know of it, I'm already concerned of it. I looked up one of my main email addresses, and their system matched it to someone else with a similar name, and then pulled in all of that person's other resources... So it has me "profiled" as someone several years younger, living on the opposite side of the country. I can already see the inaccuracies in their database leading to confusion and possibly worse.

 

I absolutely agree with you. I was looking for Apis that I use for this example and Pipl worked really well, but it does make you question your privacy and the security of the information you put online. After using it I've come to understand that nothing we put online is private, and that is a bit scary.

 

Well, for me, it wasn't a privacy concern. It wasn't even my information, and THAT is my concern. Their automated process linked MY email address to SOMEONE ELSE'S information. That means if I sent someone an email, and that used your tool, my reputation is at the stake of some random stranger on the other side of the country. It is linking to their Facebook profile (only because their name is similar, NOT because of an email address or any other kind of match), so anything that person says or does, a potential employer or contractor could see that and easily just assume it was me... THAT is very scary.

Was that person the only result it returned or did it also return yours? I think the services tries to match multiple possible people given the information you provide.

If it only returned a completely different person and not you when the email you gave is used for social media, then they must have a serious flaw in their back-end logic.

I wasn't listed at all. That's the scary part. It listed my business name along with this other person's personal details. If I search for other email addresses I've used in the past, it finds me, but my primary email address from the past 10 years or so displays this entirely different person.

Additionally, the email address in question is @ my own domain name, so there should be absolutely zero confusion, because I'm the only person in the entire world with an email address with this domain.

Wow that's really weird. I'm curious to know what kind of algorithm they use to match people with their emails, and what caused this kind of confusion. It must have been a little frightening to see someone else come up when you search me@mydomain.com though lol.

The other person has a similar real name, that's it. But anyone building a site like that SHOULD know how common duplicate names are though! hahahahahaaa

 

This should be called "Building a Gmail/browser extension…", because you can actually do it in nearly the same way in Firefox e.g. (or Edge/others if they support browser/WebExtensions)…

 

That's a good point! InboxSDK makes it simple to work with Gmail on any browser and isn't specific to Chrome.

 

This is so cool @Mikias

Can a similar implementation be done with Angular?

 

Hey Shyamal, yeah you definitely can! If I have time to create an example I will let you know.

 

Thanks a lot Mikias, looking forward to the post!