Cannot read property 'query' of undefined - In Vanilla Chrome Extension [duplicate] - google-chrome-extension

This question already has answers here:
"Cannot read property of undefined" when using chrome.tabs or other chrome API in content script
(4 answers)
Closed 2 years ago.
I'm trying to program a simplistic application that runs a timer in content.js, but also sends an alert of the web page url. After looking at the documentation, I came up with this:
content.js
chrome.tabs.query({'active': true, 'windowId': chrome.windows.WINDOW_ID_CURRENT},
function(tabs){
alert(tabs[0].url);
}
);
let message = "";
console.log("Death Timer Running...");
let body = document.getElementsByTagName("body")[0];
let div = document.createElement("DIV");
div.setAttribute("CLASS", "timer");
let text = document.createElement("P1");
text.setAttribute("ID", "myText");
text.setAttribute("CLASS", "timerText");
div.appendChild(text);
body.appendChild(div);
var endDate = new Date("Oct 07, 2085 16:37:52").getTime();
var myfunc = setInterval(function() {
// code goes here
var now = new Date().getTime();
var timeLeftSeconds = parseInt((endDate - now)/1000);
var timeLeftMinutes = parseInt(timeLeftSeconds/60);
var timeLeftHours = parseInt(timeLeftMinutes/60);
var timeLeftDays = parseInt(timeLeftHours/24);
var timeLeftYears = parseInt(timeLeftDays/365);
let secondsLeft = timeLeftSeconds;
var yearsLeft = timeLeftYears;
secondsLeft -= (yearsLeft * 365 * 24 * 60 * 60)
var monthsLeft = parseInt(secondsLeft/(60*60*24*30))
secondsLeft -= (monthsLeft * 60 * 60 * 24 * 30)
var daysLeft = parseInt(secondsLeft/(60*60*24))
secondsLeft -= (daysLeft * 60 * 60 * 24)
var hoursLeft = parseInt(secondsLeft/(60*60))
secondsLeft -= (hoursLeft * 60 * 60)
var minutesLeft = parseInt(secondsLeft/(60))
secondsLeft -= (minutesLeft * 60)
message = (yearsLeft.toString() + "y, " + monthsLeft.toString() + "mo, " + daysLeft.toString() + "d, " + hoursLeft.toString() + "h, " + minutesLeft.toString() + "mi, " + secondsLeft.toString() + "s")
console.log(message)
document.getElementById("myText").innerText = message;
}, 1000)
manifest.json
{
"manifest_version":2,
"name":"Death Timer",
"version":"0.1",
"description":"A timer that helps you put things into perspective.",
"permissions":[
"activeTab", "tabs"
],
"content_scripts": [
{
"matches":[
"<all_urls>"
],
"js":["content.js"],
"css":["content.css"]
}
]
}
The timer is working fine, however when I try to implement the retrieval of the active tab, I receive this this error:
Uncaught TypeError: Cannot read property 'query' of undefined
at content.js:2
Why would this be happening? I've looked at other SO posts which all had the same problem - but those appeared to be due to the accessing of outside resources. My app is vanilla, so this shouldn't be an issue.

The chrome.tabs API is only available in background and popup scripts. That's why it is returning tabs as undefined.
If you want to use the API, you can send a message from the content script to the background, which will use the tabs API, then send the result back to the content script.

Related

setInterval() and setTimeout() do nothing on heroku

My Node.js app works as intended and runs without errors on VSCode. However, setInterval() and setTimeout() do nothing once my app runs on heroku. I knew this because I wrote console.log() everywhere and looked at the heroku log of my app. None of the console.log() statements inside a setInterval() or setTimeout() were executed.
Surprisingly, all other functions of this app worked on heroku.
Here is the segment of code.
var refreshIntervalId = setInterval(() => {
config = require("./config.json");
// console.log("index line 44: entered loop");
if (config["reminder#" + fixedCount] == undefined) return clearInterval(refreshIntervalId);
config["reminder#" + fixedCount]["time"] -= 5 * 60 * 1000;
if (config["reminder#" + fixedCount]["time"] > 0) updateJson();
}, (5 * 60 * 1000));
setTimeout(() => {
const color = "#" + hexCodes[~~(Math.random() * hexCodes.length)], userID = config["reminder#" + fixedCount]["user"];
const userObject = client.users.cache.get(userID);
let sendReminder = new Discord.MessageEmbed()
.setTitle(`Reminder to ${userObject.username.split("#")[0]}`)
.setColor(color)
.setDescription(config["reminder#" + fixedCount]["content"]);
userObject.send({embeds: [sendReminder]}).catch(err => { });
delete config["reminder#" + fixedCount];
updateJson();
}, config["reminder#" + fixedCount]["time"]);
Any idea why this happened?

