I want to make a mute command where you can mute a user for a specific time.
I have used a setTimeout() function before but it isnt useful for a bigger time or if the bot stops and start again. So now I am saving the time to a database:
expires = new Date(new Date().getTime() + time).toLocaleString()
// -> 9.9.2021, 22:21:34
So now I want to unmute this user on 9.9.2021, 22:21:34. The problem is that I dont know how to give the bot a signal that the user has to be unmuted in time. So how to tell the bot when to call the function unmute(). For example if I get the data from the database when the bot is started and the data is: 9.9.2021, 22:21:34. Now the bot has to call a function at this date. How?
One common approach is to use the database as a message-queue. The bot would "poll" the database at regular intervals to pull relevant events and execute those that are ready. When an event is pulled, it is also deleted from the database.
Related
setTimeout(() => {
targets.forEach(target => target.roles.remove(arole));
message.channel.send(`Removed ${arole}`);
}, RoleTime);
}
}
I use the above snippet to take away the roles of mentioned users after mentioned time. It works perfectly (I use ms to store RoleTime in milis). But when the time is like 12h the bot doesn't seem to reply and take away the role(Hosted on Heroku). Any idea why? What are the other ways to achieve this?
setTimeout doesn't work for long periods of time on services like heroku, and in general it's a bad idea to use setTimeout for operations like this anyway.
Some are saying to use a cron job for something like this, but due to the nature of the discord gateway, this is probably not a good idea.
Consider storing the expiry jobs in some sort of persistent database (sql, mongo etc)
Within your bot, every set period of time (30 seconds, 60 minutes) etc:
Query the database, fetch all expiry jobs that have passed or are equal to the expiry time
SELECT profile_snowflake,role_snowflake FROM expiry_jobs WHERE expiry_time <= ?
Iterate through each expiry job and remove the roles
Reschedule task
This allows for the bot to do expiry jobs across different processes - with services such as heroku, the bot can randomly restart which would completely reset the state of the bot, so you need to use some sort of persistent data store for the expiry jobs.
I have made a discord bot using discord.js, discord.js-commando, and MongoDB everything works how I want to however I want to add a new idea to the discord bot.
I would like to start a new project where members can post X: coordinate, Y: coordinate, and the title they need from a mobile game in a discord channel and then it will run the python script to give the title at the location.
For Example:
My coordinates and the title I need:
X: 748 Y: 614 duke
Right now in the python script I just have the position of each title, If they are detected then it will click the title.
But what I need to do is find the best way to get the user's message like the above coordinates and title, once I get that user's message I will then need to run the python script to grant the title to the user. Then I need to wait 5 minutes before moving to the next person. I know how to run the python script with node.js.
I would just like a little bit of help on finding the best solution to getting the user's request (from a discord channel) then running the python script and then waiting 5 minutes before moving to the next request.
I think as well within the python script I can make it so it will click and enter the coordinates and then search for the location, once it gets there it will click the city and apply the title.
The main thing I am struggling with is Discord.js part which is collecting the message from the users to then allow the script to run.
Thank you,
I hope this makes sense. If not then please ask for more information below and I will try is give you more context/information.
UKzs
I know nothing about the part that "collects locations from coordinates in a mobila game", but assuming you can already do that, then you might find luck adding a 5-minute cooldown with https://discordjs.guide/command-handling/adding-features.html#cooldowns .
I haven't used discordjs-commando, but I have used discordjs and I would approach a command cooldown by setting a global variable with the most recent time the command was executed at.
var cooldown=new Date();
// Note: no restrictions set on if it's a command or not
client.on("message",msg=>{
// if difference between now & last exec is less than 5 minutes, ignore
if((new Date().getTime()-cooldown.getTime())<=(5*60*1000)) {
msg.channel.send(":x: I'm on cooldown, try again later");
return;
}
// set cooldown to now
cooldown=new Date();
// execute python script
msg.channel.send(msg.author.toString()+", you've been given your title");
});
I use pusher to implement real-time chat and notifications in my website. Users are allowed to start conversation(chat) with others and conversation can be only 1 on 1.
Messages are also stored in db so that user could have chat history as well.
I user with userId=14 has three active conversation I would generate JS script in php that would connect him to pusher and subscribe for three presence-channels representing each of three conversations. Every channel has events like "new-msg" etc. Everything work great - users get message if chat window is open or notification badge if not.
The problem starts when another user want to start a new conversation with userId=14. There is no private or presence channel for that. If I used public channel then every logged in user would get notified which is not good.
What I do know is that once logged in my website users connect to pusher and additionally to already active presence-channels subsribe to public channel "new-conversations" but every user waits for specific event which represents his userId.
var pusher = new Pusher('APP_KEY');
var channel = pusher.subscribe('new-conversations');
channel.bind(userId,
function(data) {
// subscribes to new presence-channel using information from data variable
}
);
When another user wants to start conversation with userId=14 he makes ajax call to server where PHP script generates event representing userId=14 containing data about himself and sends it to every connected(logged in) user but only userId=14 is waiting for this. Once triggered userId=14 can subsribe to new presence-channel.
While all this scenario works, I was wondering if there is some better, more cleaner out-of-the-box solution to this situation? I have read through pusher documentation but found nothing but I refuse to except that pusher developrs havent though about it.
POSSIBLE SOLUTION
I though of another solution. Every user should subscribe to presence-channel var channel = pusher.subscribe('presence-14'); where 14 = userId. If userId= 39 wants to start conversation with him he would send userId=14 to server and server would send userId=39 to channel "presence-14". Is that it?
It is needed to send an alert to the chat after a timer has started.
Scenario:
Remind me to call Bob in 5 minutes
OK, will remind you in 5 minutes
After this dialog fulfillment server will start a timer and when the time goes off, event is to be triggered.
But when using the event api in API.ai will not trigger a message to the chat window which was built using the JS api.
Is there a another way to achieve this.
This is very much possible. In the intents that you setup on API.ai, use #sys.time so that 'call me in 5 minutes' will return a time like 14:05:00. You can use this parameter to start a timer on your JS script and send the message when timer expires.
I'm developing a chat module for my application...
I'm opening a window for users to chat, is there way that when users close the chat window, I can update status of that record...i mean event for the closed browser?
I know that default session time is 24mins,
so after 24mins of inactivity, user will be kicked out from the site and will asked to login once again.
How to delete/flush the data in my database, when user has no activity for 24mins (when user is logged out from the session due to inactivity)?
1) You'll need javascript onUnload event for this one. It'll send an asynchronous query to your webserver, setting the offline status of the user. However, you should not rely solely on this event and also set up the 24 mins auto-offline timeout because it is not guaranteed that the user is using javascript.
2) I think your best option here is running a cron job (every 30 mins or so?) that queries your database, identifies the users whose last activity was more than 24 mins ago and then deletes the associated data.
Store every chat entry's timestamp in UNIX_TIMESTAMP. When a new chat entry incoming check every entries timestamp where timestamp is smaller than now - 24 mins. Kick users.
1) use the unload event
2) if you are developing a chat, i guess that you have a periodical function that calls the server constantly to retrieve the messages. Each time this function is called, the inactivity time will be reset, even if the user haven't sent a message. If you want to logout the user when he doesn't write anything in 24min you cant rely on the php sessions.
What you can do is: save in the db, the last time the user wrote a message on the chat, and each time you use your periodical function, validate if the user hasn't wrote anything in the last 24 mins
Use a javascript function for the event
window.onbeforeunload = myLogoutFunction;
Note: This javascript will not work on browser crash.
Have a user_log database table and fill the login and "logout" dates in it.
When there is a user with not updated logoff date, then you can assume there was something wrong with his connection.
$where = " AND `users_id`='".$response['userfound']['id']."'";
$where .= " AND `logoffdatetime`='0000-00-00 00:00:00'";
After 24min php session is gone (default php.ini settings). It wont be much usable. But you can still save into the user_log table.
You should not need the flush database.
Keeping the chat users via database alive is bad idea. Instead use a small file with timestamp in it.
Here some other useful tips
Detect if the user coming back without logout
$user_navigates = false;
if(isset($_SERVER['HTTP_REFERER']) && basename($_SERVER['HTTP_REFERER']) != _PAGE)
$user_navigates = true;
save also page refreshes into session
if(isset($_GET['pagerefreshed']))
$_SESSION['pagerefreshed'] = $_GET['pagerefreshed'];
save the logging out user_id into session, so you can use it restore things. For instance no need to reload page.
$_SESSION['loggedout']['user_id'] == $login->user_id