Discord Bot : Add roles from a JSON file - json

I would like to add or remove Reaction Roles from a JSON file on Discord. I would like that when a user clicks on the emoji, the corresponding role is added from a JSON file that links the role and the emoji.
For the moment my code works but it's not clean.
Here is my code :
const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
const { token } = require('./config.json');
const Roles = require('/roles.json');
client.on("ready", () => {
console.log("Bot opérationnel");
});
client.on('message', message => {
if (message.content === 'Choisir un rôle :') {
const reactionEmoji1 = message.guild.emojis.cache.find(emoji => emoji.name === 'FR');
const reactionEmoji2 = message.guild.emojis.cache.find(emoji => emoji.name === 'UK');
message.react(reactionEmoji1);
message.react(reactionEmoji2);
}
});
client.on("messageReactionAdd", (reaction, user) => {
if(user.bot) return;
console.log("Réaction ajoutée");
if(reaction.message.id === "1037314191163412573"){
if(reaction.emoji.name === "FR"){
var member = reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur
member.roles.add("1036583426620399647").then (mbr => { // Assigne le role
console.log("Role attribué avec succès pour" + mbr.displayName);
})
.catch(err => {
console.log("Le role n'a pas pu etre attribué :" + err);
});
}
if(reaction.emoji.name === "UK"){
var member = reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur
member.roles.add("1036583684247134208").then (mbr => { // Assigne le role
console.log("Role attribué avec succès pour" + mbr.displayName);
})
.catch(err => {
console.log("Le role n'a pas pu etre attribué :" + err);
});
}
}
});
client.on("messageReactionRemove", (reaction, user) => {
if(user.bot) return;
console.log("Réaction supprimée");
if(reaction.message.id === "1037314191163412573"){
if(reaction.emoji.name === "FR"){
var member = reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur
member.roles.remove("1036583426620399647").then (mbr => { // Assigne le role
console.log("Role supprimé avec succès pour" + mbr.displayName);
}).catch(err => {
console.log("Le role n'a pas pu etre attribué :" + err);
});
}
if(reaction.emoji.name === "UK"){
var member = reaction.message.guild.members.cache.find(member => member.id === user.id); // Va récuperer le membre du serveur
member.roles.remove("1036583684247134208").then (mbr => { // Assigne le role
console.log("Role supprimé avec succès pour" + mbr.displayName);
}).catch(err => {
console.log("Le role n'a pas pu etre attribué :" + err);
});
}
}
});
client.login(token);
And here is the JSON file :
{
"message": "1037314191163412573",
"channel": "1037311658416152616",
"reactions": [
{
"emoji": "FR",
"role": "1036583426620399647"
},
{
"emoji": "UK",
"role": "1036583684247134208"
}
]
}

Instead of directly checking each emoji with an if statement, you could loop through each value in the object and check every emoji you have stored.
This should work if you add more emojis to you object, as long as its structure is consistent.
Example:
// assuming `data` is your object
for(r of data.reactions) {
if(reaction.emoji.name === r.emoji) {
let member = reaction.message.guild.members.cache.find(member => member.id === user.id)
member.roles.add(r.role).then(() => {
// etc
})
}
}

