chrome extension to Send Message from popup to content script - javascript

I,am developing an extension in which i have to extract data from linkedin profile page when user press button on popup. I,am passing message from the popup.js page to contentscript and in response i will get data extracted from linkedin profile page by contentscript so that i can display it in popup.html. But I,am getting error when i inspected the popup.html. The error is:
Port: Could not establish connection. Receiving end does not exist. lastError:29
Error in event handler for 'undefined': Cannot read property 'farewell' of undefined
TypeError: Cannot read property 'farewell' of undefined
at chrome-extension://kdfgoafjicddfffdbfofdmckejemfije/popup.js:6:25
at <error: illegal access>
at Event.dispatchToListener (event_bindings:356:21)
at Event.dispatch_ (event_bindings:342:27)
at Event.dispatch (event_bindings:362:17)
at Object.chromeHidden.Port.dispatchOnDisconnect (miscellaneous_bindings:258:27)
For reference, my manifest file is:
{
"name": "SoftwareGrid",
"version": "0.5",
"icons": { "16": "icons/16.png","48": "icons/48.png", "128": "icons/128.png" },
"description": "Shows user cresidentials on Linkedin",
"permissions": [
"cookies",
"tabs",
"http://www.linkedin.com/*"
],
"browser_action": {
"default_title": "Show Profile",
"default_icon": { "16": "icons/16.png","48": "icons/48.png", "128": "icons/128.png" },
"default_popup": "popup.html"
},
"background": {
"scripts": ["jquery-1.7.2.min.js","background.js"]
},
"content_scripts": [{
"matches": ["http://www.linkedin.com/*"],
"all_frames": true,
"js": ["jquery-1.7.2.min.js", "script.js"],
"run_at": "document_end"
}],
"web_accessible_resources": [
"icons/i1.png"
],
"manifest_version": 2
}
My popup.js file:
function sendClicks() {
console.log("popup.js > sendClicks()");
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
console.log("avra' inviato?");
}
$(function() {
console.log("popup.js > OMD Extension ready");
$('#sendclicks').click(function(){
sendClicks();
});
});
My contentscript file
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
Plz help!

You may have to add this in your manifest:
"permissions" : ["tabs"]

Related

using background.js service_worker on about:blank page with matchAboutBlank:true not working, any workaround?

How can I run background.js (service_worker) in about:blank pages?
I want to do some JS inside Google Slide Presenter tab that opens as "about:blank" (when launching presenter from fullscreen browser).
I set "match_about_blank" : true for content_scripts and inside background.js I also tried using matchAboutBlank: true which didn't help.
I read that activeTab doesn't work with about:blank pages in another post, is there any other way I can achieve this?
manifest.json
{
"name": "Google Slide Presenter",
"description": "Highlight speaker notes with background colour",
"version": "0.1.0",
"manifest_version": 3,
"icons": {
"16": "/images/icon-16x16.png",
"32": "/images/icon-32x32.png",
"48": "/images/icon-48x48.png",
"128": "/images/icon-128x128.png"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/icon-16x16_black.png",
"32": "/images/icon-32x32_black.png",
"48": "/images/icon-48x48_black.png",
"128": "/images/icon-128x128_black.png"
}
},
"content_scripts":[{
"matches": ["https://docs.google.com/*"],
"match_about_blank" : true,
"css": ["somecss.css"]
}],
"background": {
"service_worker": "background.js"
},
"permissions": [
"storage",
"activeTab",
"scripting",
"tabs"
],
"host_permissions": [
"https://docs.google.com/*"
]
}
background.js
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && /^http/.test(tab.url)) {
chrome.scripting.executeScript({
target: { tabId: tabId },
files: ["./foreground.js"],
matchAboutBlank: true,
})
.then(() => {
console.log("INJECTED THE FOREGROUND SCRIPT.");
})
.catch(err => console.log(err));
}
});
foreground.js
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='yellow';
UPDATE - Able to run the JS but still with errors:
using content_scripts to load the js
"content_scripts":[{
"matches": ["https://docs.google.com/*"],
"match_about_blank" : true,
"css": ["progressbar.css"],
"js": ["foreground.js"],
"all_frames":true,
"match_origin_as_fallback":true,
"run_at": "document_start"
Using in foreground.js
setTimeout(function() {
const container = document.getElementsByClassName('punch-viewer-speakernotes-text-body-zoomable')[0];
if (container.textContent.includes('Speaker')) {
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='yellow';
console.log('Speaker is contained in element');
} else {
console.log('Speaker is NOT contained in element');
document.querySelector(".punch-viewer-speakernotes-text-body-scrollable").style.backgroundColor='blue';
}
}, 5000);
CONSOLE:
Speaker is contained in element
Uncaught TypeError: Cannot read properties of undefined (reading 'textContent') at foreground.js:5:19
Uncaught TypeError: Cannot read properties of undefined (reading 'textContent') at foreground.js:5:19

send a message from content script to popup script

i'm trying to send a message from my content script to my popup script because i need to use popup DOM when a page is loaded, here's what i tried :
contentScript.js
window.addEventListener("load", function() {
chrome.runtime.sendMessage({
"action": "init"
});
})
popup.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "init") {
alert('Initialisation demandée...')
} else {
alert('Je n\'ai pas compris')
}
})
manifest.json
{
"manifest_version": 2,
"name": "Youtube color modifier",
"description": "Change youtube colors",
"version": "1.0",
"page_action": {
"default_icon": "icon.png",
"default_title": "Youtube color modifier",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
],
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["contentScript.js"]
}]
}
Thank you for helping a noob :))
If you have a content script, it will be run everytime you (re)load the page, assuming that the page you are visiting is registered in the manifest.json.
So instead of this:
window.addEventListener("load", function() {
chrome.runtime.sendMessage({
"action": "init"
});
})
simply try this:
chrome.runtime.sendMessage({
"action": "init"
});

