Chrome Extension Access Xively - javascript

How can I access a Xively Feed through chrome extension. I am building a simple extension which will block websites depending on the value that is currently displayed on my Xively Feed. However I unsure on how to access the Xively feed without Html, I've looked at the XivelyJS library which I have used before but in a HTML page. However my extension needs to be independent of HTML.
Code Below is my attempt at using XivelyJS however I would be appreciative of an easier or better method.
Background.js:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: true};
},
{urls: ["*://www.facebook.com/*", "*://www.twitter.com/*"]},
["blocking"]);
// Set your API key first
// Get feed content
xively.setKey( "APIKEY" );
function ReadData(){
var reading = xively.datastream.get ("832936337", "Reading", callback (data));
console.log(reading);
console.log(data);
setTimeout(ReadData,3000);
}
ReadData();
Manifest.json:
{
"manifest_version": 2,
"name": "SiteBlockerFyp",
"description": "Block Respective Sites",
"version": "1",
"permissions": [
"webRequest",
"webRequestBlocking",
"*://www.facebook.com/*","*://www.twitter.com/*"
],
"content_scripts": [
{
"matches": ["*://www.facebook.com/*"],
"js": ["jquery.min.js", "xivelyjs.min.js"]
}
],
"background": {"scripts": ["background.js"]}
}

Found that I could access the values like so :
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: true};
console.log(details.url);
},
{urls: ["*://www.twitter.com/*"]},
["blocking"]);
// Set your API key first
// Get feed content
xively.setKey( "APIKEY" );
console.log("XIVELY LOADED");
var feedID = 832936337, // Feed ID
datastreamID = "Reading"; // Datastream ID
data = "null"; // Your element on the page
dataUpdated= "null";
console.log("READ ");
xively.datastream.get (feedID, datastreamID, function ( datastream ) {
data = datastream["current_value"];
console.log(data);
xively.datastream.subscribe( feedID, datastreamID, function ( event , datastream_updated ) {
dataUpdated = datastream_updated["current_value"] ;
console.log(dataUpdated);
});
});
chrome.tabs.query({'active': true, 'windowId': chrome.windows.WINDOW_ID_CURRENT},
function(tabs){
console.log(tabs[0].url);
if (tabs[0].url == "*www.twitter.com*") {
alert("Twitter");
}
}
);
subscribing also gave me updates as they occurred. However using background.js as a background script in the manifest means it wont run across all pages so I still trying to figure this one out, Content-scripts is apparently the way to go.
{
"manifest_version": 2,
"name": "SiteBlockerFyp",
"description": "Block Respective Sites",
"version": "1",
"permissions": [
"webRequest",
"webRequestBlocking",
"*://www.twitter.com/*",
"tabs"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery.min.js", "xivelyjs.min.js", "background.js"]
}
]
}

Related

Chrome extension - Execute content script for specific site url

At the moment I'm testing this code. My intention is to scrape some data using a content script
This is what I have in background file
chrome.action.onClicked.addListener( (tab) => {
// chrome.scripting.executeScript({
// target: {tabId: tab.id},
// files: ['content.js']
// })
console.log('Requesting tab: \n', tab)
chrome.windows.create({
type: 'popup',
height: 300,
width: 200,
url: chrome.runtime.getURL('popup.html')
})
})
This is what I have in my content script
console.info('chrome-ext template-vue-js content script')
const DOMnodes = document.querySelectorAll('article')
console.log(`Ecco le informazioni sui prezzi per Sole365`)
console.log('\n')
let details = []
DOMnodes.forEach( (node) => {
// Loop nodi prodotto
details.push(node.dataset)
console.log(`----\n`)
console.log(`Nome prodotto: ${node.dataset.productName}`)
console.log(`Descrizione breve: ${node.children[2].children[1].childNodes[1].childNodes[0].innerText}`)
// price
console.log(`Prezzo: ${node.childNodes[2].childNodes[1].childNodes[2].childNodes[0].innerText}`)
//console.log(``)
//descriz. breve
//node.children[2].children[1].childNodes[1].childNodes[0].innerText
})
console.log(details)
The script isn't executed when the website I set in manifest match. here is the dev version
{
"name": "create-chrome-ext",
"description": "Extract data",
"version": "1.0.0",
"manifest_version": 3,
"icons": {
"16": "img/logo-16.png",
"32": "img/logo-34.png",
"48": "img/logo-48.png",
"128": "img/logo-128.png"
},
"action": {
"default_icon": "img/logo-48.png"
},
"options_page": "options.html",
"background": {
"service_worker": "service-worker-loader.js",
"type": "module"
},
"host_permissions": [
"https://www.example.com/mypath/*/*"
],
"content_scripts": [
{
"js": [
"assets/content-script.js"
],
"matches": [
"https://www.example.com/mypath/*/*"
]
}
],
"web_accessible_resources": [
{
"matches": [],
"resources": [
"img/logo-16.png",
"img/logo-34.png",
"img/logo-48.png",
"img/logo-128.png"
],
"use_dynamic_url": false
},
{
"matches": [
"<all_urls>"
],
"resources": [
"**/*",
"*"
],
"use_dynamic_url": true
}
],
"permissions": [
"activeTab",
"tabs",
"alarms"
]
}
Any idea of why? My idea is to call the script when the icon is clicked and open a popup to get the resulting extracted data to use in vue frontent
When you reload the extension you also need to reinject the content script(s).
If the site is a modern SPA (Single Page Application) it uses fake navigation via history.pushState, so the page stays the same and the content script doesn't re-run.
To verify this is the case:
open devtools
open Network panel
click Doc in devtools toolbar filter
click a link in the page to navigate within the site
see if the request for the new URL is added to the network log
If there's no Doc request, you'll need matches for the entire site e.g. *://www.example.com/* and then either a) use MutationObserver in the content script or b) use chrome.webNavigation API onHistoryStateUpdated and onReferenceFragmentUpdated in the background script, which can be limited via URL filter to the site, the listener for these event(s) will send a message to the event's tabId, which will be received by the content script (example).