Voici le code qui fonctionne :
client.on("messageReactionAdd", (reaction, user) => {
if (user.bot) return;
if (reaction.message.id === role_list.message) {
let member = reaction.message.guild.members.cache.find(member => member.id === user.id);
for (let i = 0; i < role_list.reactions.length; i++) {
let r = role_list.reactions[i];
if (reaction.emoji.name === r.emoji) {
member.roles.add(r.role).then(mbr => {
console.log("Role attribué avec succès pour " + mbr.displayName);
}).catch(err => {
console.log("Le role n'a pas pu etre attribué :" + err);
});
}
}
}
});```

Related

Payment SDK React Integration - MercadoPago

I´m trying to integrate the payment SDK of MercadoPago.
The documentation indicates to add this two scripts on the html, but I can´t make it work on React.
How can I pass this scripts to a React component?
// SDK MercadoPago.js V2
<script src="https://sdk.mercadopago.com/js/v2"></script>
<script>
// Agrega credenciales de SDK
const mp = new MercadoPago("PUBLIC_KEY", {
locale: "es-AR",
});
// Inicializa el checkout
mp.checkout({
preference: {
id: "YOUR_PREFERENCE_ID",
},
render: {
container: ".cho-container", // Indica el nombre de la clase donde se mostrará el botón de pago
label: "Pagar", // Cambia el texto del botón de pago (opcional)
},
});
</script>
I´ve tried this, but does not work, (idk why it makes a POST to localhost:3001 (client):
export default function Suscripcion(props) {
//const { id } = useParams(); // id de producto
const id = 1122;
const [preferenceId, setPreferenceId] = useState(null);
const PUBLIC_KEY_VENDEDOR_PRUEBA =
"TEST-001debb2-d8d5-40a4-953f-8ca65aaa0fa0";7
function addCheckOut() {
const mp = new window.MercadoPago(PUBLIC_KEY_VENDEDOR_PRUEBA, {
locale: "es-AR",
});
// Inicializa el checkout
mp.checkout({
preference: {
id: preferenceId,
},
render: {
container: `#${FORM_ID}`, // Indica el nombre de la clase donde se mostrará el botón de pago
label: "Pagar", // Cambia el texto del botón de pago (opcional)
},
});
}
useEffect(async () => {
// luego de montarse el componente, le pedimos al backend el preferenceId
try {
const post = await fetch("http://localhost:3000/api/orders", {
method: "POST",
made: "cors",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({
productId: id,
name: "agustin",
lastname: "miotti",
email: "amiotti#secco.com.ar",
}),
});
const data = await post.json();
console.log(data.id);
setPreferenceId(await data.id);
} catch (error) {
console.log(error);
}
}, []);
useEffect(() => {
if (preferenceId) {
// con el preferenceId en mano, inyectamos el script de mercadoPago
const script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://sdk.mercadopago.com/js/v2";
script.addEventListener("load", addCheckOut);
//script.setAttribute("preference", preferenceId);
// const form = document.getElementById(FORM_ID);
// form.appendChild(script);
document.body.appendChild(script);
}
}, [preferenceId]);
return <form id={FORM_ID} method="GET" />;
}
Can anyone help me with this? Maybe it looks prety simple, but i still don´t get it.
Try this
hooks/useScript.js
import { useEffect, useState } from "react"
export default function useScript(url) {
const [loaded, setLoaded] = useState(false)
useEffect(() => {
const existingScript = document.querySelector(`[src="${url}"]`)
if (existingScript) {
setLoaded(true)
} else {
const script = document.createElement("script")
script.src = url
script.async = true
script.onload = () => {
setLoaded(true)
}
document.body.appendChild(script)
}
}, [url])
return {
loaded
}
}
Suscripcion.jsx
import { useEffect, useRef, useState } from "react"
import useScript from './hooks/useScript'
const PUBLIC_KEY_VENDEDOR_PRUEBA = "TEST-001debb2-d8d5-40a4-953f-8ca65aaa0fa0";
export default function Suscripcion(props) {
//const { id } = useParams(); // id de producto
const id = 1122;
const [preferenceId, setPreferenceId] = useState(null)
const formRef = useRef(null)
const initialized = useRef(false)
const { loaded } = useScript("https://sdk.mercadopago.com/js/v2")
useEffect(() => {
if (initialized.current) {
return
}
if (!loaded) {
return
}
if (preferenceId === null) {
return
}
initialized.current = true
const mp = new window.MercadoPago(PUBLIC_KEY_VENDEDOR_PRUEBA, {
locale: "es-AR",
});
mp.checkout({
preference: {
id: preferenceId,
},
render: {
container: formRef.current.id, // Indica el nombre de la clase donde se mostrará el botón de pago
label: "Pagar", // Cambia el texto del botón de pago (opcional)
},
});
}, [loaded, preferenceId])
useEffect(() => {
// luego de montarse el componente, le pedimos al backend el preferenceId
const fetchId = async () => {
try {
const post = await fetch("http://localhost:3000/api/orders", {
method: "POST",
made: "cors",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
body: JSON.stringify({
productId: id,
name: "agustin",
lastname: "miotti",
email: "amiotti#secco.com.ar",
}),
});
const data = await post.json();
console.log(data.id);
setPreferenceId(await data.id);
} catch (error) {
console.log(error);
}
}
fetchId()
}, []);
return <form ref={formRef} id="checkout-page" method="GET" />;
}

Condition with mysql request