Chrome extension send data between panel and content script

I must admit the chrome api seems confusing to me. I'm trying to create an extension (page-action) in which the content script will send a message to the popup and vice versa.
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"offline_enabled": true,
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["*://*.stackoverflow.com/*"],
"js": ["jquery.js", "content.js"],
"run_at": "document_idle",
"all_frames": false
}],
"page_action": {
"default_title": "Test Extension"
}
}
background.js:
chrome.runtime.onMessage.addListener(function (msg, sender) {
if ((msg.from === 'content') && (msg.subject === 'showPageAction')) {
chrome.pageAction.show(sender.tab.id);
}
});
chrome.pageAction.onClicked.addListener(function (tab) {
chrome.windows.create({ url: 'popup.html', type: 'panel' });
});
content.js:
chrome.runtime.sendMessage({
from: 'content',
subject: 'showPageAction'
});
Now the tricky part: Clicking a button in the popup which will send a message to the tab with the content script, the content script will run a function processing the dom and when done send a message back to the popup.

Chrome Extension - Notification on Certain Web Pages

I'm looking to pop up a chrome notification whenever the user visits certain web pages e.g. 'www.amazon.com' or 'google.com' etc. The extension loads into chrome perfectly fine with no errors, but the notification doesn't pop up when I head to those specific pages.
I currently have the below scripts.
manifest.json
{
"name": "Test",
"version": "0.0.1",
"manifest_version": 2,
"description": "This extension was created with the awesome extensionizr.com",
"homepage_url": "http://www.test.co.uk",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_locale": "en",
"background": {
"page": "src/bg/background.html",
"persistent": true
},
"options_page": "src/options/index.html",
"browser_action": {
"default_icon": "icons/icon19.png",
"default_title": "browser action demo",
"default_popup": "src/browser_action/browser_action.html"
},
"permissions": ["notifications"],
"content_scripts": [
{
"matches": ["http://www.amazon.com/*", "http://amazon.co.uk/*"],
"js": ["js/script.js"]
}
]
}
js/script.js
if(onCertainWebsitesNeedNotificationAppearTrue) {
// send message to background script
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
});
}
background.js
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
chrome.pageAction.show(sender.tab.id);
sendResponse();
});
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
//alert("good");
if (request.greeting == "hello")
createNotification();
});
function createNotification(){
var opt = {type: "basic",title: "Your Title",message: "Your message",iconUrl: "128.png"}
chrome.notifications.create("notificationName",opt,function(){});
//include this line if you want to clear the notification after 5 seconds
setTimeout(function(){chrome.notifications.clear("notificationName",function(){});},10000);
}
New to chrome extension coding so any help would be appreciated!
onCertainWebsitesNeedNotificationAppearTrue isn't defined anywhere so the code is not executed and the message is not sent.
Use the devtools debugger to diagnose the problems.
Also move the code from chrome.extension.onMessage callback inside chrome.runtime.onMessage callback and remove the former.

Chrome extension messaging from popup to content script

I'm trying to send a message from my popup.js to a content.js and I just don't get why it doesn't work.
Here is my set up:
manifest.json
{
"manifest_version": 2,
"name": "Form Builder",
"description": "This extension populates a form.",
"version": "0.1",
"content_scripts": [{
"all_frames": true,
"matches": ["http://*/*", "https://*/*"],
"js" : [
"/js/jquery/jquery.min.js",
"/js/formLoader.js",
"/js/content.js"
]
}],
"options_page": "/html/options.html",
"permissions": ["https://localhost:8443/",
"tabs", "activeTab", "storage", "background"
],
"icons": { "16": "/images/icons/wb_icon_16.png",
"48": "/images/icons/wb_icon_48.png",
"128": "/images/icons/wb_icon_128.png"
},
"browser_action": {
"default_popup": "/html/popup.html"
}
}
content.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse){
sendResponse("received message: " + request);
formLoader.setFormData(request, sendResponse);
// Why isn't this getting executed when I send a message from popup?
sendResponse("Thank you");
});
popup.js
var popup = {
// a few parts snipped out for brevity
sendMessage: function(message) {
chrome.tabs.sendMessage(tab.id, message, function(message) {
console.log(chrome.runtime.lastError);
popup.handleCallbacks(message);
});
},
handleCallbacks: function (message) {
console.log("handleCallbacks: " + message);
}
}
formLoader.js
var formLoader = {
init : function() {
$("#PostingBody").val("formLoader.init");
},
setFormData: function(data, callback) {
callback("[formLoader.js] got data: " + data);
}
}
formLoader.init();
When I do something like:
popup.sendMessage(data);
In my console I get:
Object {message: "Could not establish connection. Receiving end does not exist."}
handleCallbacks: undefined
Why isn't there a receiving end? What am I doing wrong with the listener in the content.js?
Thanks to:
This answer from another question
For Chrome 26+, use chrome.runtime.onMessage and chrome.runtime.sendMessage.
even though I'm positive I've found several pages and references that fail to mention this.

Categories