Custom status using discord.py rewrite - discord

This is my code
activity=discord.Game(name="Padamine", type=1)
Don’t worry, I put it in a #bot.event function. The problem is that my bot don’t put the custom status in his status. Can you help me?

Use change_presence() method to change bot status:
await bot.change_presence(activity=discord.Game("Padamine"))

If it's a static status (a status that won't change), it is recommended to use the activity keyword argument inside the bot constructor. If you want to make a dynamic status (a status that changes every now and then), use #tasks.loop of discord.ext.tasks (you can find more about tasks here)
# depending on what you name your variable, client/bot
client/bot = commands.Bot(command_prefix="yourprefix", activity=discord.Game("Padamine")) # removed type because there is no such key word argument
Also, it is recommended to not use await bot.change_presence() inside your on_ready event, I am mentioning this because many people do it and it's not good:
Discord has a high chance to completely disconnect you during the READY or GUILD_CREATE events (1006 close code) and there is nothing you can do to prevent it. As noted in the docs, on_ready is also triggered multiple times, not just once.
Basically: don't do anything in on_ready. (except printing that it came online obviously)

Related

Nextcord: I want to mention the sender of the slash command I made. How would I go about that?

I'm trying to make this command notify my admins of a bot test and need it to mention the user who called the command. How would I go about that? I don't fully understand how to get that information with slash commands.
#client.slash_command(name= "test", description="(For Deputies or Leader only) Checks the operational state of the client.", guild_ids=[806043206030589952])
#has_any_role(leader_id, deputy_id)
async def test(interaction:Interaction):
bot_log = channel_up(940125176723554394)
await bot_log.send(f'<#&806045254834847776>,{} has started diagnostics for the bot. Please ignore any possible disturbances for the next minute or so.')
Thanks in advance for the advice, it's the first discord bot I've ever created.
EDIT:
In documentation, I found the solution. I have to use interaction.user.mention to get it to mention the user who sent the command. Or at least in theory, I'm dealing with a different issue now. Hopefully this helps people who also were as confused as me out.
You can use the interaction.user.name function with an # at the beginning.
The code should look something like this:
await interaction.response.send_message("#"+str(interaction.user.name))

Discord.py adding reaction to webhook.send message

I am able to send messages to my discord channel via webhook very easily, however, when trying to add reactions to the messages it's very difficult, considering my programming is still trivial.
The code line I have right now is:
data_count=1
webhook.send(content=discord.Reaction(message="test", data=data_count, emoji="👍"), file=discord.File("american_eagle_excited.gif"), embed=discord.Embed(title="Sample Embed", description="This is the description"))
Everything, when I break down the parameters I can get to work besides the discord.Reaction class. I feel like I am missing something very easily and after trying to read through the class requirements I had to finally make my way to StackOverflow.
To add a reaction you need the discord.Message instance which is returned by the webhook.send method, you then add the reaction with message.add_reaction
message = webhook.send("test", wait=True, ...) # `wait=True` is really important, if we don't set this the bot will not wait for the message to be returned
await message.add_reaction("👍")

Discord.js Foreach loop add/removing roles