How to make Firefox WebExtension use microphone

I've been trying to make Firefox Extension which needs to have an ability for user to record a voice message.
I've made a web page which does work, but when I put the same code in the extension (with all the proper manifest.json changes), it doesn't work. It simply doesn't ask user for access to microphone.
I went through extension examples on Firefox site but I can't find the solution.
How can the extension, if it can, access users microphone?
Code:
window.addEventListener('load', initAudio);
And the initAudio function:
function initAudio() {
console.log("initAudio");
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mediaDevices.mozGetUserMedia;
if (!navigator.cancelAnimationFrame)
navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame;
if (!navigator.requestAnimationFrame)
navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame;
console.log("initAudio");
navigator.mediaDevices.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
}, gotStream, function (e) {
console.log('Error getting audio');
$("#controls").css("background", "red");
console.log(e);
});
}
I don't get console output
Error getting audio
But I also don't get the console output from gotStream function.
Later, I have an HTML object which triggers the recording process:
<img id="record" src="./res/icons/mic.png" class="">
with it's accompanying Javascript code:
$(document).ready(function () {
$("#record").click(function () {
console.log("trigerred", this);
toggleRecording(this);
});
});
function toggleRecording does get trigerred properly, but it can't work since Recorder object is not initalized (it gets initalized in gotStream function).
Here is the manifest.json file:
{
"manifest_version": 2,
"name": "Speech",
"version": "1.1",
"description": "blank desript",
"icons": {
"16": "popup/res/icons/icon16.png",
"32": "popup/res/icons/icon32.png",
"48": "popup/res/icons/icon48.png",
"128": "popup/res/icons/icon128.png"
},
"permissions": [
"storage"
],
"browser_action": {
"default_icon": {
"32": "popup/res/icons/icon.png"
},
"default_title": "Speech",
"default_popup": "popup/popup.html"
},
"content_scripts": [
{
"js": [
"popup/res/script/jquery-3.2.1.js",
"popup/res/script/audiodisplay.js",
"popup/res/script/recorder.js",
"popup/res/script/recorderWorker.js",
"popup/res/script/resampler.js",
"popup/res/script/main.js"
],
"matches": [ "<all_urls>" ],
"match_about_blank": true,
"all_frames": true
}
],
"content_security_policy": [
"script-src 'unsafe-inline'"
]
}

Chrome extension throwing a "Cannot convert undefined or null to object" error

