I am making a chrome extension that will automatically sign up for a Roblox account. (yes i still manually do captcha)
I am having some trouble with creating a new tab, and injecting a content script.
It seems that the script wont inject at all because i tried using an alert() message in the script and did not show up at all.
Here is my code if you need it
manifest.json:
{
"manifest_version": 2,
"name": "Roblox Alt Tools",
"description": "all the tools necicary for roblox alts",
"version": "1.0",
"permissions": ["tabs", "<all_urls>"],
"icons": {
"16": "/images/icon16.png",
"48": "/images/icon48.png",
"128": "/images/icon128.png"
},
"browser_action": {
"default_icon": {
"16": "/images/icon16.png",
"48": "/images/icon48.png",
"128": "/images/icon128.png"
},
"default_popup": "popup.html"
}
}
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Roblox Alt Tools</title>
<style>
body {
min-width: 250px;
max-width: 100%;
position: relative;
vertical-align:middle;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<center><h1>Roblox Alt Tools</h1>
<h3>the ultimate alt manager for Roblox</h3>
<br>
<button class="generate-acc" type="button">generate</button>
</center>
</body>
</html>
popup.js
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready)
} else {
ready()
}
function delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
async function generate() {
chrome.tabs.create({url: 'https://www.roblox.com'});
await delay(3000)
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"});
});
}
function ready() {
var btn = document.getElementsByClassName('generate-acc')[0];
btn.addEventListener('click', generate)
}
content_script.js
var password = "sub2piggygaming"
function randomstr(length) {
var result = '';
var characters = 'abcdefghijklmnopqrstuvwxyz';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;
}
async function signup() {
var signupbtn = document.getElementById("signup-button")
var usernamebtn = document.getElementById("signup-username")
var passwordbtn = document.getElementById("signup-password")
var monthdrop = document.getElementById("MonthDropdown")
var daydrop = document.getElementById("DayDropdown")
var yeardrop = document.getElementById("YearDropdown")
const keyboardEventInit = {bubbles:false, cancelable:false, composed:false, key:'', code:'', location:0};
usernamebtn.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
usernamebtn.value = await randomstr(10);
usernamebtn.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
usernamebtn.dispatchEvent(new Event('change', {bubbles: true}));
passwordbtn.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
passwordbtn.value = password;
passwordbtn.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
passwordbtn.dispatchEvent(new Event('change', {bubbles: true}));
monthdrop.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
monthdrop.value = 'Jan';
monthdrop.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
monthdrop.dispatchEvent(new Event('change', {bubbles: true}));
daydrop.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
daydrop.value = '01';
daydrop.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
daydrop.dispatchEvent(new Event('change', {bubbles: true}));
yeardrop.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
yeardrop.value = '1978';
yeardrop.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
yeardrop.dispatchEvent(new Event('change', {bubbles: true}));
await new Promise(resolve => setTimeout(resolve, 1000));
signupbtn.click();
}
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready);
} else {
signup();
}
I think the problem is the content script is executing before the tab loads.
I tried using setTimeout(), and also a Promise delay, still does not work.
Yes, the content script works in an already-loaded tab.
And yes, I looked on google, no results that work. is this even possible? do I gotta abandon my project?
thank you.
Related
I have created a new window in chrome.action.onClicked.addListener as given below.
On clicking of "Check" button in newly opened window I need to connect to content.js and print some message in the console of window. I dont know where it is going wrong! I am using Manifest version 3.
content.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if(msg.color === "#00FF00"){
document.body.style.backgroundColor = "green";
sendResponse({ status: "done" });
}
});
background.js
var urlRegex = /^(https?:\/\/)?[a-z0-9-]*\.?[a-z0-9-]+\.[a-z0-9-]+(\/[^<>]*)?$/;
chrome.action.onClicked.addListener(function(tab) {
/*...check the URL of the active tab against our pattern and... */
if (urlRegex.test(tab.url)) {
/* ...if it matches, send a message specifying a callback too */
chrome.windows.create({
tabId: tab.id,
type:"popup",
url:"popup.html",
focused:true
});
}
});
popup.html
<html>
<head>
<script defer src="popup.js"></script>
</head>
<body>
<h3>Test Extension Page</h3>
<input type="button" id="sendMessage" value="Check"/>
</body>
</html>
popup.js
let sendMessageButton = document.getElementById("sendMessage");
console.log(document.URL);
console.log(sendMessageButton.value);
function getTitle()
{
return document.title;
}
sendMessageButton.onclick = function() {
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs){
var tab = tabs[0];
chrome.scripting.executeScript(
{
target: {tabId:tab.id},
func: getTitle,
},
() => {
// This executes only after your content script executes
chrome.tabs.sendMessage(
tab.id,
{ color: "#00FF00" },
function (response) {
console.log(response.status);
}
);
});
});
};
Error in console of newly opened window.
Unchecked runtime.lastError: Cannot access contents of url "chrome-extension://jjaaoafdfmabdajdckiacompibnnmnlh/popup.html". Extension manifest must request permission to access this host.
Error handling response: TypeError: Cannot read properties of undefined (reading 'status') at chrome-extension://jjaaoafdfmabdajdckiacompibnnmnlh/popup.js:25:34
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
The problem is that the window you create becomes active and hence it becomes the result of chrome.tabs.query in your code, meaning that executeScript runs inside your own extension page, which can't work as this method is only for web sites.
The solution is to pass the tab id as URL parameter.
// background.js
chrome.action.onClicked.addListener(tab => {
chrome.windows.create({
type: 'popup',
url: 'popup.html?' + new URLSearchParams({
tabId: tab.id,
title: tab.title,
}),
});
});
// popup.js
const params = new URLSearchParams(location.search);
const tabId = +params.get('tabId');
let title = params.get('title'); // initial title
document.getElementById('sendMessage').onclick = async function () {
title = (await chrome.tabs.get(tabId)).title;
let res = await chrome.tabs.sendMessage(tabId, { color: "#00FF00" });
};
I'm wondering if it's possible to allow the user to upload an image to the extension and have that image display as a background image.
Let the user select a file, with <input type="file">
Turn the file into a data URL
Save the data URL with chrome.storage.local.set
Use a content script to replace the background image in web pages
Potential Problem: https://developer.chrome.com/docs/extensions/mv3/declare_permissions/#unlimitedStorage
Note: This permission applies only to Web SQL Database and application
cache (see issue 58985). Also, it doesn't currently work with wildcard
subdomains such as http://*.example.com.
Proof of concept:
https://github.com/GrippenDynamik/Set_Background_Image
manifest.json
{
"manifest_version": 3,
"name": "Set Background Image",
"version": "1.0",
"action": {
"default_title": "Set Background Image"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["/js/content_script.js"]
}
],
"permissions": [
"storage"
]
}
background.js
async function action_onClicked(tab, onClickData) {
chrome.tabs.create({
active: true,
url: chrome.runtime.getURL("/html/file_picker.html"),
});
}
chrome.action.onClicked.addListener(action_onClicked);
/html/file_picker.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<label for="file_picker">Choose an image to upload</label><br>
<input type="file" id="file_picker" accept="image/*"><br>
<br>
<button type="button" id="button_clear">Clear background image</button>
<br>
<img id="image"><br>
<script type="application/javascript" src="/js/file_picker.js"></script>
</body>
</html>
/js/file_picker.js
function storage_onChanged(changes, areaName) {
let settings = {};
if (areaName == "local") {
if (changes.image_data_url) {
settings.image_data_url = changes.image_data_url.newValue ?? "";
}
if (changes.image_filename) {
settings.image_filename = changes.image_filename.newValue ?? "none";
}
}
set_image(settings);
}
function set_image(settings) {
let image = document.getElementById("image");
if (settings.image_data_url !== undefined) { image.src = settings.image_data_url; }
if (settings.image_filename !== undefined) { image.alt = settings.image_filename; }
}
function remove_image() {
chrome.storage.local.remove(["image_data_url", "image_filename"]);
}
function store_image() {
if (this.files.length > 0) {
const reader = new FileReader();
reader.addEventListener("load", () => {
chrome.storage.local.set({"image_data_url": reader.result, "image_filename": this.files[0].name});
});
reader.readAsDataURL(this.files[0]);
}
}
// Initialization
chrome.storage.local.get(["image_data_url", "image_filename"])
.then(items => {
set_image({image_data_url: items.image_data_url ?? "", image_filename: items.image_filename ?? "none"});
}
);
document.getElementById("file_picker").addEventListener("change", store_image);
document.getElementById("button_clear").addEventListener("click", remove_image);
chrome.storage.onChanged.addListener(storage_onChanged);
/js/content_script.js
function storage_onChanged(changes, areaName) {
if (areaName == "local" && changes.image_data_url) {
set_background_image(changes.image_data_url.newValue, true);
}
}
function set_background_image(data_url, changed) {
if (data_url) {
// https://www.w3schools.com/jsref/prop_style_backgroundimage.asp
document.body.style.backgroundImage = "url('" + data_url + "')";
}
else if (changed) {
document.body.style.backgroundImage = "initial";
}
else {
console.log("You haven't 'uploaded' an image yet. Please click the extension action.");
}
}
// Initialization
chrome.storage.local.get("image_data_url")
.then(items => set_background_image(items.image_data_url, false));
chrome.storage.onChanged.addListener(storage_onChanged);
I am trying to read json of post request using Chrome Extension. So i have created a extension with following code:-
menifest.json file:-
{
"name": "numera name",
"version": "1.0",
"description": "numera",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["<all_urls>"],
"run_at": "document_start",
"js": ["contentScript.js"]
}
],
"permissions": [
"activeTab",
"tabs"
]
}
contentScript.js
function interceptData() {
var xhrOverrideScript = document.createElement('script');
xhrOverrideScript.type = 'text/javascript';
xhrOverrideScript.innerHTML = '
(function() {
var XHR = XMLHttpRequest.prototype;
var send = XHR.send;
var open = XHR.open;
XHR.open = function(method, url) {
this.url = url; // the request url
return open.apply(this, arguments);
}
XHR.send = function() {
this.addEventListener('load', function() {
if (this.url.includes('WaitForResponsesData')) {
var dataDOMElement = document.createElement('div');
dataDOMElement.id = '__interceptedData';
dataDOMElement.innerText = this.response;
console.log(this.response);
dataDOMElement.style.height = 0;
//dataDOMElement.style.overflow = 'hidden';
document.body.appendChild(dataDOMElement);
}
});
return send.apply(this, arguments);
};
})();'
document.head.prepend(xhrOverrideScript);
}
function checkForDOM() {
if (document.body && document.head) {
interceptData();
} else {
requestIdleCallback(checkForDOM);
}
}
requestIdleCallback(checkForDOM);
function scrapeData() {
var responseContainingEle = document.getElementById('__interceptedData');
if (responseContainingEle) {
var response = JSON.parse(responseContainingEle.innerHTML);
} else {
requestIdleCallback(scrapeData);
}
}
requestIdleCallback(scrapeData);
But I am not sure why this code is not working i have added console log and alert as well not no luck,
Also i have tried to search __interceptedData ID in page HTML but that is also not there.
I followed this URL https://medium.com/better-programming/chrome-extension-intercepting-and-reading-the-body-of-http-requests-dd9ebdf2348b
please help me out from this
When I click on the toolbar icon from my chrome extension, it brings up the default popup.html along with popup.js. From that popup.js, I want to send a message to the current active tab. I can't figure out how to get the active tab.
My code in the popup.js looks like this:
window.onload = function() {
console.log(`popup.js:window.onload`);
const timeNow = document.getElementById("timeNowId");
timeNow.innerText = new Date().toLocaleTimeString();
var resultsButton = document.getElementById("buttonId");
resultsButton.onclick = () => {
chrome.runtime.sendMessage(
"FromPopupToBackgroundToContent:" + timeNow.innerText,
function(response) {
response === undefined
? alert("popup.js:return from sendMessage:undefined")
: alert("popup.js:return from sendMessage:", response);
}
);
};
};
The full, non-working example is in this github repo at this branch linked to.
https://github.com/pkellner/chrome-extension-message-popup-to-content/tree/feature-popup-to-content-directly-getcurrent
Example:
popup.js
function popup() {
chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "start"});
});
}
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("button1").addEventListener("click", popup);
});
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "start" ) {
start();
}
}
);
function start(){
alert("started");
}
popup.html
<!DOCTYPE html>
<html>
<head></head>
<script src="popup.js"></script>
<body>
<input id="button1" type=button value=clickme>
</body>
</html>
I'm creating a Chrome extension that should interact with the user selection in the Microsoft Word Online documents - add new highlighting instead of the natural selection highlighting and then remove it.
The problem is that I'm not able to get the user selection: the response for the window.getSelection() returns the result like the selection is empty.
Here are files from my extension:
manifest.json
{
"manifest_version": 2,
"name": "The extension name",
"version": "1.0",
"description": "This extension description",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"icons": {
"128": "icon.png"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_end",
"all_frames": true
}],
"permissions": ["activeTab"]
}
popup.html
<!doctype html>
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<div id="wrapper">
<form id="settings" name="settings">
<div id="apply" class="form-row">
<input type="submit" name="apply" value="Apply"/>
</div>
</form>
</div>
</body>
</html>
popup.js
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("settings").addEventListener("submit", function (e) {
e.preventDefault();
chrome.tabs.executeScript(null, {file: 'toolbar.js'}, function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {});
});
);
}, false);
});
toolbar.js
function showToolbar() {
var dom_body = document.getElementsByTagName('body')[0];
var tb_wrapper = document.createElement('div');
tb_wrapper.id = "toolbar_wrapper";
var tb_toolbar_play = document.createElement('button');
tb_toolbar_play.id = "toolbar_play";
tb_toolbar_play.title = "Play";
tb_toolbar_play.value = "Play";
tb_wrapper.appendChild(tb_toolbar_play);
dom_body.appendChild(tb_wrapper);
}
showToolbar();
content_script.js
function playButtonOnClickEventListener(request, sender, sendResponse) {
var toolbar = document.getElementById("toolbar_wrapper");
if (toolbar !== null) {
var toolbar_play_button = document.getElementById("toolbar_play");
toolbar_play_button.addEventListener("click", function (e) {
var selection = window.getSelection();
console.log(selection);
});
}
sendResponse({data: "response", success: true});
}
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
playButtonOnClickEventListener(request, sender, sendResponse);
});
So, what I want to see in the Chrome Developer tools after the console.log(selection) executes:
What I actually get:
P.S. The extension works perfectly with Google Docs.
I'm not sure how the Word Online editor is built or why you can't use window.getSelection(), but one thing I noticed immediately is that when you select text in it, the editor gives that text a Selected class. So maybe you could take advantage of that somehow? Override the style of the relevant elements?
Possibly you could use a MutationObserver and look for this class name being added to elements. You would have to do some experimenting to see if this works for your needs, and obviously if Microsoft change the class name or behaviour, your extension breaks.
Try selecting some text and putting
document.getElementsByClassName("Selected")[0].innerHTML
in the console.
Here's the solution of the issue. Hope it can be useful for somebody once.
Currently I see the whole picture differently, so I changed the number of files and its content.
manifest.json
{
"manifest_version": 2,
"version": "1.1.1",
"name": "Test name",
"description": "Test description",
"browser_action": {
"default_icon": "icon.png"
},
"icons": {
"128": "icon.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content_script.js"],
"run_at": "document_end",
"all_frames": true
}
],
"permissions": ["activeTab"]
}
content_script.js
//Word Online pages contain several different iframes, so, in order
//to find the one where the text that we are going to work with
//is placed, we have to use the Chrome Runtime API and its
//"sendMessage" method that works in every frame.
//https://developer.chrome.com/apps/runtime#method-sendMessage
chrome.runtime.sendMessage("", function() {
if (checkFrameLocation()) {
showToolbar();
}
});
function checkFrameLocation() {
//So as I work with documents in OneDrive (onedrive.live.com)
//and in Sharepoint (<USER_NAME>-my.shrepoint.com), I found out
//that I need iframes with these URLs only.
var trusted_urls = [
"https://euc-word-edit.officeapps.live.com",
"https://word-edit.officeapps.live.com",
"nl1-word-edit.officeapps.live.com"
];
var result = false;
for (var i = 0; i < trusted_urls.length; i++) {
if (window.location.href.indexOf(trusted_urls[i]) > -1) {
result = true;
}
}
return result;
}
function showToolbar() {
var dom_body = document.body;
var tb_wrapper = document.createElement('div');
tb_wrapper.id = "toolbar_wrapper";
tb_wrapper.style.position = "absolute";
tb_wrapper.style.top = "200px";
tb_wrapper.style.left = "200px";
tb_wrapper.style.backgroundColor = "#ffffff";
tb_wrapper.style.height = "30px";
tb_wrapper.style.width = "50px";
var tb_play = document.createElement('button');
tb_play.id = "toolbar_play_button";
tb_play.title = "Play";
tb_play.innerHTML = "►";
tb_play.style.height = "100%";
tb_play.style.width = "100%";
tb_play.style.lineHeight = "12px";
tb_play.addEventListener("click", function() {
playButtonOnClickEventListener();
});
tb_wrapper.appendChild(tb_play);
dom_body.appendChild(tb_wrapper);
}
function playButtonOnClickEventListener() {
//Now we can use the window selection object
var window_selection = window.getSelection();
console.log(window_selection);
//Also, Word Online adds special class name to every selected element
//in the document. So, this is another way to get the selected text.
var elements_selection = document.getElementsByClassName("Selected");
console.log(elements_selection);
}
And here's the proof screenshot:
There are results of accessing the selected text in the Word Online document