I have a problem for my image (I use multer), when in my user edit form.
Is it possible to put conditions on my image if the field is null, it still sends my request to the server.
I did the necessary on the front-end to send the firstname and lastname data but for the image impossible, that's why I want to go through the back end.
exports.updateUser = (req, res, next) => {
try {
if (res.locals.userId === parseInt(req.params.id)) {
const user = [
[req.body.user_lastName],
[req.body.user_firstName],
[`${req.protocol}://${req.get('host')}/images/${req.file.filename}`],
[req.params.id]
]
const sql = "UPDATE users SET user_lastName=?, user_firstName=?,user_avatar=? WHERE user_id=?";
db.query(sql, user, function (error, results) {
if (!error) {
res.status(200).json({ message: 'modification profil executé' });
} else {
console.log(error)
res.status(401).json({ error: 'Erreur utilisateur table users' });
}
});
} else {
res.status(401).json({ error: 'erreur d\'authentification, vous n\'avez pas les droits pour modifier ce profil' })
}
} catch (error) {
res.status(500).json({ error });
console.log(error)
}
}
Use an if statement to set a variable conditional on whether the field was provided.
exports.updateUser = (req, res, next) => {
try {
let image = null;
if (req.?file.?filename) {
image = `${req.protocol}://${req.get('host')}/images/${req.file.filename}`;
}
if (res.locals.userId === parseInt(req.params.id)) {
const user = [
req.body.user_lastName,
req.body.user_firstName,
image,
req.params.id
]
const sql = "UPDATE users SET user_lastName=?, user_firstName=?,user_avatar=? WHERE user_id=?";
db.query(sql, user, function(error, results) {
if (!error) {
res.status(200).json({
message: 'modification profil executé'
});
} else {
console.log(error)
res.status(401).json({
error: 'Erreur utilisateur table users'
});
}
});
} else {
res.status(401).json({
error: 'erreur d\'authentification, vous n\'avez pas les droits pour modifier ce profil'
})
}
} catch (error) {
res.status(500).json({
error
});
console.log(error)
}
}

Retrieve the status of a response from a query to MySQL with no match

I am working on the login controller of my web app, especially if a user want to log without an existing mail in the DB. I can't reach the res.status in the frontend in order to handle this specific response.
My backend:
exports.signin = (req, res) => {
const email = req.body.email;
const password = req.body.password;
//Recherche du compte associé au email pour vérifié le mdp
db.query("SELECT password FROM users WHERE email = ?", email, (err, result) => {
if(result.length === 0){
console.log(err)
res.status(401).json({err})
} else {
console.log(result)
let encryptedPassword = result[0].password
console.log(encryptedPassword)
let verifyPassword = bcrypt.compareSync(password, encryptedPassword)
//Vérification du MDP
if (verifyPassword === true) {
//Requete SQL pour assigné un token en fonction de l'id qui correspond à l'utilisateur dans la BDD
db.query("SELECT id, prenom FROM users WHERE email = ?" , email, (err, result) => {
if(result){
let userID = result[0].id
let userPrenom = result[0].prenom
console.log(userID)
console.log('Le mot de passe correspond à celui renseigné dans la DB')
res.status(200).json({user_id: userID,
prenom: userPrenom,
token: jwt.sign(
{user_id: userID},
'RANDOM_TOKEN_SECRET',
{ expiresIn: '24h'})})
}
})}
else{
res.status(208).send({message: 'pbl'})
console.log('Le mot de passe ne correspond pas !')
}
}
}
)
}
I used to have if(err){console.log(err)} but my BACKEND kept crashing whenever I try an unknown email.
My frontend:
const login = () => {
Axios.post('http://localhost:3001/auth/signin', {
email: MailLog,
password: userPasswordLog,
})
.then((response) => {
//Récupérartion des informations user
if (response.status === 200){
console.log(response)
setLoginStatus("Bonjour " + response.data.prenom + " !")}
else if (response.status === 401) {
console.log(response)
setLoginStatus("Nous ne trouvons pas de compte associé à cette adresse mail")}
else {
console.log(response)
setLoginStatus('Le mot de passe et l\'adresse mail ne correspondent pas !')}
})
}
What would be the best way to fix my problem? Thank you
NB: The status code is changing when I change it in my res.status yet I can't do anything with it

"error": "Cannot read property 'findOne' of undefined"

