manifest.json
{
"name": "Omegle IP",
"version": "0.5",
"options_page": "options.html",
"options_ui": {
"page": "options.html",
"open_in_tab": false
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"manifest_version": 2,
"description": "Become a Hacker; You see the IP in the chat window",
"permissions": ["tabs", "https://*.omegle.com/*", "storage"],
"web_accessible_resources": ["inject.js"],
"content_scripts" : [{
"matches" : ["https://*.omegle.com/*"],
"run_at": "document_end",
"js" : ["contentscript.js"]
}],
"icons": {
"16": "16.png",
"32": "32.png",
"48": "48.png",
"128": "128.png"
}
}
contentscript.js
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
inject.js
chrome.storage.sync.get(['tracker', 'api'], function (obj) {
tracker = obj.tracker;
api = obj.api;
getIp(tracker, api);
});
function getIp(tracker, api){
console.log(tracker + api)
}
I cant access chrome.storage.sync.get from inject.js. But I need to... Is there a way to put the chrome request to the contentscript and pass the variables to inject.js
contentscript.js basically just creates a script field and puts the inject.js into it.
the inject.js file is normally larger, but you dont need all of that
There is a post "https://stackoverflow.com/questions/9515704/use-a-content-script-to-access-the-page-context-variables-and-functions" how to implement this, i tried but i didnt achieve to get it to work...
Could you please provide a working method, to get it to work?
Update:
contentscript.js
chrome.storage.sync.get(['tracker'], function (obj) {
tracker = obj.tracker;
ChromeExtensionData(tracker);
});
function ChromeExtensionData(tracker) {
var data = {
tracker: tracker,
};
console.log("Sending:", tracker); // works
console.log(document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data }))); // true
}
inject.js
document.addEventListener('ChromeExtensionData', function (e) {
var tracker = e.detail;
console.log('received', tracker);
});
getIp(tracker); // tracker is not definied
Its in the comments whats wrong. And i really dont know why
Update:
inject.js
document.addEventListener('ChromeExtensionData', function (e) {
console.log("Recieved"); // test -> doesnt work
var tracker = e.detail;
console.log('received', tracker); // doenst log anything
getIp(tracker);
});
contentscript.js
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
chrome.storage.sync.get(['tracker'], function (obj) {
tracker = obj.tracker;
ChromeExtensionData(tracker);
});
function ChromeExtensionData(tracker) {
jsontracker = JSON.stringify(tracker);
var data = {
tracker: jsontracker
};
console.log("Sending:", tracker); // works
document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data }));
}
Working Answer
inject.js
document.addEventListener('ChromeExtensionData', function (e) { // waits for variable from contentscript
var data = e.detail;
tracker = data.tracker;
trollChecked = data.trollChecked;
getIp(tracker, trollChecked);
});
contentscript.js
var s = document.createElement('script');
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
chrome.storage.sync.get(['tracker', 'troll'], function (obj) {
tracker = obj.tracker;
trollChecked = obj.troll
var data = {
tracker: tracker,
trollChecked: trollChecked
};
document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data })); // gets variable from optionspage and sends to the script
});
};
(document.head || document.documentElement).appendChild(s);
You can learn how to set chrome variables from here
Big Shoutout to wOxxOm for helping me and making this result possible
Related
I am working on building a Javascript (in-browser) Instagram bot. However, I ran into a problem.
If you run this script, the first function will be called and the page will be redirected to "https://www.instagram.com/explore/tags/samplehashtag/" and the second function will be called immediately after (on the previous URL before the page changes to the new URL). Is there a way to make the second function be called after this second URL has been loaded completely?
I have tried setting it to a Window setInterval() Method for an extended time period, window.onload and a couple of other methods. However, I can't seem to get anything to work. Any chance someone has a solution?
This is my first chrome extension and my first real project, so I may be missing something simple..
manifest.json
{
"name": "Inject Me",
"version": "1.0",
"manifest_version": 2,
"description": "Injecting stuff",
"homepage_url": "http://danharper.me",
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
inject.js
(function() {
let findUrl = () => {
let hashtag = "explore/tags/samplehashtag/";
location.replace("https://www.instagram.com/" + hashtag);
}
findUrl();
})();
background.js
// this is the background code...
// listen for our browerAction to be clicked
chrome.browserAction.onClicked.addListener(function(tab) {
// for the current tab, inject the "inject.js" file & execute it
chrome.tabs.executeScript(tab.ib, {
file: 'inject.js'
});
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.executeScript(tab.ib, {
file: 'inject2.js'
});
});
inject2.js
(function() {
if (window.location.href.indexOf("https://www.instagram.com/explore/tags/samplehashtag/") != -1){
let likeAndRepeat = () => {
let counter = 0;
let grabPhoto = document.querySelector('._9AhH0');
grabPhoto.click();
let likeAndSkip = function() {
let heart = document.querySelector('.glyphsSpriteHeart__outline__24__grey_9.u-__7');
let arrow = document.querySelector('a.coreSpriteRightPaginationArrow');
if (heart) {
heart.click();
counter++;
console.log(`You have liked ${counter} photographs`)
}
arrow.click();
}
setInterval(likeAndSkip, 3000);
//alert('likeAndRepeat Inserted');
};
likeAndRepeat();
}
})();
It is not clear from the question and the example, when you want to run your function. But in chrome extension there is something called Message Passing
https://developer.chrome.com/extensions/messaging
With message passing you can pass messages from one file to another, and similarly listen for messages.
So as it looks from your use case, you can listen for a particular message and then fire your method.
For example
background.js
chrome.runtime.sendMessage({message: "FIRE_SOME_METHOD"})
popup.js
chrome.runtime.onMessage.addListener(
function(request) {
if (request.message == "FIRE_SOME_METHOD")
someMethod();
});
EDIT
Also if you want to listen for the URL changes, you can simply put a listener provided as in the documentation.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
console.log('updated tab');
});
I want to get some values of the JSON object in the code of chrome. tabs. executeScript and send them out, but the value of JSON in the code is always undefined. Why?
Here's my bacground. JS code:
chrome.extension.onRequest.addListener(({ tabId, args }) => {
chrome.tabs.executeScript(tabId, {
code: `
var value = ${JSON.stringify(args)};
var obj = value.trans_result;
console.log(obj);
var sendData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8088/info?str="+sendData, true);
xhr.send();
}
`,});
});
Here's my manifest.json.JS code:
{
"name": "chrome-extension-example",
"version": "1.0",
"minimum_chrome_version": "10.0",
"description": "test",
"devtools_page": "index.html",
"icons":
{
"16": "img/icon.png",
"48": "img/icon.png",
"128": "img/icon.png"
},
"page_action":
{
"default_icon": "img/icon.png",
"default_title": "hello...",
"default_popup": "popup.html"
},
"background": { "scripts": ["background.js"] },
"permissions": [
"tabs",
"declarativeContent",
"https://fanyi.baidu.com/*",
"http://localhost:8080/*"
],
"manifest_version": 2
}
and my manifest.json.JS code:
const log = (...args) => chrome.extension.sendRequest({
tabId: chrome.devtools.tabId,
args,
});
chrome.devtools.network.onRequestFinished.addListener(async (...args) => {
try {
const [{
request: { method, queryString, url },
getContent,
}] = args;
//log(method, queryString, url);
const content = await new Promise((res, rej) => getContent(res));
log(content);
} catch (err) {
log(err.stack || err.toString());
}
});
thank you very much!
The code that is executed by chrome.tabs.executeScript takes what you wrote there and interprets it in that tab's space. So it's using the value of args that is present in that tab's space, which is undefined. Basically the args in var value = ${JSON.stringify(args)}; is different from the args above.
You could try
chrome.extension.onRequest.addListener(({ tabId, args }) => {
chrome.tabs.executeScript(tabId, {
code: `
var value = ${JSON.stringify(` + args + `)};
var obj = value.trans_result;
console.log(obj);
var sendData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8088/info?str="+sendData, true);
xhr.send();
}
`,});
});
Also, for what it's worth, chrome.extension.onRequest is deprecated. It's recommended that you use onMessage and sendMessage instead.
I saw many pages talking about how to intercept the HTTP Response from a site. I'm trying this: Chrome Extension - How to get HTTP Response Body?
There are no execuble programs... this is my code:
manifest.json:
{
"manifest_version": 2,
"name": "Extension Name",
"description": "Some Desc.",
"version": "1.1",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "index.html"
},
"permissions": [
"activeTab",
"storage",
"tabs",
"https://*.google.com/"
],
"content_scripts": [
{
"matches": ["https://*.google.com/"],
"run_at": "document_start",
"js": ["contentscript.js", "inject.js"]
}
],
"web_accessible_resources": ["injected.js"]
}
index.html:
<html>
<head>
<script src="contentscript.js"></script>
</head>
<body>
<p>HTTP INTERCEPTOR</p>
</body>
</html>
injected.js:
(function(xhr) {
console.log('injeced file');
var XHR = XMLHttpRequest.prototype;
var open = XHR.open;
var send = XHR.send;
var setRequestHeader = XHR.setRequestHeader;
XHR.open = function(method, url) {
this._method = method;
this._url = url;
this._requestHeaders = {};
this._startTime = (new Date()).toISOString();
return open.apply(this, arguments);
};
XHR.setRequestHeader = function(header, value) {
this._requestHeaders[header] = value;
return setRequestHeader.apply(this, arguments);
};
XHR.send = function(postData) {
this.addEventListener('load', function() {
var endTime = (new Date()).toISOString();
var myUrl = this._url ? this._url.toLowerCase() : this._url;
if(myUrl) {
if (postData) {
if (typeof postData === 'string') {
try {
// here you get the REQUEST HEADERS, in JSON format, so you can also use JSON.parse
this._requestHeaders = postData;
} catch(err) {
console.log('Request Header JSON decode failed, transfer_encoding field could be base64');
console.log(err);
}
} else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') {
// do something if you need
}
}
// here you get the RESPONSE HEADERS
var responseHeaders = this.getAllResponseHeaders();
if ( this.responseType != 'blob' && this.responseText) {
// responseText is string or null
try {
// here you get RESPONSE TEXT (BODY), in JSON format, so you can use JSON.parse
var arr = this.responseText;
// printing url, request headers, response headers, response body, to console
console.log(this._url);
console.log(JSON.parse(this._requestHeaders));
console.log(responseHeaders);
console.log(JSON.parse(arr));
} catch(err) {
console.log("Error in responseType try catch");
console.log(err);
}
}
}
});
return send.apply(this, arguments);
};
})(XMLHttpRequest);
inject.js I set a timeout so I can enable the debugger:
/**
* code in inject.js
* added "web_accessible_resources": ["injected.js"] to manifest.json
*/
setTimeout(function() {
var s = document.createElement('script');
s.src = chrome.extension.getURL('injected.js');
s.onload = function() {
this.remove();
console.log('remove');
};
(document.head || document.documentElement).appendChild(s);
}, 10000);
Why the code is not injected into https://www.google.com/? Inspecting the DOM I don't see the code... the code runs and xhr is started but the methods open, setRequestHeader and send are never called.
The code is from my answer here.
Content Script, in that case, is used to communicate with injected.js.
Sample code is as follows:
/**
* Content script currently only used to communicate extension state on off message to injected.js
* Sends back response to extension (popup.js) after sending message to injected.js
*/
$(function(){
// localStorage is different from chrome.storage
// localStorage for injected script, and chrome.storage for extension script (popup.js) and contentscript.js
chrome.storage.sync.get("state", function (data) {
if (typeof data.state === 'undefined') {
chrome.storage.sync.set({"state": "on"}, function() {}); // async
}
console.log("Content Script State: " + data.state);
});
// message from extension script to this content script.
// will be used to receive enable disable messages
// sends response in 'status' variable
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"content script receiving message from a content script:" + sender.tab.url :
"content script receiving message from the extension");
if (request.toggle === true) {
chrome.storage.sync.set({"state": "on"}, function() { console.log("Content Script State Updated: on"); }); // async
var data = {
app_state: "on"
};
document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
// cannot return state in function since above .set is async and popup.js does not receive the response
sendResponse({state: "on"});
} else if (request.toggle === false) {
chrome.storage.sync.set({"state": "off"}, function() { console.log("Content Script State Updated: off"); }); // async
var data = {
app_state: "off"
};
document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
sendResponse({state: "off"});
} else {
sendResponse({state: "error"});
}
});
});
Please read more on Content Scripts. Hope you find this useful.
I'm working on a Google Chrome Extension, and I'm encountering a bug I can't solve on my own.
It works as expected switching to Youtube's Dark Mode on a single Youtube tab, but if you're on Youtube and Ctrl/Cmd click a link (open in a new tab), content.js is triggered again and the current tab is turned white and the new tab is dark.
If you are in a dark tab, a "child" tab should automatically be dark.
manifest.json:
{
"manifest_version": 2,
"permissions": [
"https://www.youtube.com/*",
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistant": false
},
"browser_action": {
"default_title": "Engage Youtube Dark Mode."
},
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["content.js"]
}]
}
background.js:
//var alreadyTriggered = false;
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
});
/*
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
alreadyTriggered = false;
});*/
chrome.runtime.onMessage.addListener(function(response, sender, sendResponse) {
//if (!alreadyTriggered) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
//alreadyTriggered = true;
//};
return true;
});
content.js:
var myDate = new Date();
if ((myDate.getHours() <= 7) || (myDate.getHours() >= 19))
{
var darkMode = document.body.getAttribute("dark");
if (!darkMode) {
chrome.runtime.sendMessage(window.location.href, function(result) {});
};
};
I'm guessing that I'm using activeTab incorrectly. Any help would be greatly appreciated. Thanks!
clicker.js:
stepOne();
function stepOne() {
try {
var buttons = document.querySelectorAll("button.ytd-topbar-menu-button-renderer");
buttons[0].click();
stepTwo();
}
catch(error) {
setTimeout(stepOne, 250);
}
}
function stepTwo() {
try {
buttons = document.querySelectorAll("paper-item.ytd-account-settings");
buttons[0].click();
stepThree();
}
catch(error) {
setTimeout(stepTwo, 100);
}
}
function stepThree() {
try {
buttons = document.querySelectorAll("paper-toggle-button.style-scope.ytd-account-settings");
buttons[0].click();
document.body.click();
}
catch(error) {
setTimeout(stepThree, 100);
}
}
What ended up working for me was to use a combination of:
using window.onload = doStuff();
And to make sure that the value for darkMode was null, not undefined.
Hopefully this helps someone who's been endlessly tweaking their code.
I am trying to install my Extension's CRX version but it is not loading some of image files on extension button placed on address bar.I have even put try/catch but it is not giving any error either. The Developer/Unpack version is working just fine.
What's wrong am I doing? What I guess my all image files are not compressed in CRX file. Unfortunately I can't extract CRX content either as renamig to .ZIP is not letting me to unzip on MacoSX
I am installing CRX by dragging on to extensions page.
How do I test the issue?
Code is given below:
Manifest.jsonn
{
"name": "Domain Colors",
"version": "1.0",
"manifest_version": 2,
"description": "Change Button Color for domains.",
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js": ["script.js"]
}
],
"permissions": [
"tabs", "http://*/*"
],
"browser_action": {
"default_title": "Colry",
"default_icon": "blue.png"
},
"background": {
"scripts": ["background41.js"]
}
}
script.js
alert("Testing Version..Wait for a while");
var request = new XMLHttpRequest();
if (request == null)
{
alert("Unable to create request");
}
else
{
try
{
var timestamp = new Date().getTime(); //to avoid cache ajax calls
var randomnumber=Math.floor(Math.random()*11);
timestamp = timestamp * randomnumber;
var _domain = document.domain;
_domain = _domain.replace("www.","");
var url = "http://xxxxnet/xxx/xxx.asp?xx="+_domain+"&ts="+timestamp;
request.onreadystatechange = function()
{
//request.setRequestHeader('Cache-Control', 'no-cache');
//request.setRequestHeader('Pragma', 'no-cache');
if(request.readyState == 4)
{
LDResponse(request.responseText);
}
}
request.open("GET", url, true);
request.send(null);
}
catch(e){
alert('An error has occurred in AJAX Call: '+e.message)
}
}
function LDResponse(response)
{
var json = JSON.parse(response);
alert(response);
var msg = document.domain+","+json["buttonColour"]+","+json["buttonTip"];
chrome.extension.sendMessage(msg);
}
background file
var currentUrl = "";
var currentColor = "";
var currentTip = "";
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
if (changeInfo.status === 'loading')
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/gray.png',
tabId:tabId
});
chrome.extension.onMessage.addListener(function(message, sender)
{
try
{
var stuff = message.split(",");
currentUrl = stuff[0];
currentUrl = currentUrl.replace("www.","");
currentColor = stuff[1];
currentTip = stuff[2];
}
catch(e)
{
alert('An error in onMessage method: '+e.message)
}
});
}
else if (changeInfo.status === 'complete')
{
try
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png",
tabId:tabId
});
chrome.browserAction.setTitle({
tabId:tabId,
title:currentTip
});
}
catch(e)
{
alert('An error in Complete method: '+e.message)
}
}
});
Thanks
Replace path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png with path: chrome.extension.getURL("currentColor.png") to get it to work.
Your runtime extension id is not lkhgldilknhpmdodeblhnbniahbjcdcm, so to use dynamic generated content you should use chrome.extension.getURL()