Chrome Extension. chrome.runtime.onMesasgeExternal - google-chrome-extension

I cant connect with my extension.
I'm trying to connect, Im using repl.it to test but nothing.
My main.js
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
console.log('Success!!');
console.log(request, sender, sendResponse);
}
);
My code in repl.it
chrome.runtime.sendMessage("hpibninopnnoohihjplmdcmjfkeepahh", {message: "Hello"}, function (response) {
console.log("Response: ", response);
})
My manifest.json
{
"manifest_version": 2,
"name": "Example",
"description": "Trying to connect",
"version": "0.1",
"externally_connectable": {
"matches": [
"https://repl.it/Ngjk"
]
},
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["main.js"],
"persistent": true
},
"permissions": [
"activeTab",
"tabs",
"background"
]
}
I can't see the problem, other code works well but I cant connect and I dont know why.

You should modify your main.js.
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
console.log('Success!!');
console.log(request, sender, sendResponse);
sendResponse({myResponse: 'hello'});
});
Moreover, you can add console.log(chrome.runtime.lastError ); inside your chrome.runtime.onMessageExternal.addListener to see errors if any.
EDIT
Your code will work if you open chrome dev tools on https://repl.it/Ngjk and run it in console. However, it doesn't work on https://repl.it/ because it is being executed from address about:blank.

Related

trying to execute JS code on a tab but getting executeScript is undefined [duplicate]

Why is this function from Chrome not working? I'm trying this example:
https://developer.chrome.com/docs/extensions/mv3/content_scripts/#programmatic.
I'm developing an extension for chrome and sending a message from popup.js to service worker background.js and get error in executeScript.
popup.js
chrome.runtime.sendMessage({ from: "newScript"});
manifest.json
{
"manifest_version": 3,
"name": "TennisBet",
"version": "1.0",
"description": "Extrension for bet on tennis.",
"action": {
"default_icon": {
"256": "images/tennis256.png",
"128": "images/tennis128.png",
"64": "images/tennis64.png",
"32": "images/tennis32.png",
"24": "images/tennis24.png",
"16": "images/tennis16.png"
},
"default_popup": "popup/popup.html"
},
"background": {
"service_worker": "background-wrapper.js"
},
"host_permissions": ["*://*/*"],
"permissions": [
"tabs",
"alarms",
"activeTab",
"declarativeContent",
"storage"
]
}
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
switch(request.from){
case "error":
console.log(request.message);
break;
case "checkTabs":
tabsWorker();
break;
case "newScript":
chrome.scripting.executeScript({ // Error in event handler: TypeError: Cannot read property 'executeScript' of undefined
file: "content_scripts/cscript.js"
});
break;
default:
console.log("Message listener status active");
break;
}
});
The executeScript method in ManifestV3 has changed and is now in chrome.scripting API:
https://developer.chrome.com/docs/extensions/reference/scripting/
Add this line in manifest.json:
"permissions": ["scripting"]
background.js
chrome.scripting.executeScript({
target: {tabId: id, allFrames: true},
files: ['content_scripts/cscript.js'],
});

Chrome and closing a specific tab URL

I need to close a specific tab in Google Chrome.
The behaviour is that an extension open up URL after she loaded and this can't be avoid.
This doesn't work :
#manifest.json
{
"name": "Close Tab Helpx Adobe",
"description": "Close the url http://www.example.com",
"version": "0.1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"],
"persistent": false
}
},
"icons": {
"16": "close-tab-helpx-adobe-16.png",
"128": "close-tab-helpx-adobe-128.png"
},
"permissions": [
"tabs"
]
}
#background.js
chrome.tabs.onUpdated.addListener(function(tab) {
if(tab.url=="http://www.example.com") {
chrome.tabs.remove(tab)
}
});
In developper mode, i can see Uncaught TypeError: Cannot read property 'onUpdated' of undefined
As you can see, i'm a beginner.
Do you know how to achieve this ?
EDIT:
I also tried :
#background.js
chrome.tabs.onActivated.addListener(function(activeInfo) {
chrome.tabs.get(activeInfo.tabId, function(tab){
if(tab.url=="http://www.example.com") {
chrome.tabs.remove(tab);
}
});
});
chrome.tabs.getCurrent(function(tab){
if(tab.url=="http://www.example.com") {
chrome.tabs.remove(tab);
}
});
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
if(tabs[0].url=="http://www.example.com") {
chrome.tabs.remove(tabs[0]);
}
});
The error is the same, only the property name change onActivated, getcurrent or query
Thanks to wOxxOm (and his patience), here is a code which do the job :
#manifest.json
{
"name": "Close Tab Helpx Adobe",
"description": "Close the url http://www.example.com",
"version": "0.1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
},
"icons": {
"16": "close-tab-helpx-adobe-16.png",
"128": "close-tab-helpx-adobe-128.png"
},
"permissions": [
"tabs"
]
}
#background.js
chrome.tabs.onCreated.addListener(function(tab) {
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if(tab.url=="http://www.example.com") {
chrome.tabs.remove(tab.id);
}
});
});
So, i have my answer.
To go further ...
Haibara Ai says "Please be aware chrome.tabs.onUpdated will also fired for iframes, if a page contains many iframes, each completed iframe will trigger the event though you have checked : https://stackoverflow.com/a/36818991/2241806"

Can I post messages from page directly to extension's background script w/o content-script in chrome?

