Search code examples
javascriptgoogle-chrome-extensiondojo

chrome.runtime.onMessage.addListener is undefined in content script


Im trying to send message to Background, and as well receive back to content script. enter image description here

enter image description here

This is my content_script.js

init();
function init() {
   function notifyBackgroundPage(event) {
        chrome.runtime.sendMessage(chromeExtID, {
            greeting: "Greeting from the content script"
        });
    }

    window.addEventListener("click", notifyBackgroundPage);

    // accept messages from background
    // below line addListener is undefined
    chrome.runtime.onMessage.addListener(function backgroundListener(request, sender, sendResponse) {
        console.log("BgExt.js says: " + request);
    });
  }

BgExt.js

define([], function GmailExt() {

    return {
        start: function () {

            chrome.runtime.onMessage.addListener(
                function (request, sender, sendResponse) {
                    console.log('inside response');
                    // to send back your response  to the current tab
                    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
                        chrome.tabs.sendMessage(tabs[0].id, {farewell: response}, function (response) {
                        });
                    });
                    return true;
                }
            );
        }
    };
});

This GmailExt file is loaded inside all.js (while all.js is inserted in index.html)

require([
    "base_host/chrome/Server",
    "kernel/Kernel",
    "hydra/version",
    "base_host/chrome/StartupConfig",
    "hydra/apps",
    "dojo/_base/Deferred",
    "talkto_util/common",
    "dojo/i18n!base_host/nls/CommonStrings",
    "base_host/chrome/BgExt",
    "dojo/domReady!"
], function (Server, Kernel, version, StartupConfig, apps, Deferred, talktoUtil, nls, BgExt) {
    document.getElementById("logoMessage").innerText = nls.simple_secure_text;
    var host = new Server();
    //if app and not extension
    chrome.browserAction && chrome.browserAction.onClicked.addListener(function() {
        Deferred.when(kernel.onInit(), function () {
            host.appManager.showShell();
        });
        return true;
    });

    BgExt.start();
});

client_base/host/chrome/index.html

<!DOCTYPE HTML>
<html>
<head>
    <!-- Background Page for Extension/app -->
    <title>Flock</title>
    <meta charset="UTF-8">
    <!--BUILD_REPLACE_BLOCK_START-->
    <!-- This block will be remove by build.
    All the files from libs/common/files.txt would be prepended to dojo.js -->
    <script type="text/javascript" src="../../../hydra/src/libs/common/dojoConfig.js"></script>
    <script type="text/javascript" src="../../../hydra/src/libs/common/underscore.js"></script>
    <script type="text/javascript" src="../../../hydra/src/libs/common/underscore-ext.js"></script>
    <!--BUILD_REPLACE_BLOCK_END-->
    <script type="text/javascript" src="../../../hydra/src/libs/dojotoolkit/dojo/dojo.js"></script>
    <script type="text/javascript" src="all.js"></script>
</head>
<body>

</body>
</html>

Manifest.json

    {
  "manifest_version": 2,
  "content_security_policy": "script-src 'self' 'unsafe-eval' https://j.maxmind.com https://ssl.google-analytics.com https://flock-apps.flock.co https://flock-apps.flock-staging.co https://flock-apps.flock.com https://flock-apps.flock-staging.com; object-src 'self'",
  "minimum_chrome_version": "22",

  "options_page": "client_base/host/chrome/static/crx_browser_actions/index.html?app=preferences",
  "name": "__MSG_extName__",
  "description": "__MSG_extDescription__",
  "background": {
    "page": "client_base/host/chrome/index.html",
    "persistent": true
  },

  "browser_action": {
    "default_popup": "/gmail_ext/popup.html"
  },
  "web_accessible_resources": [
    "client_base/host/chrome/static/blank.gif",
    "gmail_ext/icons.png",
    "gmail_ext/jquery-3.2.1.min.js",
    "gmail_ext/gmail.js",
    "gmail_ext/content_script.js"
  ],
  "permissions": [
    "<all_urls>",
    "unlimitedStorage",
    "notifications",
    "idle",
    "background",
    "tabs",
    "activeTab"
  ],
  "optional_permissions": [
    "clipboardWrite"
  ],
  "externally_connectable": {
    "matches": [
      "https://*.google.com/*",
      "http://localhost/*",
    ]
  },
  "content_scripts": [
    {
      "matches": [
        "*://mail.google.com/*"
      ],
      "css": [
        "/gmail_ext/content_script.css"
      ],
      "js": [
        "/gmail_ext/loader.js"
      ],
      "run_at": "document_end"
    }
  ],
  "version": "1.0"
}

Solution

  • I fixed it. The Solution was since I was using loader.js to load my content script and jquery via chrome.extension.getURL('/gmail_ext/content_script.js');

    And was using "content_script.js" as a web_accessible_resources only loader.js had access to chrome object.

    And yes, its a Dojo project, you can see the Working Extension here : https://chrome.google.com/webstore/detail/flock-chat-for-teams-and/enfaahabcinohafeakbliimmoholjeip?hl=en

    I'm using page events now as showed here : https://developer.chrome.com/extensions/content_scripts#host-page-communication

    At the top of loader.js I added below:

    function initPort() {
        var contentScriptPort,
            chromeExtID = "lddaepjihbpbfpegjhjnkffjmmoigphe";
    
        contentScriptPort = chrome.runtime.connect(chromeExtID);
    
        contentScriptPort.onMessage.addListener(function (message) {
            // Send data back to content script received from Background.
            window.postMessage({type: "FROM_BACKGROUND", emails: message}, "*");
        });
    
        window.addEventListener("message", function _postMessage(event) {
            // We only accept messages from ourselves
            if (event.source != window)
                return;
    
            if (event.data.type && (event.data.type == "FROM_PAGE")) {
                // console.log("Content script received: " + event.data.emails);
                contentScriptPort.postMessage(event.data);
            }
        }, false);
    }
    
    initPort();