0

I am trying to list labels using Gmail api. I want to use Gmail api in content script. Following is my manifest.json file and content script file:

{
  "name": "Append Test Text",
  "description": "Add test123 to body",
  "version": "1.0",
  "permissions": ["activeTab"],
  "content_scripts": [
    {
      "matches": ["https://mail.google.com/*"],
      "js": ["jquery-3.4.1.min.js", "gmail.js", "content-script.js"],
      "all_frames": true
    }
  ],
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "browser_action": {
    "default_title": "Append Test Text"
  },
  "manifest_version": 2
}

content-script.js:

// Client ID and API key from the Developer Console
var CLIENT_ID = "<CLIENT_ID>";
var API_KEY = "<API_KEY>";

// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = [
  "https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"
];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/gmail.readonly";

/**
 *  On load, called to load the auth2 library and API client library.
 */
function handleClientLoad() {
  console.log("hello");
  gapi.load("client:auth2", initClient);
}

/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
  gapi.client
    .init({
      apiKey: API_KEY,
      clientId: CLIENT_ID,
      discoveryDocs: DISCOVERY_DOCS,
      scope: SCOPES
    })
    .then(
      function() {
        // Listen for sign-in state changes.
        gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

        // Handle the initial sign-in state.
        updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
      },
      function(error) {
        console.log(JSON.stringify(error, null, 2));
      }
    );
}

/**
 *  Called when the signed in status changes, to update the UI
 *  appropriately. After a sign-in, the API is called.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    listLabels();
  } else {
    gapi.auth2.getAuthInstance().signIn();
  }
}

/**
 * Print all Labels in the authorized user's inbox. If no labels
 * are found an appropriate message is printed.
 */
function listLabels() {
  gapi.client.gmail.users.labels
    .list({
      userId: "me"
    })
    .then(function(response) {
      var labels = response.result.labels;
      console.log("Labels:");

      if (labels && labels.length > 0) {
        for (i = 0; i < labels.length; i++) {
          var label = labels[i];
          console.log(label.name);
        }
      } else {
        console.log("No Labels found.");
      }
    });
}
var script = $(
  '<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === "complete") this.onload()"></script>'
);
$("body").append(script);

after running this there should at least be a "hello" in the console proving that the handleClientLoad() function is working. But nothing shows in the console.

3
  • The main problem is that you add the script into the page context but content scripts run in the isolated world context where they can't access the variables/functions created by a page script such as the one you're adding. You should either put your entire code inside another script element or query the API in your background script (that will require a separate entry for the API URL in "permissions" too. Commented Sep 26, 2019 at 9:30
  • @wOxxOm, I tried with putting entire code inside another script element. It doesn't work either. Commented Sep 26, 2019 at 10:33
  • Assuming you've reloaded the extension, you need to debug it. Like add console.log or debugger statements where needed. BTW I don't think the code in the inline attribute onload will run. I think you should add that as in a normal event listener for load event in your js script. Commented Sep 26, 2019 at 10:39

1 Answer 1

4

Technically, Chrome won't allow you to do that. If you use content script to inject into a website then you can just send request only on that site, if you're trying to send a request into another site, Chrome will stop you due to CORS policy.

So to achieve it, you have to setup a background script which receive passed messages from your content script and then send request into Google API endpoint and then you can return the result into your content script via defined message channel. Here is how you can setup message passing in Chrome Extension.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.