Hello everybody !!
Here I have a big problem, I would like to do a registration in back with Node.js sequelize and mySql.
I looked here and there but I did not find the answer to my problem so I came to ask you for help.
With mongoDb, it was easier but I admit that I am going in circles.
Here is my code:
// Importation :
// Bcrypt:
const bcrypt = require("bcrypt");
// Jsonwebtoken d'authentification:
const jwt = require("jsonwebtoken");
// Import du models user:
const models = require("../models/user")
//////////////////////////////////////////////////////////////////////////////////////////////
// Fonction/
// Incription:
exports.signup = (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
const bio = req.body.bio;
const admin = req.body.admin;
console.log(req.body)
try {
models.User.findOne({
attributes: ['email'],
where: {
email: email
}
})
.then((userFound => {
if (!userFound) {
bcrypt.hash(password, 10, function (err, bcryptPassword) {
const newUser = models.User.create({
username : username,
email : email,
password : bcryptPassword,
bio : bio,
admin : false
})
.then(newUser => {
res.status(201).json({
'userId': newUser.id
})
})
.catch(err => {
res.status(500).json({
'error': 'Impossible d\'ajouter un utilisateur'
})
})
})
} else {
return res.status(409).json({
error: 'Ce compte existe déjà '
})
}
})
.catch((err) =>
res.status(500).json({
'err': err + 'Impossible de vérifier l\'utilisateur',
})
)
)
}catch (error) {
res.status(400).json({
error: error.message
});
}
}
And the model User:
'use strict'
const { db } = require('../config/connexion')
const { Sequelize, DataTypes } = require('sequelize')
const user = db.define('User', {
// Model attributes are defined here
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING,
bio: DataTypes.TEXT,
admin: DataTypes.BOOLEAN,
})
module.exports = user
and connexion.js:
// Connexion de sequelize à mysql:
const {
Sequelize
} = require('sequelize')
const db = new Sequelize(
process.env.NAMEDB,
process.env.USERDB,
process.env.PASSWORDDB, {
host: process.env.HOSTDB,
dialect: process.env.DIALECTDB,
pool: {
min: 0, // nombre minimum de connexion dans le pool
max: 5, // nombre maximum de connexion dans le pool
acquire: 30000, // durée maximale, en millisecondes, pendant laquelle ce pool essaiera d'obtenir la connexion avant de lancer une erreur
idle: 10000, // temps maximum, en millisecondes, pendant lequel une connexion peut être inactive avant d'être libérée
},
}
)
//////////////////////////////////////////////////////////////////////////////////////////////
// Etablit la connexion à mysql:
const dbConnect = async (db) => {
await db
.authenticate()
.then(() => {
db.sync()
console.log('Connecté à la base de données MySQL!')
})
.catch((err) => {
console.error('error: ' + err.message)
setTimeout(() => {
dbConnection(db)
}, 5000)
})
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Exportation:
module.exports = {
db,
dbConnect,
}
Certainly there is still a lot to do, but being a beginner I improve as I go.
Do not be angry with me if my English is not at the top, I admit that it is not my strong point.
Thanking you in advance for all the help provided.
You are directly setting the export object equal to the user object.
When you do this const models = require("../models/user"), models is equal to the user value directly.
You can directly use models.findOne. Read this
You are setting the user variable to be the export of the file
module.exports = user
You then import the user variable as models.
const models = require("../models/user")
this means that you do not need to access user as a property. Instead use:
models.findOne({ // Changed from models.User to models
attributes: ["email"],
where: {
email: email,
},
});
This should stop your current error, but you will keep on getting errors until you change all instances of models.User to models.
Your main file should end up looking like this:
// Importation :
// Bcrypt:
const bcrypt = require("bcrypt");
// Jsonwebtoken d'authentification:
const jwt = require("jsonwebtoken");
// Import du models user:
const models = require("../models/user");
//////////////////////////////////////////////////////////////////////////////////////////////
// Fonction/
// Incription:
exports.signup = (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
const bio = req.body.bio;
const admin = req.body.admin;
console.log(req.body);
try {
models
.findOne({
attributes: ["email"],
where: {
email: email,
},
})
.then(
((userFound) => {
if (!userFound) {
bcrypt.hash(password, 10, function (err, bcryptPassword) {
const newUser = models
.create({
username: username,
email: email,
password: bcryptPassword,
bio: bio,
admin: false,
})
.then((newUser) => {
res.status(201).json({
userId: newUser.id,
});
})
.catch((err) => {
res.status(500).json({
error: "Impossible d'ajouter un utilisateur",
});
});
});
} else {
return res.status(409).json({
error: "Ce compte existe déjà ",
});
}
}).catch((err) =>
res.status(500).json({
err: err + "Impossible de vérifier l'utilisateur",
})
)
);
} catch (error) {
res.status(400).json({
error: error.message,
});
}
};
Check your "model" file to see if the "User" model exists there. Also check if you are using the 'module.exports'
You are exporting the User model directly, but calling it like it is in an object property named User. You can either access it directly, changing:
models.User.findOne
to:
models.findOne
and then you'd probably want to rename models to User.
Or change your export to:
module.exports = { User: user };

How to fix an undefined json in angular?

I have a form with a uploader input to get an image "angular-file-uploader" npm library. but in the function that receive the data, it receive the data undefined, I can't do a JSON.parse() with the data.
I don't know if the problem is in the backend (nodejs) but with postman the backend works.
<angular-file-uploader #fileUpload1
[config]="afuConfig"
[resetUpload]=resetVar
(ApiResponse)="avatarUpload($event)">
</angular-file-uploader>
this.afuConfig = {
multiple: false,
formatsAllowed: '.jpg, .jpeg, .png, .gif',
maxSize: '50',
uploadAPI:{
url: this.url+'upload-avatar',
headers:{
// 'Content-Type' : 'text/plain;charset=UTF-8',
'Authorization': this.token
}
},
theme: 'attachPin',
hideProgressBar: false,
hideResetBtn: true,
hideSelectBtn: false,
attachPinText:'Sube la imagen'
};
}
avatarUpload(book)
{
console.log(book); //here the error is TypeError: Cannot read property 'length' of undefined
let data = JSON.parse(book.response);// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position 0
this.book.image = data.book.image;
console.log(data);
}
backend nodejs function uploadAvatar()
uploadAvatar: function(req, res){
// Configurar el modulo multiparty (md) routes/user.js
// Recoger el fichero de la petición
var file_name = 'imagen no subida...';
if(!req.files){
return res.status(404).send({
status: 'error',
message: file_name
});
}
// Conseguir el nombre y la extension del archivo
var file_path = req.params.file0.path;
// var file_split = file_path.split('\\');
// ** Adventencia ** En linux o mac
var file_split = file_path.split('/');
// Nombre del archivo
var file_name = file_split[2];
// Extensión del archivo
var ext_split = file_name.split('\.');
var file_ext = ext_split[1];
// Comprobar extension (solo imagenes), si no es valida borrar fichero subido
if(file_ext != 'png' && file_ext != 'jpg' && file_ext != 'jpeg' && file_ext != 'gif'){
fs.unlink(file_path, (err) => {
return res.status(200).send({
status: 'error',
message: 'La extensión del archivo no es valida.'
});
});
}else{
// Sacar el id del libro
var params = req.body;
var bookId = req.params.bookId;
// Buscar y actualizar documento bd
Book.findOneAndUpdate({_id: bookId}, {image: file_name}, {new:true}, (err, bookUpdated) => {
if(err || !bookUpdated){
// Devolver respuesta
return res.status(500).send({
status: 'error',
message: 'Error al guardar la imagen'
});
}
// Devolver respuesta
return res.status(200).send({
status: 'success',
image: book.image,
user: bookUpdated
});
});
}
},
Edited
console.log(book);
TypeError: Cannot read property 'length' of undefined
at http.js:168
at Array.forEach (<anonymous>)
at HttpHeaders.lazyInit (http.js:156)
at HttpHeaders.init (http.js:277)
at HttpHeaders.forEach (http.js:379)
at Observable._subscribe (http.js:2398)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at subscribeToResult (subscribeToResult.js:9)
avatarUpload(book)
{
console.log(book); //here the error is TypeError: Cannot read property 'length' of undefined
let data = JSON.parse(book.response);// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position 0
this.book.image = data.book.image;
console.log(book);
}
at MergeMapSubscriber._innerSub (mergeMap.js:59)
book.response is not a json object. That is why you getting the following error while trying to parse it.
let data = JSON.parse(book.response);
// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position.
Can you please update question with book data?