I read this and trying to make simple extension that is displaying notification, so I wrote the below:
// background.js
let color = '#3aa757';
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.sync.set({ color });
});
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"],
});
// Example of a simple user data object
const user = {
username: 'demo-user'
};
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// 2. A page requested user data, respond with a copy of `user`
if (message === 'get-user-data') {
showStayHydratedNotification()
sendResponse(user);
}
});
function showStayHydratedNotification() {
chrome.notifications.create('NOTFICATION_ID', {
type: 'basic',
iconUrl: '../m.png',
title: 'notification title',
message: 'notification message',
priority: 2,
buttons: [
{
title: 'Yes'
},
{
title: 'No'
}
]
})
}
And
//content-script
document.body.style.backgroundColor = 'orange';
console.log('Hello')
// 1. Send the background a message requesting the user's data
chrome.runtime.sendMessage('get-user-data', (response) => {
// 3. Got an asynchronous response with the data from the background
console.log('received user data', response);
// initializeUI(response);
});
My manifest is:
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "js/background.js"
},
"permissions": ["storage", "activeTab", "contextMenus", "scripting", "alarms", "notifications"],
"options_page": "html/options.html",
"action": {
"default_popup": "html/popup.html"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"exclude_matches": ["*://*/*business*"],
"run_at": "document_idle",
"css": ["css/my-styles.css"],
"js": ["js/content-script.js"]
}
]
}
The extension structure is:
When I load the page, everything in the extension is working fine, except the notification, it is not showing up, and I'm not getting any error:
What could be the mistake I made?
Related
I want to send a message from a content script injected in a web page to the background of the Chrome extension, but getting the famous chrome.runtime.lastError with error message 'Could not establish connection. Receiving end does not exist.'
I have the next manifest.json
{
"manifest_version": 2,
"name": "Sample Name",
"version": "1.0.0",
"description": "Sample description",
"short_name": "Short Sample Name",
"permissions": ["tabs", "https://google.com/*", "activeTab", "declarativeContent", "storage"],
"externally_connectable": {
"ids": ["{my_extension_id}"],
"matches": ["https://www.google.com/*"]
},
"content_scripts": [
{
"ids": ["{my_extension_id}"],
"matches": ["https://www.google.com/*"],
"js": [
"content.js"
],
"css": ["test.css"]
}
],
"browser_action": {
"default_title": "Sample title",
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png"
}
}
}
the next content.js
const extensionId = "{my_extension_id}";
const url = window.location.href;
function ping() {
chrome.runtime.sendMessage(extensionId, "ping", (response) => {
if (chrome.runtime.lastError) {
console.log("chrome.runtime.lastError again...");
setTimeout(ping, 1000);
} else {
chrome.runtime.sendMessage(
extensionId,
{ url: url },
function (response) {
console.log(response);
}
);
}
});
}
ping();
and the next background.js
chrome.app.runtime.onLaunched.addListener(function () {
chrome.app.window.create("window.html", {
outerBounds: {
width: 500,
height: 500,
},
});
});
chrome.runtime.onConnect.addListener((port) => {
console.log("connected ", port);
port.onMessageExternal.addListener(function (request, sender, sendResponse) {
if (blocklistedWebsite.includes(sender.url)) return;
sendResponse({
success: true,
msg: "I have received your message",
});
});
});
const blocklistedWebsite = [];
chrome.runtime.onMessageExternal.addListener(function (request, sender, sendResponse) {
sendResponse({
success: true,
msg: "I have received your message",
});
});
I tried to do it correct, but now I'm getting a message about chrome.runtime.lastError every second in the web page console. I use the latest version of Chrome.
popup.js
function start(){
let options = {
type: "basic",
title: "Primary Title",
message: "Primary message to display",
iconUrl: "/icon_128.png"
}
chrome.notifications.create(options);
}
// When the button is clicked, inject function will execute on current page
startButton.addEventListener("click", async () => {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: start,
});
});
manifest.json
{
"name": "Meet Auto Exit Bot",
"description": "Exits meet based on number of people present.",
"version": "1.0",
"manifest_version": 3,
"icons": {
"128": "icon_128.png"
},
"action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js"
},
"permissions": [
"storage",
"activeTab",
"scripting",
"notifications"
]
}
I am developing a chrome in which I am using chrome notifications to notify users. But I am not able to figure out why chrome.notifications.create is not working inside my start() function. It works when using outside the callback function.
I am working on a Chrome extension, but cannot get notifications working. the workflow is the user right clicks on a link, selects "Send Link" from the extension's context menu, then a confirmation should display as a notification.
I have followed the example posted in another question, but it does not work. No notification is shown, nothing is logged in the console and the chrome.runtime.lastError is always "undefined". It's like the whole thing is just ignored. This is on Windows 10. What am I doing wrong?
script.js
function getlink(info,tab) {
var opt = {
iconUrl: "http://www.google.com/favicon.ico",
type: 'list',
title: 'Primary Title',
message: 'Primary message to display',
priority: 1,
items: [{ title: 'Item1', message: 'This is item 1.'},
{ title: 'Item2', message: 'This is item 2.'},
{ title: 'Item3', message: 'This is item 3.'}]
};
chrome.notifications.create('notify1', opt, function() { console.log('created!'); });
alert(chrome.runtime.lastError); //always undefined
}
chrome.contextMenus.create({
title: "Send link",
contexts:["link"],
onclick: getlink
});
manifest.json
{
"manifest_version": 2,
"version": "1.0",
"name": "ext1",
"description": "Extension1",
"icons": {
"16": "images/img16.png",
"48": "images/img48.png",
"128": "images/img128.png"
},
"browser_action":
{
"default_icon": "images/img128.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs",
"contextMenus",
"*://*/*",
"notifications"
],
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": ["styles.css"],
"js": ["getDescription.js"]
}
],
"background": {
"scripts": ["script.js"]
}
}
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.
I'm trying to get my page action icon to show on a specific url. I've tried implementing the examples here but these require the trunk/dev release.
The current code I have is taken from a SO answer. But this doesn't seem to work because the tab object never has a url property in my testing to be able to restrict on.
// background.js
function checkURL(tabId, info, tab) {
if (info.status === "complete") {
if (tab.url) {
// restrict here
chrome.pageAction.show(tabId);
}
}
}
chrome.tabs.onUpdated.addListener(checkURL);
// manifest
{
"manifest_version": 2,
"name": "My first extension",
"version": "1.0",
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"js": [
"script.js"
],
"run_at": "document_idle"
}
],
"background": {
"page": "background.html",
"persistent": false
},
"page_action": {
"default_icon": "icon.png"
}
}
What am I doing wrong?
This works for me:
//background.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (~tab.url.indexOf('.pl')) {
chrome.pageAction.show(tabId);
}
});
//manifest.json
"permissions": [
"tabs"
]
and I'm not using persistent:false
I'm late to answer this, but this may help anyone else having the same issue. I just spent about 20 minutes looking for it for my own extension.
Look here https://developer.chrome.com/extensions/declarativeContent
Add this to your manifest.json
"background" : {
"scripts": ["background.js"]
}
"permissions" : [
"declarativeContent"
]
Then in background.js
var rule1 = {
conditions: [
new chrome.declarativeContent.PageStateMatcher({
// If I wanted my extension to work only on SO I would put
// hostContains: 'stackoverflow.com'
// You can check out the link above for more options for the rules
pageUrl: { hostContains: 'some string' }
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
};
chrome.runtime.onInstalled.addListener(function (details) {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([rule1])
})
})