I'm trying to create a simple command that quickly adds a certain role to all server members (or remove, depending on the command used), but I'm having a bit of an issue.
Current code:
try {
message.guild.members.filter(m => !m.user.bot).forEach((member) => {
member.removeRole(role)
});
console.log(`Role ${role.name} taken from everyone!`)
} catch {
error => console.log(error)
}
This works, but I get a lot. And I mean A LOT of errors. Mostly time errors, such as timeout: error removing role.
It says in the start that there's too much listeners, so I went online to find this .setMaxListeners(0);
But it doesn't do anything
Any help would be appreciated! Thank you
All of the behavior you described is because Discord.js needs to make so many calls to the same API endpoint concurrently, and only a certain amount can be processed at once. The loop is going through each member and calling your method again and again, and Discord.js winds up putting all these requests into a queue. When it has to wait too long to add the role, the error you see is returned. And about having too many listeners attached and the possible memory leak warning, Discord.js attaches a listener for when Discord says the role is actually removed. Because your code isn't waiting for the role to be removed for each member, a lot are attached at once.
Even if you wanted to await the member.removeRole() call, it wouldn't work in a forEach() loop because of the way it's built. It doesn't wait for your function to finish, so it just keeps going and then moves on. A for...of loop would fix this issue.
The best solution in this case might actually be to clone and then delete the role. By deleting it, it's automatically removed from every member, and you don't have to make all those calls to the API or wait for all of them. To "clone" it, you can create a new role using the old role instance as the data, adding 1 to the position (assuming the old role is there).
Also, just as a side note, the catch block of a try...catch statement doesn't use a callback function. The code inside of it is read and executed just like in the try block (only if there's an error of course). And, if you're not awaiting promises, your catch block won't actually catch rejections because everything may have already moved on (the promise is pending, so it just continues).

Is it possible to detect the removal of a reaction?

I know you can detect the addition of a new reaction but using a ReactionCollector. But is it possible to detect the removal of a reaction?
I know i could keeping track of all reactions in a DB, and continuously poll the discord api and compare the DB version to the live version. But I'd rather not do this if there's a better solution out there.
Yes, the discord.js API has an event you can listen for: messageReactionRemove. You have to maintain a message cache, because it only fires for messages in your cache. You fill out your cache using fetchMessages.
You can make a event for this, called 'messageReactionRemove' to see if someone removes a reaction.
This is a simple example for a reaction role bot i have:
const events = {
MESSAGE_REACTION_REMOVE: 'messageReactionRemove',
};
Then you can make for instance an if statement, and ask for the MESSAGE_REACTION_REMOVE
if (event.t === "MESSAGE_REACTION_REMOVE") member.addRole(guildRole.id);

REST optimistic-locking and multiple PUTs

Far as I understand, PUT request is not supposed to return any content.
Consider the client wants to run this pseudo code:
x = resource.get({id: 1});
x.field1 = "some update";
resource.put(x);
x.field2 = "another update";
resource.put(x);
(Imagine I have an input control and a button "Save", this allows me to change a part of object "x" shown in an input control, then on button click PUT changes to server, then continue editing and maybe "save" another change to "x")
Following different proposals on how to implement optimistic locking in REST APIs, the above code MUST fail, because version mark (however implemented) for "x" as returned by get() will become stale after put().
Then how do you people usually make it work?
Or do you just re-GET objects after every PUT?
You can use "conditional" actions with HTTP, for example the If-Match header described here:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
In short: You deliver an ETag with the GET request, and supply this ETag back to the server in the If-Match header. The server will respond with a failure if the resource you are trying to PUT has another ETag. You can also use simple timestamps with the If-Unmodified-Since header.
Of course you will have to make your server code understand conditional requests.
For multiple steps, the PUT can indeed return the new representation, it can therefore include the new ETag or timestamp too. Even if the server does not return the new representation for a PUT, you could still use the timestamp from the response with an If-Unmodified-Since conditional PUT.
Here is probably what I was looking for: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
They implicitly say that we CAN return ETag from PUT. Though only in the case server applied the changes as they were given, without any corrections.
However this raises yet another question. In real world app PUT caller will run asynchronously in JS gui, like in my example in the question. So, Save button might be pressed several times with or without entering any changes. If we don't use optimistic locking, then supposed PUT idempotency makes it safe to send another PUT query with each button click, as long as the last one wins (but actually if there were changes then it's not guaranteed, so the question remains).
But with optimistic locking, when first PUT succeeds, it returns updatred ETag, ok? And if there is another PUT request running, still with outdated tag version, that latter request will get 412 and the user will see a message "someone else changed the resource" - but actually it was our former changes.
What do you usually do to prevent that? Disable the Save button until its request is fully completed? What if it times out? Or do you think it's acceptable to see concurrent-change error message if it was a timeout, because the stability is already compromised anyway?

Resources