I created a simple chrome extension that adds some functionality to my webPage (site), that is only accessible via extension. Is it possible to postMessages directly from webpage (NOT via content-script) to extension's background-script. And if it's not, what is the use-case of chrome.runtime.connect(EXTENSION_ID);, I mean why it's accessible from web-page?
Code bellow represents how I communicate between my page and extension. It doesn't work, onConnect.addListener doesn't trigger in myExtension, port.onMessage doesn't trigger in myExtension nor in my webPage.
https://localhost:8000/myPage.html:
var port = chrome.runtime.connect("ppibnonicgkeojloifobdloaiajedhgg"); // this is extensionId I got from chrome://extension
port.onMessage.addListener(function (event) {
console.log(event);
});
port.postMessage({type: 'PYCHAT_SCREEN_SHARE_PING', text: 'start'});
background.js from my extension:
chrome.runtime.onConnect.addListener(function(port) {
console.log("Connected from new port ", port);
port.onMessage.addListener(function(msg) {
console.log("Got new message ", msg);
port.postMessage({type: "PYCHAT_SCREEN_SHARE_PING_RESPONSE", data: "successs"});
});
});
manifest.json:
{
"name": "test",
"description": "test",
"version": "1.0.0",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"permissions": [
"desktopCapture",
"tabs"
],
}
Thanks to #wOxxOm #rsanchez I should:
Use chrome.runtime.onMessageExternal in background.js
Add externally_connectable to manifest.json
https://localhost:8000:
var port = chrome.runtime.connect("ppibnonicgkeojloifobdloaiajedhgg");
port.onMessage.addListener(function (event) {
console.log(event);
});
port.postMessage({type: 'PYCHAT_SCREEN_SHARE_PING', text: 'start'});
manifest.json
{
"name": "test",
"description": "test",
"version": "1.0.0",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"permissions": [
"desktopCapture",
"tabs"
],
"externally_connectable": {
"matches": ["https://localhost:8000"]
}
}
background.js:
chrome.runtime.onConnectExternal.addListener(function(port) {
port.onMessage.addListener(function(msg) {
console.log("it works")
port.postMessage({type: "PYCHAT_SCREEN_SHARE_PING_RESPONSE", data: "successs"});
});
});

Chrome extension message passing from popup to content

I'm trying to create a chrome extension to learn front-end technologies, and got stuck on message passing between popup and content script.
The following is what I'm trying to do:
1. Let background page hold a global var.
2. When user clicking a button on the popup html, the global var is modified. Meanwhile, the popup sends the global var to the content scripts for all of the tabs.
In the background.js I have:
var settings = {
version: 1,
enabled: false
};
popup.js:
$(document).ready(function(){
$("#switcher").click(function( event ) {
event.preventDefault();
var bg = chrome.extension.getBackgroundPage();
var settings = bg.settings;
settings.enabled = !settings.enabled;
// send message to the content for all the tabs
chrome.tabs.query({active: true}, function (tabs) {
for (var i = 0; i < tabs.length; ++i) {
console.log("sending message to tab " + i);
chrome.runtime.sendMessage(tabs[i].id, {enabled: settings.enabled}, function(response) {
console.log(response);
});
}
});
});
});
Finally, the content.js:
$(document).ready(function(){
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
console.log("request is: " + request.enabled);
sendResponse("get it");
}
);
});
I tried to debug it, but I found the 'sendMessage' function never got returned back.. and the 'onMessage' never got triggered. Did I miss something?
My manifest file:
{
"name": "__MSG_appName__",
"version": "0.0.1",
"manifest_version": 2,
"description": "__MSG_appDescription__",
"icons": {
"16": "images/icon-16.png",
"128": "images/icon-128.png"
},
"default_locale": "en",
"permissions": [
"contextMenus", "storage", "tabs"
],
"background": {
"scripts": [
"scripts/background.js"
],
"persistent": true
},
"browser_action": {
"default_icon": {
"19": "images/icon-19.png",
"38": "images/icon-38.png"
},
"default_popup": "popup.html"
},
"content_scripts": [
{
"run_at":"document_start",
"all_frames":true,
"matches": ["*://*/*"],
"js": ["bower_components/jquery/dist/jquery.min.js", "scripts/content.js"]
}
],
"web_accessible_resources": ["bower_components/jquery/dist/jquery.min.map"]
}
You should be using chrome.tabs.sendMessage instead of chrome.runtime.sendMessage to send messages to content scripts in tabs.

Getting Port: Could not establish connection. Receiving end does not exist. and nothing has worked. Literally

So, I've looked into every other Stack Overflow post on this topic, changed everything I could line by line, and nothing is working. (Nevermind that 99% of this code is straight off dev.google.com) No matter what I try, I get the error mentioned in the title. There doesn't seem to be an explanation, so I'm hoping this group can spot the potentially stupid thing I'm missing. Thanks!
Manifest.json
{
"manifest_version": 2,
"name": "Topic Fetch",
"description": "This extension extracts the meta keywords from a news article and give you related articles from Google News",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_title" : "Get Related Links"
},
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["Content-Script.js"],
"run_at": "document_end"
}
],
"permissions": [
"tabs","<all_urls>",
"activeTab"
]
}
background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log(tabs);
chrome.tabs.sendMessage(tabs[0].id, "message", function(response) {
alert(response);
});
});
Content-Script.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
sendResponse('Hello!');
});
EDIT: Here's the code I'm using (for the most part) and info about message passing in Chrome extensions: https://developer.chrome.com/extensions/messaging.html
Content script code won't run until you refresh the page, so it isn't listening yet. The code in the background.js is not intended to be run immediately (as you have it). It should only be run after you have confirmed that the tab is listening.
I suggest trying the opposite way first: listen with the background.js and send a message with the content script.

Resources