Getting "#ReferenceError: connection is not defined" - discord.js

I've been using the code from discord.js guide and keep getting this error when I try to make it join
Here's my code:
const Discord = require('discord.js');
const client = new Discord.Client();
const PREFIX = '%';
const request = require('request');
const cheerio = require('cheerio');
var servers = {};
client.on('ready', () => {
console.log('This client is online!');
})
client.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'image':
var imreq = (args[1])
image(message, imreq);
break;
case 'bruh':
client.on('message', async message => {
// Join the same voice channel of the author of the message
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
}
});
const dispatcher = connection.play('C:\Users\jayja\Downloads\Bruh Sound Effect 2.mp3 ');
dispatcher.on('start', () => {
console.log('audio.mp3 is now playing!');
});
dispatcher.on('finish', () => {
console.log('audio.mp3 has finished playing!');
});
// Always remember to handle errors appropriately!
dispatcher.on('error', console.error);
break;
}
});
function image(message, imreq) {
var options = {
url: "http://results.dogpile.com/serp?qc=images&q=" + imreq,
method: "GET",
headers: {
"Accept": "text/html",
"User-Agent": "Chrome"
}
};
request(options, function(error, response, responseBody) {
if (error) {
return;
}
$ = cheerio.load(responseBody);
var links = $(".image a.link");
var urls = new Array(links.length).fill(0).map((v, i) =>
links.eq(i).attr("href"));
console.log(urls);
if (!urls.length) {
return;
}
// Send result
message.channel.send(urls[Math.floor(Math.random() * urls.length)]);
});
}
client.login(token)
Heres a screenshot of the terminal:
Screenshot

So like I guessed, you don't need to listen to the message event of the client. You already have the message object via the initial command trigger.
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
const dispatcher = connection.play('C:\Users\jayja\Downloads\Bruh Sound Effect 2.mp3 ');
dispatcher.on('start', () => {
console.log('audio.mp3 is now playing!');
});
dispatcher.on('finish', () => {
console.log('audio.mp3 has finished playing!');
});
// Always remember to handle errors appropriately!
dispatcher.on('error', console.error);
}
This should be all you need. You also might find this guide interesting to read.

Related

trouble with async reucrsion of directories , with file system access api in react js

This code is designed to recursively iterate through a selected directory using the file system access api , and sent it via axios post request.
I have an encountered 2 problems :
I am struggling to find the right way to to enter subdirectories (now it only works for a directory with only files and no subDirs)
as you can see , i set a timeout before the post request , for some reason I cant identify , the promise in savedOCS function , probably resolves before it should.
I have the following code :
async uploadDirectory () {
const directoryHandle = await window.showDirectoryPicker();
const t0 = performance.now();
console.log(`t0 ${t0}`);
this.setState({chosenDirectory: directoryHandle.name} , ()=> {
console.log(this.state.chosenDirectory);
});
await this.handleDirectoryEntry(directoryHandle);
const t4 = performance.now();
console.log(`t4 ${t4}`);
setTimeout(() => {
this.axios.post(
'/DirectoryTransfer', {
directory: this.state.chosenDirectory,
directoryFiles: this.state.directoryFiles
}
).then((resData) => {
// this.fetchRemoteFileSystem();
const t5 = performance.now();
console.log(`t5 ${t5}`);
}).catch((error) => {
console.log(error)
})
}, 5000);
}
async handleDirectoryEntry(directoryHandle,subdir) {
let fileEntries = [];
console.log(directoryHandle);
for await (const entry of directoryHandle.values()) {
console.log(entry);
if(entry.kind === "file" && subdir === '') {
fileEntries.push(await entry.getFile());
}
}
console.log(fileEntries);
await this.saveDocs(fileEntries);
}
saveDocs = async (files) => {
const filePromises = files.map((file) => {
return new Promise ((resolve ,reject)=> {
const fileReader = new FileReader();
fileReader.onload = async ()=> {
try {
let directoryFiles = this.state.directoryFiles || [];
console.log('before setState: ', directoryFiles)
let response = false;
const t2 = performance.now();
console.log(`t2 ${t2}`)
await this.setState(
(prevState) => ({
directoryFiles: [...prevState.directoryFiles, { name: file.name, data: fileReader.result }]
}),
() => {
response = true;
console.log("after setState: ", this.state.directoryFiles);
const t3 = performance.now();
console.log(`t3 ${t3}`)
}
);
resolve(response);
} catch(err) {
reject(err)
}
}
fileReader.onerror = (err) => {
reject(err);
}
fileReader.readAsText(file);
})
})
const fileInfos = await Promise.all(filePromises);
return fileInfos;
}
i tried to find a way to iterate subDirs using recursion , and to async read files inside a directory.
current results :
the code reads the files fine.
without the timeout it sends a post request with an empty array of files.
doesn't have an implementation for subDirs.

React useEffect gives react-hooks/exhaustive-deps error on publishing