I'm building an extension that will store a token from a chrome tab (it will take the token once you finish loading that particular tab).
When running the extension (It is run by a press of the button) it is supposed to "get" the token and use it to create an ajax call.
This is a simple explanation of what it does; this is the code:
background.js :
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'h' }
})
],
actions: [new chrome.declarativeContent.ShowPageAction()]
}]);
});
});
manifest:
{
"name": "Page action by URL",
"version": "1.0",
"description": "Shows a page action for urls which have the letter 'g' in them.",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"page_action": {
"default_icon": "images/icon32.png",
"default_title": "linkedin URL!",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js" : ["getToken.js"],
"run_at":"document_end"
}
],
"permissions": [
"storage",
"activeTab",
"tabs",
"<all_urls>",
"cookies",
"declarativeContent",
"http://*/*",
"https://*/*"
],
"icons" : {
"48" : "images/icon32.png",
"128" : "images/icon32.png"
},
"manifest_version": 2
}
getToken.js: [Content script]
if(document.getElementById('HrmsTkn')){
chrome.storage.local.set({ 'HrmsTkn': document.getElementById('HrmsTkn').value});
chrome.storage.local.get('HrmsTkn', function(result){
alert('Got it' + result.HrmsTkn);
});
}
and popup.js (button activation function):
$(function () {
$('#btnGetHtml').click(function () {
var token;
chrome.storage.local.get('HrmsTkn', function (items) {
if(items){
token = items.HrmsTkn;
}
});
try {
alert(token);
}
catch(e) {
}
});
});
I get the following error in devTools and undefined alerted once the button is clicked, also I checked the storage area of the extension using StorageAreaExtension which shows the extension has the value I'm trying to get.
And when I debug it, in the storage.local.get function, it throws the following error:
Lazy require of extension.binding did not set the binding field
extensions::lastError:82: Uncaught TypeError: Cannot convert undefined
or null to object{TypeError: Cannot convert undefined or null to
object
Any ideas why? I've looked up google for the past few days but did not find any reliable fix.

Unable to fire notification from content script

I am unable to fire a notification from my Chrome extension. I am aware that we cannot fire it directly from a content script, which is the reason I have the notification code in the background.js file. But, that still isn't working. I need your help in figuring out how to display notifications from a Chrome extension.
Content Script:
{
"name": "test",
"version": "0.0.1",
"manifest_version": 2,
"description": "xdsfds",
"author": "Miraj",
"background": {
"scripts" : ["background.js"],
"persistent" : false
},
"content_scripts": [
{
"matches": ["https://google.com/*","file:///*/Desktop/extensionPage.html"],
"js": ["/js/lib/jquery-3.1.1.min.js",
"/js/lib/bootstrap.min.js",
"/js/lib/angular.min.js",
"/js/lib/idbstore.js",
"/js/contentScript.js",
"/js/angJs/main.js",
"/js/angJs/communiqueService.js",
"/js/angJs/commTrackerDir.js"],
"css": ["/css/sforce.css",
"/css/main.css"]
}
],
"web_accessible_resources": [
"/templates/*"
],
"permissions": [
"cookies",
"unlimitedStorage",
"notifications"
]
}
Background.js
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
alert('i am listening'); //this is getting invoked
var opt = {
type: "basic",
title: "Primary Title",
message: "Primary message to display",
iconUrl: '/images/notification.png'
};
chrome.notifications.create(new Date().getTime(), opt, function(rs){
alert(rs);
});
sendResponse({returnMsg: "All good!"}); // optional response
});
ContentScript.js
chrome.extension.sendMessage({msg: "Sup?"}, function(response) {
// optional callback - gets response
console.log(response);
});
The first argument for chrome.notifications.createshould be a string. new Date().getTime() returns an integer. You could use ""+new Date().getTime() to convert it to a string.

How can I call functions defined in a Chrome Extension from regular websites?

I'd like to make a website that is not part of the chrome plugin but rather just uses some API that the plugin exposes to it. Is this possible and if so, how do I do it? I googled this question and was unable to find anything.
I'm trying to use content scripts but nothing happens. Can someone explain what's wrong here?
manifest.json
{
"manifest_version": 2,
"name": "Hello World Extension",
"description": "This extension prints hello world.",
"version": "1.0",
"background": {
"page": "background.html"
},
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://locahost:8888/*"],
"js": ["EmotivAPI.js"]
}
]
}
EmotivAPI.js
var port = chrome.runtime.connect();
console.log("Hello?");
window.addEventListener("message", function (event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
alert("recieved!");
}
}, false);
js in the webpage
window.sayHello = function () {
window.postMessage({ type: "FROM_PAGE", text: "Hello from webpage!" }, "*");
}
console.log('Emotiv extension loaded.');
}
I'm calling window.sayHello() from the console
Content Scripts can help you in this case.
The content script will be injected into a page:
"content_scripts": [
{
"matches": ["http://www.google.com/*"], // try with "http://localhost:*/*" or "http://localhost:*"
"css": ["mystyles.css"],
"js": ["content_script.js"]
}
]
If you want to inject the code only sometimes, use the permissions field instead
/* in manifest.json */
"permissions": [
"tabs", "http://*/*"
],
In you extension html file, you can then execute the script by:
chrome.tabs.executeScript(null, {file: "content_script.js"});

Categories