Is there anyway how i can edit my message after the bot restarted, i want him to send an message, restarting now and after the restart it should edit the message to Done :white_checkmark:
console.log(message.author.tag + ' restarted The bot')
message.reply('You restarted the bot, wait a few seconds') // <-- this message should be edited
bot.channels.get("593824605144088586").send(message.author.tag + ' restarted the bot')
bot.channels.get("593824605144088586").send('---------------------------------------------------')
setTimeout(function () { resetBot() }, 5000);
function resetBot() {
restarted = true;
bot.channels.get("593824605144088586").send('Restarting...')
.then(msg => bot.destroy())
.then(() => bot.login(auth.token));
}
Message.reply() returns a Promise, resolving with another Message. To use the sent message, you have to access the returned value. Mind the scope of restartMsg in the examples below.
console.log(`${message.author.tag} restarted the bot.`);
message.reply('You restarted the bot, please wait.')
.then(restartMsg => {
const logsChannel = bot.channels.get('593824605144088586');
if (!logsChannel) return console.error('Logs channel missing.');
logsChannel.send(`${message.author.tag} restarted the bot.\n---`)
.then(() => {
setTimeout(() => {
logsChannel.send('Restarting...')
.then(() => bot.destroy())
.then(() => bot.login(auth.token))
.then(() => restartMsg.edit('Restart successful.'));
}, 5000);
});
})
.catch(console.error);
Async/await equivalent:
// Asynchronous context (meaning within an async function) needed to use 'await.'
try {
console.log(`${message.author.tag} restarted the bot.`);
const restartMsg = await message.reply('You restarted the bot, please wait.');
const logsChannel = bot.channels.get('593824605144088586');
if (!logsChannel) return console.error('Logs channel missing.');
await logsChannel.send(`${message.author.tag} restarted the bot.\n---`);
setTimeout(async () => {
await logsChannel.send('Restarting...');
await bot.destroy();
await bot.login(auth.token);
await restartMsg.edit('Restart successful.');
}, 5000);
} catch(err) {
console.error(err);
}
Related
I wanted to run different error handling with React Promise.
API 1 and 2 should have different error handlings.
Execute APIs all at once to save time.
Run different error handling statements for each API as soon as possible, without waiting for the others.
Each API should continue even if one fails.
How can this be done?
Reference:
Fetch API requesting multiple get requests
Promise.all([
fetch(api1).then(value => value.json()),
fetch(api2).then(value => value.json())
])
.then((value) => {
console.log(value)
//json response
})
.catch((err) => {
console.log(err);
});
Promise.all is just wrapping up whatever promises you give it - so there's no reason you couldn't handle the errors separately for each one. For example, you could create a separate function for each of the fetches - you could even throw a custom error here that dictates some sort of "followUp" action to do, or identifies where the error is from, or anything (you can throw anything in javascript):
const fetchFromApi1 = async () => {
try {
const response = await fetch(api1);
return response.json();
} catch (err) {
console.log('API 1 failed');
// Throw a custom error
throw {
errorSource: 'API_CALL_1',
message: 'API call 1 failed',
};
}
};
const fetchFromApi2 = async () => {
// ----- 8< -----
};
Then you can just combine them in your your Promise.all - if you've thrown a custom error as above, you can use that to work out what to do:
const fetchAllTheThings = async () => {
try {
const [response1, response2] = await Promise.all([
fetchFromApi1(),
fetchFromApi2(),
]);
} catch (err) {
const { errorSource, message } = err;
// do something....
}
};
Edit
If you want to know which promise failed at the point of calling, you're probably better off using allSettled -
const fetchAllTheThings = async () => {
const [result1, result2] = await Promise.allSettled([
fetchFromApi1(),
fetchFromApi2(),
]);
if (result1.status === 'rejected') {
// Sad for promise 1
}
if (result2.status === 'rejected') {
// Sad for promise 2
}
};
const p1 = new Promise((res, rej) => {
setTimeout(() => {
res("p1 success")
}, 1000)
})
const p2 = new Promise((res, rej) => {
setTimeout(() => {
res("p2 success")
}, 3000)
})
const p3 = new Promise((res, rej) => {
setTimeout(() => {
rej("p3 failed")
}, 1000)
})
const p4 = new Promise((res, rej) => {
setTimeout(() => {
rej("p4 failed")
}, 2000)
})
Promise.allSettled([p1, p2, p3, p4])
.then(console.log)
Am using server sent events in an express server like this;
const sendEventDashboard = async (req, res) => {
try {
const orders = await Order.find({ agent_id: req.params.id })
.populate("agent_id")
.sort({ _id: -1 });
res.writeHead(200, {
"Cache-Control": "no-cache",
"Content-Type": "text/event-stream",
Connection: "keep-alive",
});
const sseId = new Date().toDateString();
const intervalId = setInterval(() => {
writeEvent(res, sseId, JSON.stringify(orders));
}, SEND_INTERVAL);
res.on("close", () => {
clearInterval(intervalId);
res.end();
// console.log("Client closed connection browser");
});
} catch (error) {
console.log(error);
}
};
export const getOrdersStreamDashboard = async (req, res) => {
if (req.headers.accept === "text/event-stream") {
sendEventDashboard(req, res);
} else {
res.json({ message: "Okay" });
}
};
and this is how i use it in a react app using a useEffect hook;
useEffect(() => {
const es = new EventSource(
`${process.env.REACT_APP_SERVER_URL}/weborders/${agentId}/stream_dashboard`
);
es.addEventListener("open", () => {
console.log("Dashboard stream opened!");
});
es.addEventListener("message", (e) => {
const data = JSON.parse(e.data);
setTrackOrderCount(data);
});
return () => {
// es.removeAllEventListeners();
es.close();
es.removeEventListener("message", (e) => {
const data = JSON.parse(e.data);
setTrackOrderCount(data);
});
};
}, [trackOrderCount]);
Everything runs as desired apart from event source always running until when the app/browser crushes. I get no error when it stops running and have to refresh for it to start again. This happens like after 10mins of inactivity or being on that same page for a long duration. Is there a way I can only run sse only when the state in the server is different from that of the client because i think the browser crushes because server sent events continuously run even when there's no event. I tried to remove the dependency array [trackOrderCount] in the useEffect and the setInterval in the server but that didn't solve the issue.
The solution might be in comparing the local and global versions before the event is sent but i've failed to figure out where to put that logic! I the browser's console, this is what i get;
and this will run for sometime then crush!
I am trying to implement an auto-logout functionality. I am implementing auto-logout using setTimeout.
Here is the code:
const onSubmitHandler = (e) => {
e.preventDefault();
console.log(emailId);
console.log(password);
axios.post('http://localhost:8080/login', { emailId, password })
.then(response => {
console.log(response);
localStorage.setItem('token', response.data.token);
axios.defaults.headers.common['Authorization'] = response.data.token;
setTimeout(() => {
localStorage.removeItem('token');
axios.defaults.headers.common['Authorization'] = null;
navigate('/');
}, 60000);
navigate('/');
})
.catch(err => {
console.log(err.response.data.message);
if (err.response.status === 500) {
navigate('/500');
}
setError(err.response.data.message);
})
}
The problem I am facing with my current implementation is that when I log in to my web app and then log out before auto-logout(i.e before setTimeout part fires) then again log in. Now when I stay I get navigated to "/" twice.
This means that the previous log in setTimeout did not die when I logged out manually.
Please guide me on how the previous setTimeout could be stopped once a new setTimeout starts, also let me know I more information is needed.
I saved the old token and the new token in the local storage. I also save the setTimeout in the local storage. The old token is used to determine if a new login has been made before the token expiration time and setTimeout is stored in the local storage to delete the previous setTimeout.
Here is my code:
const onSubmitHandler = (e) => {
e.preventDefault();
console.log(emailId);
console.log(password);
axios.post('http://localhost:8080/login', { emailId, password })
.then(response => {
console.log(response);
localStorage.setItem('token', response.data.token);
axios.defaults.headers.common['Authorization'] = response.data.token;
if (JSON.stringify(localStorage.getItem('oldToken')) !== JSON.stringify(localStorage.getItem('token'))) {
localStorage.setItem('oldToken', localStorage.getItem('token'));
clearTimeout(localStorage.getItem('timerId'));
const myTimeout= setTimeout(() => {
localStorage.removeItem('token');
axios.defaults.headers.common['Authorization'] = null;
navigate('/');
}, 60000);
localStorage.setItem('timerId', myTimeout);
}
navigate('/');
})
.catch(err => {
console.log(err.response.data.message);
if (err.response.status === 500) {
navigate('/500');
}
setError(err.response.data.message);
})
}
So how do we detect the userID with the kick command below?
So below is my kick command and whenever I kick a person I need to mention them (?kick #test) I want to kick a user by their user id (?kick 354353) and their mentions.
const client = new Discord.Client();
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// Ignore messages that aren't from a guild
if (!message.guild) return;
if (message.content.startsWith('?kick')) {
if (member.hasPermission(['KICK_MEMBERS', 'BAN_MEMBERS']))
return;
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
if (member) {
member
.kick('Optional reason that will display in the audit logs')
.then(() => {
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member');
// Log the error
console.error(err);
});
} else {
// The mentioned user isn't in this guild
message.reply("That user isn't in this guild!");
}
// Otherwise, if no user was mentioned
} else {
message.reply("You didn't mention the user to kick!");
}
}
});
client.login('TOKEN');
I recommend setting up Arguments if you plan to make more commands that take user input.
However if you're not interested in fully setting up arguments, you can just slice the message and grab the id. You will then need to fetch the member object, make sure to make your function is async for this, or use Promise#then if you prefer.
if (message.content.startsWith('?kick')) {
if (member.hasPermission(['KICK_MEMBERS', 'BAN_MEMBERS']))
return;
const memberId = message.content.slice(' ')[1];
if (memberId) {
const memberToKick = await message.guild.members.cache.fetch(userId);
memberToKick.kick('Optional reason that will display in the audit logs')
.then(() => {
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member');
// Log the error
console.error(err);
});
}
}
I'm making a support command: you type a command, the bot send you a message and then you reply to that message. I've used the awaitMessages function but it doesn't work.
case `support` : {
message.channel.send("What's your problem?");
let filter = m => m.author.id === message.author.id;
let msg = await message.channel.awaitMessages(filter, {maxMatches: 1});
message.channel.send("Your problem is: " + msg.first().content);
break;
}
To use .then() you need to return a Promise. This is a basic example of how you can use Promise:
const myFunction = () => {
return new Promise((resolve, reject) => {
if(taskIsSuccesFullyDone)
{
resolve(true); // Pass anything
}else{
reject('Something went wrong!');
}
});
}
myFunction().then(() => {
// Task is succesful completed.
// Do anything
})
.catch(error => console.log(error.message || error));
In your case, your code would look something like this:
function support_message() {
return new Promise((resolve, reject) => {
message.author.send(`Hello, <#${message.author.id}>, reply to this message explaining the problem you have.`)
.then(message => resolve(message))
.catch((error) => {
message.reply("I can't send you messages, be sure that you allow direct messages from unknown users to use this command.");
reject(error);
})
});
}
case `staff-support` : {
support_message().then(message => {
// We got the message object passed from the resolved Promise
// Do anything here
})
.catch((err) => {
// There was a problem!
// Do anything here.
});
break;
}