My .net core react web application works fine, except that when I try to publish it gives me the following error:
Occurred while linting C:\.....Fetch.js: 79
Rule: "react-hooks/exhaustive-deps"
This is my code:
const populateTable1Data = async () => {
var response = await axios.get(apiurl + { params: { id: props.id1 } });
var data = await response.data;
setTable1Data(data);
}
const populateTable2Data = async () => {
var response = await axios.get(apiurl + { params: { id: props.id2 } });
var data = await response.data;
setTable2Data(data);
setLoading(false);
}
useEffect(() => {
const load = async () => {
await populateTable1Data();
await populateTable2Data();
setLoading(false)
}
load()
}, []);
Problem is that I have a very similar useEffect inside another component which doesn't give errors though:
const populateTableData = async () => {
const response = await axios.get(apiurl + key);
const data = await response.data;
setTableData(data);
setLoading(false);
}
useEffect(() => {
populateTableData();
}, [])
If anyone has the same problem, I solved by doing this:
const populateTable1Data = async (dataProps) => {
var response = await axios.get(apiurl + { params: { id: dataProps.id1 } });
var data = await response.data;
setTable1Data(data);
}
const populateTable2Data = async (dataProps) => {
var response = await axios.get(apiurl + { params: { id: dataProps.id2 } });
var data = await response.data;
setTable2Data(data);
setLoading(false);
}
useEffect(() => {
const load = async () => {
await populateTable1Data(props);
await populateTable2Data(props);
setLoading(false)
}
load()
}, [props]);
I essentially passed the props on the function call, I don't know why does it have to be this way, I'll leave the answer here in case anyone else needs it while waiting for someone to be kind enought to explain the reason for this.

Why is data not being saved in the array? | discord.js v13

Whenever I'm attempting to push data into an array, then log it after the for loop it just prints an empty array. Why is that?
const discord = require('discord.js');
const db = require('quick.db');
const fs = require('fs');
module.exports = {
name: 'XYZ',
run: async (client, message) => {
var array_V = ['ID1', 'ID2'];
var snowflakes = [];
var i = 0;
message.guild.channels.cache.forEach(channel => {
if (!channel.isText()) return;
for (const channel of message.guild.channels.cache.values()) {
let messages = await channel.messages.fetch()
messages.each((msg) => {
if (msg.author.id === array_V[i]) {
snowflakes.push(msg.createdTimestamp)
}
})
}
});
}
}
Now outputs SyntaxError: await is only valid in async functions and the top level bodies of modules although it is already declared as an async function in the header.
You are pushing it in a .then. Use await and for loops to have it update and then run the next code
for (const channel of message.guild.channels.cache.filter(c => c.type === "GUILD_TEXT").values()) {
let messages = await channel.messages.fetch()
messages.each((msg) => {
if (msg.author.id === array_V[i]) {
snowflakes.push(msg.createdTimestamp)
}
})
}
This should work since everything asynchronous is being awaited in the for loop

Socket.io connected property is always false

I am trying to create a private messaging app. The socket connects at first but then when I try to emit any event from the client side, it shows that socket.connected property is false.
Please help me out.
Here's is my client side code, Please note that socket.on("users") part works correctly because all of it happens when the socket it connected. It means the connection part is happening correctly. After that whenever I try to call a function that emits a socket event, it shows that socket.connected property is false and doesnt do anything.
Any help would be appreciated.
var connectionOptions = {
transports: ["websocket"],
autoConnect: false,
};
socket = io("http://localhost:3001", connectionOptions);
socket.on("connection _error", (err) => {
if (err.message === "invalid username") {
console.log("ERROR");
}
});
socket.on("users", (users) => {
users.forEach((user) => {
user.self = user.userID === socket.id;
//initReactiveProperties(user);
});
socket.on("user connected", (user) => {
// TODO
setUsers((existingusers) => [...existingusers, user]);
console.log(user);
});
// put the current user first, and then sort by username
users = users.sort((a, b) => {
if (a.self) return -1;
if (b.self) return 1;
if (a.username < b.username) return -1;
return a.username > b.username ? 1 : 0;
});
//console.log(users);
});
socket.on("private message", ({ content, from }) => {
console.log(content);
});
useEffect(() => {
const username = localStorage.getItem("username");
console.log(username);
socket.auth = { username };
socket.connect();
}, []);
function SendMessage() {
socket.emit("test", "hello");
// selectedChatUser
console.log(socket.connected);
if (selectChatUser) {
socket.emit("private message", {
content: "hello there",
to: selectChatUser.userID,
});
console.log("Message Sent");
}
}
And here is my server side code:
const app = require("express")();
const httpServer = require("http").createServer(app);
const cors = require("cors");
app.use(cors());
const options = {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
};
const io = require("socket.io")(httpServer, options);
io.use((socket, next) => {
const username = socket.handshake.auth.username;
if (!username) {
return next(new Error("invalid usernmae"));
}
socket.username = username;
next();
});
io.on("connect", (socket) => {
console.log("New connection");
const users = [];
for (let [id, socket] of io.of("/").sockets) {
users.push({
userID: id,
username: socket.username,
});
}
socket.broadcast.emit("user connected", {
userID: socket.id,
username: socket.username,
});
socket.emit("users", users);
socket.on("test", () => {
console.log("test");
});
socket.on("private message", ({ content, to }) => {
console.log(content);
console.log("hello there");
socket.to(to).emit("private message", {
content,
from: socket.id,
});
});
});
httpServer.listen(3001, () => {
console.log("Server has started");
});
// https://socket.io/
Following line will re-run every time your component renders, losing reference to the socket that was actually connected:
socket = io("http://localhost:3001", connectionOptions);
You can use a ref to persist it between renders:
const socketRef = useRef();
socketRef.current = socket;
// use socketRef.current everywhere else in your code

