OK, this may sound like a really simple question, but the below code keeps giving me an error on the console. After some research, it looks as though I may have messed up setting the variables, but I'm not sure how to fix.
For context, this module is to update channels with server stats.
Code:
function updateStats(client) {
const Discord = require('discord.js');
const config = require("../settings/configuration");
const settings = require("../settings/configuration");
const guild = client.guilds.cache.get(settings.BOT_SETTINGS.Guild_ID);
const totalUsers = client.channels.fetch('883654989271154728');
const onlineUsers = client.channels.fetch('883655041813200926');
setInterval(function() {
const interval = (async function() {
for await (const startTime of setInterval(interval, Date.now())) {
const now = Date.now();
console.log(now);
if ((now - startTime) > 1000)function updateStats(client) {
const Discord = require('discord.js');
const config = require("../settings/configuration");
const settings = require("../settings/configuration");
const guild = client.guilds.cache.get(settings.BOT_SETTINGS.Guild_ID);
const totalUsers = client.channels.fetch('883654989271154728');
const onlineUsers = client.channels.fetch('883655041813200926');
setInterval(function() {
const interval = (async function() {
for await (const startTime of setInterval(interval, Date.now())) {
const now = Date.now();
console.log(now);
if ((now - startTime) > 1000)
break;
}
console.log(Date.now());
})();
console.log('Getting stats update..')
var userCount = guild.memberCount;
var onlineCount = guild.members.filter(m => m.presence.status === 'online').size
$console.log("Total Users: " + userCount);
$console.log("Online Users: " + onlineCount);
totalUsers.setName("Total Users: " + userCount)
.then(newChannel => console.log(`Stat channel renamed to: ${newChannel.name}`))
.catch(console.error);
onlineUsers.setName("Online Users: " + onlineCount)
.then(newChannel => console.log(`Stat channel renamed to: ${newChannel.name}`))
.catch(console.error);
}, 30000)
}
module.exports = {
updateStats
}
break;
}
console.log(Date.now());
})();
console.log('Getting stats update..')
var userCount = guild.memberCount;
var onlineCount = guild.members.filter(m => m.presence.status === 'online').size
console.log("Total Users: " + userCount);
console.log("Online Users: " + onlineCount);
totalUsers.setName("Total Users: " + userCount)
.then(newChannel => console.log(`Stat channel renamed to: ${newChannel.name}`))
.catch(console.error);
onlineUsers.setName("Online Users: " + onlineCount)
.then(newChannel => console.log(`Stat channel renamed to: ${newChannel.name}`))
.catch(console.error);
}, 30000)
}
module.exports = {
updateStats
}
Error on console:
[Error] An error happened in process:
ReferenceError: Cannot access 'interval' before initialization
at /home/container/events/Stats.js:10:51
at Timeout._onTimeout (/home/container/events/Stats.js:49:9)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
Just change const interval = (async function() { to let interval = (async function() { and then just use interval = (async function() {
like that:
let interval = (async function() {
for await (const startTime of setInterval(interval, Date.now())) {
const now = Date.now();
console.log(now);
if ((now - startTime) > 1000)function updateStats(client) {
const Discord = require('discord.js');
const config = require("../settings/configuration");
const settings = require("../settings/configuration");
const guild = client.guilds.cache.get(settings.BOT_SETTINGS.Guild_ID);
const totalUsers = client.channels.fetch('883654989271154728');
const onlineUsers = client.channels.fetch('883655041813200926');
setInterval(function() {
interval = (async function() {
Related
I'm building a website with node.js and I' m making some push notifications and it doesn' t send them on chrome version 109.0.5414.120 . I tried running it on opera gx and it worked there. I have to use chrome because its for a school project and all my teachers use chrome and the don't want to download new programms
the code;
app.js
const express = require("express")
const webpush = require('web-push')
const app = express()
app.use(express.json());
const path = require("path")
app.use(express.static(path.join(__dirname, 'client')))
const publicKey = "BL2QpTNn-CZARUqJhm4tDPPful3TMIjugZdyi1WNIcaps21w7KJFy4cjilMNk-NbeEIwWVA5ddCXpOStd6RTuXA"
const privateKey = "dWcFCcnNS-uBYS6GISodobLXht-9KpOQmeHh1h89T7w"
webpush.setVapidDetails("mailto:thdegroote18#gmail.com", publicKey, privateKey)
app.post("/subscribe", async (req, res) => {
try {
// Subscription Details From the client side , We would get back to this
const subscription = req.body;
subscribers.push(subscription);
// Save the new subscrber to the subscribers file
fs.writeFileSync("./subscribers.json", JSON.stringify(subscribers));
res.status(201).send("Subscription Saved");
} catch (error) {
console.error(error);
}
});
const subscribers = require("./subscribers.json")
const fs = require("fs")
async function sendPushNotificaiton() {
for (let i = 0; i < subscribers.length; i++) {
const subscription = subscribers[i];
//Notification Payload, this could contain more information about the notification
const payload = {
title: "Push Test",
body: " Push Notification Message",
icon: "https://blog.mensaiah.com/assets/round_logo.png",
};
//Pass object into sendNotification
await webpush.sendNotification(subscription, JSON.stringify(payload));
}
}
//Send Notification Every Minute
const durationInMillisecond = 60 * 10000
setInterval(sendPushNotificaiton,durationInMillisecond);
const port = 1999
app.listen(port, () => {
console.log(`server started on port ${port}`)
})
client.js
const publicVapidKey = "BL2QpTNn-CZARUqJhm4tDPPful3TMIjugZdyi1WNIcaps21w7KJFy4cjilMNk-NbeEIwWVA5ddCXpOStd6RTuXA";
async function subscribeToPush() {
console.log("Registering service worker...");
const register = await navigator.serviceWorker.register("/worker.js", {
scope: "/"
});
console.log("Service Worker Registered...");
console.log("Registering Push...");
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
});
console.log("Push Registered...");
console.log("Subscribing for Push ...");
await fetch("http://localhost:1999/subscribe", {
method: "POST",
body: JSON.stringify(subscription),
headers: {
"Content-Type":"application/json"
}
});
}
function urlBase64ToUint8Array(base64String) {
const padding = "=".repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
if ('serviceWorker' in navigator) {
subscribeToPush().catch(console.log);
}
worker.js
self.addEventListener("push", e => {
// Data from service
const data = e.data.json();
console.log("Push Recieved...");
self.registration.showNotification(data.title, {
body: data.body,
icon: data.icon,
});
});
I'm creating the telegram bot, and I have question.
In app.js
const { admin } = require('./admin');
require('dotenv').config();
const token = process.env.token;
const bot = new TelegramBot(token, { polling: true });
let chatId = [];
async function startApp() {
let restTime = await moment.tz('America/Chicago').format('hh:mm A');
let weekend = await moment.tz('America/Chicago').day();
console.log("start bot " + restTime);
const nowHours = new Date().getHours()
const restMessage = {
text: process.env.restText
}
const weekendMessage = {
text: process.env.weekendText
}
function startBot() {
return bot.on('message', async(msg) => {
if (msg.text === '/admin'){
return admin(msg);
}
...
and I have:
admin.js:
require('dotenv').config();
const pass = process.env.passwordAdmin
function admin(bot,msg) {
bot.sendMessage(msg.from.id, 'Enter admin password')
bot.onText(`${pass}`,()=>{
bot.sendMessage(msg.from.id, "Good")
})
}
module.exports = {admin}
error: [polling_error] {}
How I can pause the bot.on listener in app.js when I start bot.onText listener or other listener, and then, when admin end they work, return to app.js listener?
Me helps my friend,
const pass = new RegExp(process.env.passwordAdmin)
...
bot.onText (pass, () => {
but listener bot.on('message'..) is still working.
My Index.js is having a error. I can't understand why.
const { Client, Collection } = require("discord.js");
const { readdirSync } = require("fs");
const { join } = require("path");
const { TOKEN, PREFIX } = require("./util/Util");
const i18n = require("./util/i18n");
const { Intents, client } = require('discord.js');
client.login(TOKEN);
client.commands = new Collection();
client.prefix = PREFIX;
client.queue = new Map();
const cooldowns = new Collection();
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
client.on("ready", () => {
console.log(`${client.user.username} ready!`);
client.user.setActivity(`with ${client.guilds.cache.size} servers`);
});
client.on("warn", (info) => console.log(info));
client.on("error", console.error);
const commandFiles = readdirSync(join(__dirname, "commands")).filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(join(__dirname, "commands", `${file}`));
client.commands.set(command.name, command);
}
client.on("message", async (message) => {
if (message.author.bot) return;
if (!message.guild) return;
const prefixRegex = new RegExp(`^(<#!?${client.user.id}>|${escapeRegex(PREFIX)})\\s*`);
if (!prefixRegex.test(message.content)) return;
const [, matchedPrefix] = message.content.match(prefixRegex);
const args = message.content.slice(matchedPrefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command =
client.commands.get(commandName) ||
client.commands.find((cmd) => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 1) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
i18n.__mf("common.cooldownMessage", { time: timeLeft.toFixed(1), name: command.name })
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply(i18n.__("common.errorCommand")).catch(console.error);
}
});
client.login(TOKEN);
The import is called Client instead of client. So change your import and instantiate the client like so:
const { Intents, Client } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
You will have to set the intents according to your own use case, as per this answer.
You are calling client.login(TOKEN); two times, in the beginning and in the final of the code.
I have the following scanner
const scan = promisify(redisClient1.scan).bind(redisClient1);
const scanAll = async (pattern) => {
const found = [];
let cursor = '0';
do {
const reply = await scan(cursor, 'MATCH', pattern);
cursor = reply[0];
found.push(...reply[1]);
} while (cursor !== '0');
return found;
};
But to use it i have to initialize redisClient1 every time
const redisClient1 = require('redis').createClient(config.redisPort, config.redisUrl, {
no_ready_check: true,
db: 1
});
redisClient1.on('error', function (err) {
console.log('Error ' + err);
});
redisClient1.on('connect', function () {
console.log('Connected to Redis pre/dev.');
});
Problem is, i need the scanAll function to have as parameters the redisPort and redisUrl (db is always 1)
So the client initialization should happen once the function received the parameters
Meaning it would look something like this
const scanAll = async (url, port) => {
const found = [];
let cursor = '0';
do {
const reply = await customScan(url+port;, cursor, 'Match', pattern)
cursor = reply[0];
found.push(...reply[1]);
} while (cursor !== '0');
return found;
};
How can i do something similar?
I ended up with this
const createRedisClient = async (port, url) => {
const redisClient = require('redis').createClient(config.redisPort, config.redisUrl, {
no_ready_check: true,
db: 1
})
return redisClient;
}
const scanAll = async (pattern) => {
const redisClient = await createRedisClient('1111', 'server.com')
const scan = promisify(redisClient.scan).bind(redisClient);
const found = [];
let cursor = '0';
do {
const reply = await scan(cursor, 'MATCH', pattern);
cursor = reply[0];
found.push(...reply[1]);
} while (cursor !== '0');
return found;
};
const serverInfo = async () => {
const redisClient = await createRedisClient('1111', 'server.com')
const info = promisify(redisClient.info).bind(redisClient);
const reply = await info();
return reply;
}
I have tried to mock the redisClient.js using redis-mock using jest. But I couldn't find the solution for it. please give me a code sample for it. I need to mock it in controller.
redisClient.js
const redis = require('redis');
const asyncRedis = require("async-redis");
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
},
}
);
module.exports = asyncRedis.decorate(connection);
Controller
const logger = require('../../helper/logger');
const response = require("../../config/response");
const constant = require('../../config/constant');
const QuizService = require('../../services/quiz/quizService');
class QuizController {
constructor() {
this.quizService = new QuizService();
}
async getQuiz(req, res) {
const { userId, query: { campaignId } } = req;
try {
const question = await this.quizService.getQuestion(userId, campaignId);
res.send(response.res(true, constant.MSG.Quiz_FETCHED, question));
} catch (error) {
res.status(constant.RESPONSE.INTERNAL_ERROR.CODE)
.send(response.res(false, error.message, null, error.code))
}
}
}
Service
const _ = require('lodash');
const moment = require('moment');
const { Op } = require('sequelize');
const { v4: uuidv4 } = require("uuid");
const shuffle = require('shuffle-array');
const serialize = require("serialize-javascript");
const utill = require("../../helper/util");
const redis = require("../../cache/redisClient");
const constant = require('../../config/constant');
const scoreHelper = require('./../../helper/scoreHelper');
const db = require("../../models");
const Quiz = db.quiz;
const Campaign = db.campaign;
const campaign = require('../campaign/campaignService')
const SubscriberAnswer = require('../subscriberAnswer/subscriberAnswerService')
const SubscriberProgram = require('../subscriberProgram/SubsciberProgramService')
class quizService {
constructor() {
this.subscriberAnswer = new SubscriberAnswer()
this.subscriberProgram = new SubscriberProgram()
this.campaign = new campaign()
}
async getQuestion(userId, campaignId) {
const subscribedProgramData = await this._checkAvailableQuestionLimit(userId, campaignId)
if(!subscribedProgramData){
throw { message: constant.MSG.TRY_AGAIN }
}
if (subscribedProgramData.no_of_questions > 0) {
const question = await Quiz.findQuestion(userId, campaignId);
if (question.length) {
const data = {
subscriber_id: userId,
campaign_id: campaignId,
questions_id: question[0].id
}
const updateData = {
id: subscribedProgramData.id,
no_of_questions: (subscribedProgramData.no_of_questions - 1)
}
await this.subscriberAnswer.create(data);
await this.subscriberProgram.updateQuota(updateData);
const id = uuidv4();
const {answer, ...questionData } = question[0];
const responseData = await this.handleQuestionData(id, userId, campaignId, questionData, answer);
return responseData;
} else {
throw { code:constant.RESPONSE_COEDES.ALL_ANSWERED, message: constant.MSG.ANSWER_ALL }
}
} else {
throw { message: constant.MSG.QUOTA_OVER }
}
}
}
My Unit Testing Code
const QuizService = require("../../src/services/quiz/quizService");
const QuizController = require("../../src/controllers/quiz/quizController");
const quizService = new QuizService();
const quizController = new QuizController();
const httpMocks = require("node-mocks-http");
jest.mock("../../src/helper/logger");
jest.mock("../../src/cache/redisClient.js");
beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
jest.resetAllMocks();
quizService.getQuestion = jest.fn();
});
quizService.getQuestion = jest.fn();
const response = {
id: 1,
name: 'Sandun',
msisdn: '94704377575',
otp: '1234',
deleted: 0,
attempts: 0,
img_url: 'https://'
}
// This test shows how the constructor can be mocked, and how to spy on passed parameters.
describe("Test QuizController", () => {
afterEach(() => {
jest.resetAllMocks();
});
//Because getQuestion is prototype method
it("Test - GetQuiz - Success", async () => {
req.query.programId = 1;
req.userId = 1;
jest.spyOn(QuizService.prototype, "getQuestion").mockReturnValue(response);
await quizController.getQuiz(req, res);
expect(res.statusCode).toBe(200);
});
});
ERROR
FAIL test/controllers/quiz.controller.test.js
● Test suite failed to run
TypeError: Cannot read property 'startsWith' of undefined
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
^
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
at normalizeUrl (node_modules/redis-mock/lib/utils/parseRedisUrl.js:4:11)
at Object.<anonymous>.module.exports (node_modules/redis-mock/lib/utils/parseRedisUrl.js:61:34)
at generateUrlOptions (node_modules/redis-mock/lib/client/createClient.js:25:30)
at unifyOptions (node_modules/redis-mock/lib/client/createClient.js:61:10)
at Object.createClient (node_modules/redis-mock/lib/client/createClient.js:64:47)
at Object.<anonymous> (src/cache/redisClient.js:5:26)
at Object.<anonymous> (src/services/quiz/quizService.js:8:15)
at Object.<anonymous> (test/controllers/quiz.controller.test.js:1:21)