How to avoid having “quota exceeded for 'ReadGroup'” error in google api

I've created a bot which goes in Google Spreadsheet getting some datas before sending them by DM to 50 guild members into Discord.
However, due to high requests of datas, I've got an error message saying that I've exceeded the quota for group 'ReadGroup' and limit 'USER-100s'.
To avoid getting this error, I've created a buffer function however it still doesn't work, does anyone know how to avoid getting this limit error?
Here is the main code which is launched when I type a specific commande in Discord :
const client1 = new google.auth.JWT(keys.client_email, null, keys.private_key, ['https://www.googleapis.com/auth/spreadsheets']);
const client2 = new discord.Client();
.
.
.
let valeur1 = await liste(client1);
await sleep(100000);
console.log("End of first buffering time (100s)");
for (i = 0; i < valeur1.length; i++){
if (valeur1[i] != undefined){
try{
let valeur2 = await envoi(client1, valeur1[i]);
const user = client2.users.get(String(valeur1[i])) || await client2.fetchUser(String(valeur1[i]));
console.log("Ready to send to : " + user.id);
await user.send("The character you need to improve is : " + valeur2[0] + "\n 1. " + valeur2[1] + " = " + valeur2[2] + " >>> " + valeur2[3] + "\n 2. " + valeur2[4] + " = " + valeur2[5] + " >>> " + valeur2[6] + "\n 3. " + valeur2[7] + " = " + valeur2[8] + " >>> " + valeur2[9]);
console.log("Message sent for : " + user.id);
}
catch(err){
console.error(err);
console.log("Error detected for : " + valeur1[i]);
break;
}
}
}
Here is the first function called ("liste") which return the list of the 50 members id :
async function liste(client){
const gsapi = google.sheets({version:'v4',auth: client});
let data1 = new Array();
for (i = 0; i < 50; i++) {
const opt1 = {spreadsheetId: 'XXXXXX', range: 'Serveur!C' + (3+i)};
let data2 = await gsapi.spreadsheets.values.get(opt1);
data1.push(data2.data.values);
}
return data1;
}
And here is the second function called ("envoi") which is supposed to send the DM to the 50 different members of the guild :
async function envoi(client, id){
const gsapi = google.sheets({version:'v4',auth: client});
for (i = 0; i < 50; i++){
const opt1 = {spreadsheetId: 'XXXXXX', range: 'Discord!A' + (3+i)};
let data1 = await gsapi.spreadsheets.values.get(opt1);
if (parseInt(id) === parseInt(data1.data.values)){
const opt2 = {spreadsheetId: 'XXXXXX', range: 'Discord!C' + (3+i)};
let data2 = await gsapi.spreadsheets.values.get(opt2);
const opt3 = {spreadsheetId: 'XXXXXX', range: 'Discord!D' + (3+i)};
let data3 = await gsapi.spreadsheets.values.get(opt3);
.
.
.
const opt10 = {spreadsheetId: 'XXXXXX', range: 'Discord!K' + (3+i)};
let data10 = await gsapi.spreadsheets.values.get(opt10);
const opt11 = {spreadsheetId: 'XXXXXX', range: 'Discord!L' + (3+i)};
let data11 = await gsapi.spreadsheets.values.get(opt11);
var stats = [data2.data.values,data3.data.values,data4.data.values,data5.data.values,data6.data.values,data7.data.values,data8.data.values,data9.data.values,data10.data.values,data11.data.values];
await sleep(10000);
console.log("Extraction done for " + parseInt(id));
return stats;
}
}
console.log("Member not found");
return "erreur";
}
As a result, I would like to get all the members to get their DM. However after the 18th member, an error appear, even though I put some buffering time.
In the console.log, I get :
End of first buffering time (100s)
Extraction done for 408575708424699900
Ready to send to : 408575708424699925
Message sent for : 408575708424699925
.
.
.
Extraction done for 438420776652374000
Ready to send to : 438420776652374036
Message sent for : 438420776652374036
Error: Quota exceeded for quota group 'ReadGroup' and limit 'USER-100s' of service 'sheets.googleapis.com'
.
.
.
Error detected for : 493854774446391296
This is even more strange that the error concerns a member who already have received his DM (he is one the the first 10 members in the list)
Thanks to Tanaike, I updated my code using spreadsheets.values.batchGet() method. In that way instead of extraction values by values, I extracted a batch of values.
And then I made my formula. Now I don't have any issues anymore and even better, my script is way much quicker :)

CLUI - fancy progress bar in nodejs console - is there an easy way to update it?