React Native - iOS subscription receipt verification (firebase)

currently I am working on a app but struggling to find since last two weeks the following:
I have react native iOS app with RN-iap for subscription.. and would like to implement receipt verification via cloud function at firebase.
I found a similar solution but its with SWIFT: https://www.loopwerk.io/articles/2020/storekit-webhooks-firestore/
can anybody please help me convert the code (swift below) into React Native ? really appreciate
or if any suitable example or lines please.
(I am using React native firebase).
I can able to fetch receipt and save in Firestore collection. Thanks in advance.
below are the codes:
FRONT END CALLING Cloud function
import Firebase
import FirebaseFunctions
import Foundation
final class CloudFunction {
private lazy var functions = Functions.functions()
func validateReceipt(receipt: String, completionHandler: #escaping () -> Void) {
let parameters = ["receipt": receipt]
functions.httpsCallable("validateReceipt").call(parameters) { _, error in
if let error = error {
print(error)
}
completionHandler()
}
}
}
Cloud Function for above:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const fetch = require('node-fetch');
const db = admin.firestore();
const runtimeOpts = {
memory: '1GB',
};
function validateAndStoreReceipt(url, options, userSnapshot) {
return fetch(url, options).then(result => {
return result.json();
}).then(data => {
if (data.status === 21007) {
// Retry with sandbox URL
return validateAndStoreReceipt('https://sandbox.itunes.apple.com/verifyReceipt', options, userSnapshot);
}
// Process the result
if (data.status !== 0) {
return false;
}
const latestReceiptInfo = data.latest_receipt_info[0];
const expireDate = +latestReceiptInfo.expires_date_ms;
const isSubscribed = expireDate > Date.now();
const status = {
isSubscribed: isSubscribed,
expireDate: expireDate,
};
const appleSubscription = {
receipt: data.latest_receipt,
productId: latestReceiptInfo.product_id,
originalTransactionId: latestReceiptInfo.original_transaction_id
};
// Update the user document!
return userSnapshot.ref.update({status: status, appleSubscription: appleSubscription});
});
}
exports.validateReceipt = functions.runWith(runtimeOpts).https.onCall(async (data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError('permission-denied', 'The function must be called while authenticated.');
}
if (!data.receipt) {
throw new functions.https.HttpsError('permission-denied', 'receipt is required');
}
// First we fetch the user
const userSnapshot = await db.collection('users').doc(context.auth.uid).get();
if (!userSnapshot.exists) {
throw new functions.https.HttpsError('not-found', 'No user document found.');
}
// Now we fetch the receipt from Apple
let body = {
'receipt-data': data.receipt,
'password': 'MY_SECRET_PASSWORD',
'exclude-old-transactions': true
};
const options = {
method: 'post',
body: JSON.stringify(body),
headers: {'Content-Type': 'application/json'},
};
return validateAndStoreReceipt('https://buy.itunes.apple.com/verifyReceipt', options, userSnapshot);
});
continuation another cloud function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const db = admin.firestore();
const runtimeOpts = {
memory: '1GB',
};
exports.appleWebhook = functions.runWith(runtimeOpts).https.onRequest(async (req, res) => {
// Only allow POST requests
if (req.method !== 'POST') {
return res.status(403).send('Forbidden');
}
// Check for correct password
if (req.body.password !== 'MY_SECRET_PASSWORD') {
return res.status(403).send('Forbidden');
}
const receipt = req.body.unified_receipt.latest_receipt_info[0];
// Find the user with this stored transaction id
const userQuerySnapshot = await db.collection('users')
.where('appleSubscription.originalTransactionId', '==', receipt.original_transaction_id)
.limit(1)
.get();
if (userQuerySnapshot.empty) {
throw new functions.https.HttpsError('not-found', 'No user found');
}
const expireDate = +receipt.expires_date_ms;
const isSubscribed = expireDate > Date.now();
const status = {
isSubscribed: isSubscribed,
expireDate: expireDate,
};
const appleSubscription = {
receipt: req.body.unified_receipt.latest_receipt,
productId: receipt.product_id,
originalTransactionId: receipt.original_transaction_id,
};
// Update the user
return userQuerySnapshot.docs[0].ref.update({ status: status, appleSubscription: appleSubscription }).then(function() {
return res.sendStatus(200);
});
});

Resources