Search code examples
javascriptgoogle-chromegoogle-chrome-appcontent-scriptmessage-passing

Using content scripts/messaging with Chrome Apps (not extension) to send data


So I've been trying to send data from a web page to the Chrome Application (not Chrome Extension). Reading stuff around, according to me, this primarily would require the use of url_handlers for invoking Chrome App from a web page, content scripts to inject JS into the web page and/or Messaging for communication between Chrome Application and the web page.

Also, installed App from it's .crx, else loading unpacked directory leads to this error:

"content_scripts is only allowed for extensions and legacy packaged apps, but this is a packaged app."

Now, I tried injecting JS in the required site. However, on inspecting using Chrome Dev Tools, there's no such entry in the Sources->Content scripts section for that site. It simply didn't inject itself when using a Chrome App. It works perfectly with extensions but I want to use Chrome App for other functionalities.

As an alternative, I looked for Messaging examples where its usage is mentioned as:

"... your app or extension can receive and respond to messages from regular web pages."

But, somehow I couldn't get it working.
Any headers on either of the approaches? Other Suggestions?

manifest.json:

{
  "name": "App",
  "version": "1.0",
  "manifest_version": 2,
  "minimum_chrome_version": "31",
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "permissions": [
    {"fileSystem": ["write", "retainEntries", "directory"]},
    "storage",
    "http://example.com/*"
  ],
  "externally_connectable": {
    "matches": ["http://example.com/*"]
  },
  "content_scripts": [{
    "matches": ["http://example.com/*"],
    "js": ["content.js"]
  }]
}

Solution

  • Indeed, you can't have content scripts in an app.

    However, using externally_connectable is valid.

    You have already declared that you want to be externally connectable from example.com. (Note: be careful when defining match patterns, for instance this one does not cover www.example.com)

    In example.com's own scripts, you can then include the following:

    chrome.runtime.sendMessage("idOfYourAppHere", message, function(response) {
      /* ... */
    });
    

    And in the app (probably its background script) you can catch that with

    chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
      /* ... */
      sendResponse(response); 
    });
    

    This does require you to know the ID in advance. You can pin it by packing your extension and extracting the "key" field from the manifest. See this question for some more details.