There is an existing example that updates progress bar in place: https://github.com/nathanpeck/clui/blob/master/examples/progress.js (60 lines in total)
There is much simpler example directly in the readme: https://github.com/nathanpeck/clui/blob/master/README.md (4 lines only)
var clui = require('clui');
var Progress = clui.Progress;
var thisProgressBar = new Progress(20);
console.log(thisProgressBar.update(10, 30));
So I've added setInterval so that it updates the progress. I've also added line to clear the console and new console.log with each interval:
var clui = require('clui');
var Progress = clui.Progress;
var value = 50;
var thisProgressBar = new Progress(20);
console.log(thisProgressBar.update(value, 100));
var intervalId = setInterval(function() {
value++;
// console.log("Updated value: " + value);
process.stdout.write('\033c'); // clearing the console
console.log(thisProgressBar.update(value, 100));
if (value === 100) {
clearInterval(intervalId);
}
}, 500)
In the example with countdown spinner - https://github.com/nathanpeck/clui/blob/master/README.md#spinnerstatustext - I don't have to clear the console and do console.log.
Ideally I would like to do just thisProgressBar.update(value, 100) and the progress bar should be updated in place easily... Not sure my approach is good, and before I start replicating 60 lines solution I want to ask!
Opened GitHub issue as well for extra visibility: https://github.com/nathanpeck/clui/issues/22
Tried creating https://runkit.com/embed/umrs8pxg9geg demo but it is not real console.
You can use npm log-with-statusbar package. How about this:
var clui = require("clui");
var log = require("log-with-statusbar")();
var Progress = clui.Progress;
var value = 50;
var thisProgressBar = new Progress(20);
// console.log(thisProgressBar.update(value, 100));
log.setStatusBarText([thisProgressBar.update(value, 100)]);
var intervalId = setInterval(function() {
value++;
// console.log("Updated value: " + value);
log("Updated value: " + value);
// process.stdout.write('\033c'); // clearing the console
log.setStatusBarText([thisProgressBar.update(value, 100)]);
// console.log(thisProgressBar.update(value, 100));
if (value === 100) {
clearInterval(intervalId);
}
}, 500);

CronJob executing only once

I'm using CronJob for NodeJS https://github.com/kelektiv/node-cron
I don't understand why but my CronJob is running only once. It is supposed to run once every 10 seconds but after the first run it doesn't restart.
async function Job(moneda, condicion) {
console.log('init');
var res = await Analyzer.GetSpread(moneda);
var spread = res.MaxExchange.Bid/res.MinExchange.Ask;
console.log('Spread: ' + spread + 'Moneda: ' + moneda);
if (await condicion.CumpleCondicion(spread)){
var ids = await db.GetSuscripciones();
var mensaje = 'Spread: ' + spread.toFixed(3) + '\nMenor Ask: ' + res.MinExchange.Exchange + '--> ' + res.MinExchange.Ask + '\nMayor Bid: ' + res.MaxExchange.Exchange + '--> ' + res.MaxExchange.Bid;
for (var i = 0, len = ids.length; i < len; i++) {
bot.SendAlert(ids[i].id,mensaje);
}
}
console.log('end'); //this is reached
}
exports.Start = function(value){
condicionBTC = new condicionState('btc');
new CronJob('*/10 * * * * *', Job('btc',condicionBTC), null, true, 'America/Los_Angeles');
}
And this is printed in the console (only once)
init
Spread: 1.007141110114658 Moneda: btc
cumple condicion 1.007141110114658
end
If there's some exception stopping the cron job, where should I catch it so I can see what's going on?
I've added this
var job = new CronJob('*/10 * * * * *', Job('btc',condicionBTC), null, true, 'America/Los_Angeles');
setInterval(function(){ console.log(job.running); }, 3000);
and keeps printing true
Your cron pattern is wrong. According to https://github.com/kelektiv/node-cron :
"this library has six fields, with 1 second as the finest granularity."
Seconds: 0-59
Minutes: 0-59
Hours: 0-23
Day of Month: 1-31
Months: 0-11 (Jan-Dec)
Day of Week: 0-6 (Sun-Sat)
So your cron pattern is trying to run every 10th of a second, which is not possible.
Try replacing your cron pattern with '10 * * * * *'

How Can I Console.log countdownjs module via node.js

I'm using countdownjs module
, How Can I Console.log countdownjs for 3 days later, via node.js?
Here is a small example how you can use the countdown module:
var now = new Date();
var durationInDays = 3;
var durationInMilliseconds = (durationInDays * 24 * 60 * 60 * 1000);
var future = now.getTime() + durationInMilliseconds;
var countdownInfo = countdown(now, future);
// print it once
console.log(countdownInfo.toString());
// print it every 5 seconds
function repeatedPrint() {
setTimeout(function () {
// you have to provide a new start date to get updated information
countdownInfo = countdown(new Date(), future);
console.log(countdownInfo.toString());
repeatedPrint();
}, 5 * 1000);
}
repeatedPrint();

Resources