Check whether user has a Chrome extension installed
Asked Answered
C

19

139

I am in the process of building a Chrome extension, and for the whole thing to work the way I would like it to, I need an external JavaScript script to be able to detect if a user has my extension installed.

For example: A user installs my plugin, then goes to a website with my script on it. The website detects that my extension is installed and updates the page accordingly.

Is this possible?

Cockhorse answered 9/6, 2011 at 13:27 Comment(3)
Yes, it is possible to detect extensions, so long as you know your extension ID (which I'm sure you do). Check this site for more information: blog.kotowicz.net/2012/02/intro-to-chrome-addons-hacking.html Skip down to the section on 'Finding your addons one by one'. Good luck!Kathleenkathlene
The proper way to implement this is described by BJury bellow.Destructionist
this post helped: ide.hey.network/post/5c3b6c7aa7af38479accc0c7Newhouse
A
55

I am sure there is a direct way (calling functions on your extension directly, or by using the JS classes for extensions), but an indirect method (until something better comes along):

Have your Chrome extension look for a specific DIV or other element on your page, with a very specific ID.

For example:

<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

Do a getElementById and set the innerHTML to the version number of your extension or something. You can then read the contents of that client-side.

Again though, you should use a direct method if there is one available.


EDIT: Direct method found!!

Use the connection methods found here: https://developer.chrome.com/extensions/extension#global-events

Untested, but you should be able to do...

var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
Anamorphosis answered 9/6, 2011 at 13:34 Comment(12)
hmmm chrome.extension.connect only seems to work when executed from within the extension (or any extension). I need it to work from any random js script. Any ideas?Cockhorse
Strange, the documentation says it should work. "Unlike the other chrome.* APIs, parts of chrome.extension can be used by content scripts" and it lists sendRequest(), onRequest, connect(), onRequest, and getURL().Anamorphosis
@James are you executing the script that uses .connect() from a hosted script? I know Chrome tries hard not to do stuff with just local files that aren't hosted for security purposes. - Just checking.Amputee
@James the script I'm executing .connect() from is on the same server if that's what you mean?Cockhorse
I've done some research into chrome.extension, it won't work unfortunately. However, this seems promising: code.google.com/chrome/extensions/…Cockhorse
Heh, that's the method I originally posted. Just out of curiousity, why won't the chrome.extension stuff work? Is this documented somewhere? Am I interpreting what trey mean by a "content page" incorrectly?Anamorphosis
Ye basically the content page has to be part of the extension, so chrome.extension.connect cannot be executed from a js script that is not part of the extension :-/ Oh ye sorry I forgot you posted that :PCockhorse
Aha, that makes sense! Sorry you're stuck with such a hackish solution.Anamorphosis
@Amputee Any chance you could post the entire code for this on pastie.org or something like that? I am trying to achieve the same but couldn't yet.Washery
The last method is no longer valid, as connect function was moved to chrome.runtime namespace. See BJury's answer (and comments) for a more up-to-date versionCorinthians
You could add this link to add more weight to your answer : developer.chrome.com/webstore/… Also, the advantage of this method is that you do not need to know the extension's id, which is handy because you do not need any config for dev/production.Grubb
is there a compatible method for users not using chrome?Souvaine
K
151

Chrome now has the ability to send messages from the website to the extension.

So in the extension background.js (content.js will not work) add something like:

chrome.runtime.onMessageExternal.addListener(
    function(request, sender, sendResponse) {
        if (request) {
            if (request.message) {
                if (request.message == "version") {
                    sendResponse({version: 1.0});
                }
            }
        }
        return true;
    });

This will then let you make a call from the website:

var hasExtension = false;

chrome.runtime.sendMessage(extensionId, { message: "version" },
    function (reply) {
        if (reply) {
            if (reply.version) {
                if (reply.version >= requiredVersion) {
                    hasExtension = true;
                }
            }
        }
        else {
          hasExtension = false;
        }
    });

You can then check the hasExtension variable. The only drawback is the call is asynchronous, so you have to work around that somehow.

Edit: As mentioned below, you'll need to add an entry to the manifest.json listing the domains that can message your addon. Eg:

"externally_connectable": {
    "matches": ["*://localhost/*", "*://your.domain.com/*"]
},

2021 Update: chrome.runtime.sendMessage will throw the following exception in console if the extension isn't installed or it's disabled.

Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist

To fix this, add this validation inside the sendMessage callback

if (chrome.runtime.lastError) {
    // handle error 
}
Keavy answered 10/1, 2014 at 11:53 Comment(15)
This works like a charm. Another drawback is of course that you have to control the extension - you can't use this to see if an arbitrary third-party extension is installed.Conveyor
@EricP The original question stated that they were writing the extension, so the issue is moot.Keavy
You will also have to add the following to your manifest.json: "externally_connectable": { "matches": ["://.yourdomain.com/*"] }Hepato
It should be {version: '1.0'} and not {version: 1.0} or else you'll get 'Uncaught SyntaxError: Unexpected number' in extension Inspect view console.Tomfoolery
On the "checking" side (the web page trying to check availability of a given extension), chrome.runtime is undefined, chrome 36 on linux.Siegler
@niconic That doesn't sound right. Its been in Chrome since 22. (And sendMessage has been there since 26.)Keavy
@niconic This is the error you'll receive if you don't implement the "externally_connectable" property in your manifest as per noname's commentBladdernose
This didn't work for me untill I installed the extension part into a background script. Hint from Dawid Szymański's answer.Spinneret
@user This is not correct, as chrome.runtime.sendMessage is not available on the webpage side, and you get "chrome.runtime is undefined". Note that it IS available in a content script, just not a webpage. There is an open bug to fix that, but as of FF 54 it is not resolved. See bugzilla.mozilla.org/show_bug.cgi?id=1319168Schoolboy
@BillHayden thanks for clarifying. I was using a polyfill of sorts from github.com/EmailThis/extension-boilerplate that made it available. Removing the common to prevent confusion.Santonin
The extension side of the code must be declared in the background component of the app, not the content. There is no onMessageExternal availability inside content.js as per the documentation developer.chrome.com/extensions/runtime#event-onMessageExternalKwabena
FWIW, this is a Chrome-only solution — doesn't work on Firefox's new WebExtensions.Volteface
when i tried with above code my chrome Version 60.0.3112.113. every time i am getting reply object is undefined and hasExtension = false from the sendMessage().I changed version to {version: '1.0'} and my manifest file contains "background": { "scripts": ["background-script.js"], "persistent": true }, "content_scripts": [ { "js": [ "content-script.js" ], "all_frames": true, "run_at": "document_end", "matches": ["localhost:4200*","localhost:4200*"] }], "permissions": [ "management" ] Plz help meDraughts
@Draughts Its probably best you make a new question.Keavy
I am facing with error Uncaught TypeError: Cannot read properties of undefined (reading 'sendMessage')Yoong
A
55

I am sure there is a direct way (calling functions on your extension directly, or by using the JS classes for extensions), but an indirect method (until something better comes along):

Have your Chrome extension look for a specific DIV or other element on your page, with a very specific ID.

For example:

<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

Do a getElementById and set the innerHTML to the version number of your extension or something. You can then read the contents of that client-side.

Again though, you should use a direct method if there is one available.


EDIT: Direct method found!!

Use the connection methods found here: https://developer.chrome.com/extensions/extension#global-events

Untested, but you should be able to do...

var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
Anamorphosis answered 9/6, 2011 at 13:34 Comment(12)
hmmm chrome.extension.connect only seems to work when executed from within the extension (or any extension). I need it to work from any random js script. Any ideas?Cockhorse
Strange, the documentation says it should work. "Unlike the other chrome.* APIs, parts of chrome.extension can be used by content scripts" and it lists sendRequest(), onRequest, connect(), onRequest, and getURL().Anamorphosis
@James are you executing the script that uses .connect() from a hosted script? I know Chrome tries hard not to do stuff with just local files that aren't hosted for security purposes. - Just checking.Amputee
@James the script I'm executing .connect() from is on the same server if that's what you mean?Cockhorse
I've done some research into chrome.extension, it won't work unfortunately. However, this seems promising: code.google.com/chrome/extensions/…Cockhorse
Heh, that's the method I originally posted. Just out of curiousity, why won't the chrome.extension stuff work? Is this documented somewhere? Am I interpreting what trey mean by a "content page" incorrectly?Anamorphosis
Ye basically the content page has to be part of the extension, so chrome.extension.connect cannot be executed from a js script that is not part of the extension :-/ Oh ye sorry I forgot you posted that :PCockhorse
Aha, that makes sense! Sorry you're stuck with such a hackish solution.Anamorphosis
@Amputee Any chance you could post the entire code for this on pastie.org or something like that? I am trying to achieve the same but couldn't yet.Washery
The last method is no longer valid, as connect function was moved to chrome.runtime namespace. See BJury's answer (and comments) for a more up-to-date versionCorinthians
You could add this link to add more weight to your answer : developer.chrome.com/webstore/… Also, the advantage of this method is that you do not need to know the extension's id, which is handy because you do not need any config for dev/production.Grubb
is there a compatible method for users not using chrome?Souvaine
C
26

Another method is to expose a web-accessible resource, though this will allow any website to test if your extension is installed.

Suppose your extension's ID is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, and you add a file (say, a transparent pixel image) as test.png in your extension's files.

Then, you expose this file to the web pages with web_accessible_resources manifest key:

  "web_accessible_resources": [
    "test.png"
  ],

In your web page, you can try to load this file by its full URL (in an <img> tag, via XHR, or in any other way):

chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.png

If the file loads, then the extension is installed. If there's an error while loading this file, then the extension is not installed.

// Code from https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/8ArcsWMBaM4/2GKwVOZm1qMJ
function detectExtension(extensionId, callback) { 
  var img; 
  img = new Image(); 
  img.src = "chrome-extension://" + extensionId + "/test.png"; 
  img.onload = function() { 
    callback(true); 
  }; 
  img.onerror = function() { 
    callback(false); 
  };
}

Of note: if there is an error while loading this file, said network stack error will appear in the console with no possibility to silence it. When Chromecast used this method, it caused quite a bit of controversy because of this; with the eventual very ugly solution of simply blacklisting very specific errors from Dev Tools altogether by the Chrome team.


Important note: this method will not work in Firefox WebExtensions. Web-accessible resources inherently expose the extension to fingerprinting, since the URL is predictable by knowing the ID. Firefox decided to close that hole by assigning an instance-specific random URL to web accessible resources:

The files will then be available using a URL like:

moz-extension://<random-UUID>/<path/to/resource>

This UUID is randomly generated for every browser instance and is not your extension's ID. This prevents websites from fingerprinting the extensions a user has installed.

However, while the extension can use runtime.getURL() to obtain this address, you can't hard-code it in your website.

Corinthians answered 13/1, 2015 at 19:47 Comment(3)
Although this answer gets the "juice" from https://mcmap.net/q/165956/-check-whether-user-has-a-chrome-extension-installed, IMHO adds some pretty important informations such as exposing the resource in the extension and the fact that you can use an ajax request for checking for existence (Image object seems available only on HTML5 if I'm not wrong goo.gl/HBeI1i). With the info in this answer I've been able to solve the problem, I found it like an "out of the box" solutionSiegler
@niconic That answer (being bad as link-only anyway) refers to the situation before manifest version 2 came in effect. Previously, one did not need to declare resources web-accessible.Corinthians
the webpage is not allow we access to chrome-extension://Yoong
C
20

I thought I would share my research on this. I needed to be able to detect if a specific extension was installed for some file:/// links to work. I came across this article here This explained a method of getting the manifest.json of an extension.

I adjusted the code a bit and came up with:

function Ext_Detect_NotInstalled(ExtName, ExtID) {
  console.log(ExtName + ' Not Installed');
  if (divAnnounce.innerHTML != '')
    divAnnounce.innerHTML = divAnnounce.innerHTML + "<BR>"

  divAnnounce.innerHTML = divAnnounce.innerHTML + 'Page needs ' + ExtName + ' Extension -- to intall the LocalLinks extension click <a href="https://chrome.google.com/webstore/detail/locallinks/' + ExtID + '">here</a>';
}

function Ext_Detect_Installed(ExtName, ExtID) {
  console.log(ExtName + ' Installed');
}

var Ext_Detect = function (ExtName, ExtID) {
  var s = document.createElement('script');
  s.onload = function () { Ext_Detect_Installed(ExtName, ExtID); };
  s.onerror = function () { Ext_Detect_NotInstalled(ExtName, ExtID); };
  s.src = 'chrome-extension://' + ExtID + '/manifest.json';
  document.body.appendChild(s);
}

var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;

if (is_chrome == true) {
  window.onload = function () { Ext_Detect('LocalLinks', 'jllpkdkcdjndhggodimiphkghogcpida'); };
}

With this you should be able to use Ext_Detect(ExtensionName,ExtensionID) to detect the installation of any number of extensions.

Chrissychrist answered 5/12, 2012 at 23:21 Comment(8)
Looks like Google's made things more secure, I get the following error when I run Ext_Detect(): Denying load of chrome-extension://[my_extension_id]/manifest.json. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.Disaffection
I'm able to get this to work with Version 32.0.1700.107 m of Chrome as of 2/27/2014Kenrick
as @Disaffection said. Resources inside of packages using manifest_version 2 (or above) are blocked by default, and must be whitelisted for use via this property by adding to manifest.json: "web_accessible_resources": [ "manifest..json" ],Tomfoolery
Using @Keavy answer you can also pass data easily from the extension to the script (for example the extension version) and you don't need to expose any file from the extension.Tomfoolery
This worked for me best because our extension will be used across multiple domains and could not be pre-defined as new domains are added regularly. Instead of accessing manifest.json I created a new file version.json and put the version number inside. This works just the same.Shielashield
Make sure you are specifying the correct extension id. I was using the id from my published extension, when I was testing this with my development version (which had a different id).Cheri
Hint: if you get the "resources must be listed [as] web_accessible_resources" error, open a tab in chrome and visit chrome-extension://whatever-extension-id/manifest.json. This reliably displays the manifest on that tab. Search the text for "web_accessible_resources" and adjust the suggested code's src attribute to use one of the listed resources.Thereafter
this will result in "site not secure" https warnings on iOS ChromeMichaeline
M
8

Another possible solution if you own the website is to use inline installation.

if (chrome.app.isInstalled) {
  // extension is installed.
}

I know this an old question but this way was introduced in Chrome 15 and so I thought Id list it for anyone only now looking for an answer.

Machutte answered 16/2, 2012 at 16:52 Comment(3)
This works great for a Chrome App, but not for a Chrome Extension AFAIKOrdnance
Yep that website does tell you how to inline install an extension, but apparently recommends "Extensions can communicate with the embedding page via content scripts to let it know that they are already installed." instead of being able to use chrome.app.isInstalled. Confused me too...Calendar
developer.chrome.com/webstore/…Niemann
E
7

Here is an other modern approach:

const checkExtension = (id, src, callback) => {
    let e = new Image()
    e.src = 'chrome-extension://'+ id +'/'+ src
    e.onload = () => callback(1), e.onerror = () => callback(0)
}

// "src" must be included to "web_accessible_resources" in manifest.json
checkExtension('gighmmpiobklfepjocnamgkkbiglidom', 'icons/icon24.png', (ok) => {
    console.log('AdBlock: %s', ok ? 'installed' : 'not installed')
})
checkExtension('bhlhnicpbhignbdhedgjhgdocnmhomnp', 'images/checkmark-icon.png', (ok) => {
    console.log('ColorZilla: %s', ok ? 'installed' : 'not installed')
})
Enemy answered 17/7, 2020 at 1:0 Comment(3)
be sure to update the manifest to allow access to resources: "web_accessible_resources": ["icons/*.png"]Charkha
This is a great solution - works perfectly!Nonbelligerent
this will result in "site not secure" https warnings on iOS ChromeMichaeline
H
5

I used the cookie method:

In my manifest.js file I included a content script that only runs on my site:

 "content_scripts": [
        {
        "matches": [
            "*://*.mysite.co/*"
            ],
        "js": ["js/mysite.js"],
        "run_at": "document_idle"
        }
    ], 

in my js/mysite.js I have one line:

document.cookie = "extension_downloaded=True";

and in my index.html page I look for that cookie.

if (document.cookie.indexOf('extension_downloaded') != -1){
    document.getElementById('install-btn').style.display = 'none';
}
Hum answered 12/2, 2015 at 17:59 Comment(2)
I tried all solution above but doesn't work, then i see your answer, this is what i looking for!Mraz
This adds overhead to every HTTP request henceforth.Volteface
V
5

A lot of the answers here so far are Chrome only or incur an HTTP overhead penalty. The solution that we are using is a little different:

1. Add a new object to the manifest content_scripts list like so:

{
  "matches": ["https://www.yoursite.com/*"],
  "js": [
    "install_notifier.js"
  ],
  "run_at": "document_idle"
}

This will allow the code in install_notifier.js to run on that site (if you didn't already have permissions there).

2. Send a message to every site in the manifest key above.

Add something like this to install_notifier.js (note that this is using a closure to keep the variables from being global, but that's not strictly necessary):

// Dispatch a message to every URL that's in the manifest to say that the extension is
// installed.  This allows webpages to take action based on the presence of the
// extension and its version. This is only allowed for a small whitelist of
// domains defined in the manifest.
(function () {
  let currentVersion = chrome.runtime.getManifest().version;
  window.postMessage({
    sender: "my-extension",
    message_name: "version",
    message: currentVersion
  }, "*");
})();

Your message could say anything, but it's useful to send the version so you know what you're dealing with. Then...

3. On your website, listen for that message.

Add this to your website somewhere:

window.addEventListener("message", function (event) {
  if (event.source == window &&
    event.data.sender &&
    event.data.sender === "my-extension" &&
    event.data.message_name &&
    event.data.message_name === "version") {
    console.log("Got the message");
  }
});

This works in Firefox and Chrome, and doesn't incur HTTP overhead or manipulate the page.

Volteface answered 29/3, 2018 at 15:49 Comment(2)
Two issues that I see with this solution. First, if I uninstall or disable the extension, this solution provides no way of detecting this. Second, it cannot detect if the extension is not installed, as it only acts on a message event. Am I correct in assuming this?Robinette
I think we have different goals. The post above lets you know if an extension is installed in somebody's browser. Not if the "installation action" happened or if the "uninstallation action" happened. Just whether it is currently installed.Volteface
P
3

Your extension could interact with the website (e.g. changing variables) and your website could detect this.

But there should be a better way to do this. I wonder how Google is doing it on their extension gallery (already installed applications are marked).

Edit:

The gallery use the chrome.management.get function. Example:

chrome.management.get("mblbciejcodpealifnhfjbdlkedplodp", function(a){console.log(a);});

But you can only access the method from pages with the right permissions.

Philosopher answered 9/6, 2011 at 13:33 Comment(3)
ye that would require the extension to interact with every site on every tab which would be slow/difficult to implement and buggy :-/Cockhorse
The problem is that communication in the other direction (page to extension) is not possible, because of the security model of chrome. If you don't want to go the 'interacting' way, take the cookie way.Philosopher
Dear @Philosopher , chrome.management.get... , returns this error: Uncaught TypeError: Cannot read property 'get' of undefinedGranulation
O
3

You could have the extension set a cookie and have your websites JavaScript check if that cookie is present and update accordingly. This and probably most other methods mentioned here could of course be cirvumvented by the user, unless you try and have the extension create custom cookies depending on timestamps etc, and have your application analyze them server side to see if it really is a user with the extension or someone pretending to have it by modifying his cookies.

Opalina answered 9/6, 2011 at 13:36 Comment(1)
the only problem is that if a user deletes your extensions. The cookie will probably remain set.Hum
D
3

There's another method shown at this Google Groups post. In short, you could try detecting whether the extension icon loads successfully. This may be helpful if the extension you're checking for isn't your own.

Devinne answered 9/2, 2012 at 18:50 Comment(1)
Ok. How do we check if an extension icon exists?Striper
Z
3

Webpage interacts with extension through background script.

manifest.json:

"background": {
    "scripts": ["background.js"],
    "persistent": true
},
"externally_connectable": {
    "matches": ["*://(domain.ext)/*"]
},

background.js:
chrome.runtime.onMessageExternal.addListener(function(msg, sender, sendResponse) {
    if ((msg.action == "id") && (msg.value == id))
    {
        sendResponse({id : id});
    }
});

page.html:

<script>
var id = "some_ext_id";
chrome.runtime.sendMessage(id, {action: "id", value : id}, function(response) {
    if(response && (response.id == id)) //extension installed
    {
        console.log(response);
    }
    else //extension not installed
    {
        console.log("Please consider installig extension");
    }

});
</script>
Zymotic answered 30/9, 2016 at 20:59 Comment(1)
Doesn't work on Firefox WebExtensions, where externally_connectable isn't supported.Volteface
G
2

You could also use a cross-browser method what I have used. Uses the concept of adding a div.

in your content script (whenever the script loads, it should do this)

if ((window.location.href).includes('*myurl/urlregex*')) {
        $('html').addClass('ifextension');
        }

in your website you assert something like,

if (!($('html').hasClass('ifextension')){}

And throw appropriate message.

Gouveia answered 19/6, 2017 at 9:29 Comment(4)
I had tested this but the order of operations seems weird- which script gets run first etc?Narcisanarcissism
@BradyMoritz the same order as in the answer. Add the class first and then assert.Gouveia
it seemed like my content script was not necessarily running before my in-page script though?Narcisanarcissism
That, I think is easy to fix. You can make sure that your content script runs right after hitting the required URL/route using regex.have you tried that?Gouveia
L
1

Modern way to check if extension is there and also can be used with Async/Await:

$.sendMessage = (appId, request) => {
    return new Promise(resolve => {
    if (chrome.runtime)     // undefined if no extension allowed to message from this domain
        chrome.runtime.sendMessage(appId, request, response => {
            if (chrome.runtime.lastError) resolve()  // handle error because our extension's background script not there to answer
            resolve(response);  // extension background script answered
        });
    else
        resolve(); // extension not found
});

}

Languish answered 10/4, 2023 at 0:55 Comment(0)
R
0

If you have control over the Chrome extension, you can try what I did:

// Inside Chrome extension
var div = document.createElement('div');
div.setAttribute('id', 'myapp-extension-installed-div');
document.getElementsByTagName('body')[0].appendChild(div);

And then:

// On web page that needs to detect extension
if ($('#myapp-extension-installed-div').length) {

}

It feels a little hacky, but I couldn't get the other methods to work, and I worry about Chrome changing its API here. It's doubtful this method will stop working any time soon.

Rame answered 10/9, 2016 at 11:49 Comment(1)
as mentioned above- I had tested this but the order of operations seems weird- which script gets run first etc?Narcisanarcissism
N
0

If you're trying to detect any extension from any website, This post helped: https://ide.hey.network/post/5c3b6c7aa7af38479accc0c7

Basically, the solution would be to simply try to get a specific file (manifest.json or an image) from the extension by specifying its path. Here's what I used. Definitely working:

const imgExists = function(_f, _cb) {
    const __i = new Image();
    __i.onload = function() {
        if (typeof _cb === 'function') {
            _cb(true);
        }
    }
    __i.onerror = function() {
        if (typeof _cb === 'function') {
            _cb(false);
        }
    }
    __i.src = _f;
    __i = null;
});

try {
    imgExists("chrome-extension://${CHROME_XT_ID}/xt_content/assets/logo.png", function(_test) {
        console.log(_test ? 'chrome extension installed !' : 'chrome extension not installed..');
        ifrm.xt_chrome = _test;
        // use that information
    });
} catch (e) {
    console.log('ERROR', e)
}
Newhouse answered 20/1, 2019 at 22:33 Comment(1)
this will result in "site not secure" https warnings on iOS ChromeMichaeline
M
0

Here is how you can detect a specific Extension installed and show a warning message.

First you need to open the manifest file of the extension by going to chrome-extension://extension_id_here_hkdppipefbchgpohn/manifest.json and look for any file name within "web_accessible_resources" section.

<div class="chromewarning" style="display:none">
    <script type="text/javascript">
                            $.get("chrome-extension://extension_id_here_hkdppipefbchgpohn/filename_found_in_ web_accessible_resources.png").done(function () {
                              $(".chromewarning").show();
                            }).fail(function () {
                             //  alert("failed.");
                            });
                        </script>
                        <p>We have detected a browser extension that conflicts with learning modules in this course.</p>
            </div>
Millett answered 28/10, 2020 at 11:21 Comment(1)
this will result in "site not secure" https warnings on iOS ChromeMichaeline
O
0

Chrome Extension Manifest v3:

const isFirefox = chrome.runtime.OnInstalledReason.CHROME_UPDATE != "chrome_update";

For FireFox, I believe chrome.runtime.OnInstalledReason.BROWSER_UPDATE will be "browser_update": https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/OnInstalledReason

Orford answered 31/12, 2022 at 23:18 Comment(0)
R
0

I wrote API which will count the installations for chrome & firefox. Called this API from background.js or extension. Register background.js in manifest.json for both chrome & firefox.

I'm passing browser name while making API call.

Chrome

function handleInstalled(details) {
    if (details.reason == 'install') {
        fetch('https://YOUR_API_URL/api/browser-extension', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ browser: 'chrome' }),
        })
            .then((response) => response.json())
            .then((response) => console.log(response))
            .catch((error) => console.error(error))
    }
}

chrome.runtime.onInstalled.addListener(handleInstalled)

Firefox

function handleInstalled(details) {
    if (details.reason == 'install') {
        fetch('https://YOUR_API_URL/api/browser-extension', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ browser: 'firefox' }),
        })
            .then((response) => response.json())
            .then((response) => console.log(response))
            .catch((error) => console.error(error))
    }
}

browser.runtime.onInstalled.addListener(handleInstalled)
Retharethink answered 11/3, 2023 at 7:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.