I'm making a bot that has a join-leave message but I need to set it so that a user can send specify what channel they want the message to be posted in.
Example:
User: .joinleave
Bot: Please send the channel id you want the join-leave messages to be sent.
User: [Channel-ID]
Bot: Thank you! Join-leave messages will be posted in [Channel-ID]
What I have so far:
#client.event
async def on_member_join(member):
role = discord.utils.get(member.server.roles, name='Member')
await client.add_roles(member, role)
embed = discord.Embed(title="{}'s info".format(member.name), description="New Member!!!", color='Blue')
embed.add_field(name="Name", value=member.name, inline=True)
embed.add_field(name="ID", value=member.id, inline=True)
embed.add_field(name="Status", value=member.status, inline=True)
embed.add_field(name="Roles", value=member.top_role)
embed.add_field(name="Joined", value=member.joined_at)
embed.add_field(name="Created", value=member.created_at)
embed.set_thumbnail(url=member.avatar_url)
inlul = client.get_channel("")
await client.send_message(inlul, embed=embed)
I figured I would make a command that would be '.joinleave' and that's where they would enter the channel ID. I just don't know how I would save that info from multiple servers and it be different per server. Then pass it to the #client.event.
You'll want a global dictionary variable that uses the server ID as the keys and the channel ID as the values. The problem is saving it to storage. I have two solutions to this.
One File
Make a file, called server_channels.txt or something, and have a line for each server. First, it will show the server ID, then the channel ID. It would look something like this:
[server id 1] [channel id 1] # just replace each of these
[server id 2] [channel id 2]
...
You'll need to parse this file whenever the bot starts and put it into a dictionary. You also need to update the file whenever there is an update to the dictionary.
Multiple Files
Instead of reading through an entire file, make a directory called server_channels or something. It will contain a file for each server. The name of the file is the server ID, and the file will contain the channel ID.
Related
ive been texted something on my discord server before as embed. and now i just wanted to edit my old embed messages to redesign how its look by rewrite something and change colors.
how can i edit a specific embed messages by message id? i know it can edit itself by using :
first_embed = Embed(title='embed 1')
new_embed = Embed(title='embed 2')
msg = await ctx.send(embed=first_embed)
await msg.edit(embed=new_embed)
but i don't really know how to make it works. how it can edit at message ids? like checking its own id?
I am not 100% sure if I understand your question correctly, but to edit messages you could fetch them like this:
message = await ctx.fetch_message(message ID)
Or you can just use the integrated message converter in the arguments of the command.
#bot.command()
async def edit_embed(ctx, message: discord.Message):
#define the new embed here
await message.edit(embed=new_embed)
The user has to supply the message ID or message URL directly as an argument and discord.py will automatically convert it to a message object. Keep in mind that if you use the message ID, you will have to use the command in the same channel as the message you want to edit.
You have to make a new command to edit embeds and get the embed message's ID and the stuff you want to change as parameters. Then you can to Embed.copy() or Embed.to_dict() to get embed's data and then update the data you got as parameter.
An example would be:
#bot.command()
async def editembed(ctx, channel: discord.Chanel, msg_id, title, color):
msg = await channel.fetch_message(msg_id)
embed = msg.embeds[0].to_dict()
embed["title"] = title
embed["color"] = color
await msg.edit(embed = discord.Embed.from_dict())
Note: bot has no fetch message attribute so you have to either get it from channel or context (while using context you have to send the command on the same channel as the message to be edited)
I want my bot to change user roles depending on nickname patterns (basically the company ID).
When the user puts his ID in the nickname, on_member_update() is called normally.
In the function, the bot adds roles and changes the nickname again to a specific pattern. This triggers the on_member_update() yet again.
Note that I have the bot in 1 guild only.
I tried to stop it by adding
if before.display_name == after.display_name:
return
But it still enters the function when the nickname is changed. Is there a way to avoid the function triggering itself again?
The code:
#bot.event
async def on_member_update(before, after):
if before.display_name == after.display_name:
return
id = re.findall(r'\d{6,7}', after.display_name)
if not id:
return
else:
# Business logic (changing nickname, adding roles etc...)
This is not an entire answer but it will guide you in the right direction.
You have to keep record of ids of changed users either in a database or using a JSON file. I called it users_changed which should be a list.
Note: that id is reserved in Python you must use another thing maybe even id_
users_changed = [11111,22222,33333] # get this from the db or file.
#bot.event
async def on_member_update(before, after):
if before.id in users_changed:
return
# code here
# then add before.id into the users_changed
I want to find the user id of the person who DMs the bot. Is there any way to do it? I am using Discord.js
I tried by storing member author and member Id but it didn't work. But when I store channel, it store it as authors tag. But the id for that channel does not matches with the id of the user who DM the bot. I am trying to make support mail bot. But it requires the user id so that I can continue the thread by DMing the user. But it's not possible until I get the user id or server member object. And I can't store that DMchannel in my database because i use json for storing datas.
Due to my low reputation, I can't comment, sorry if this does not answer your question.
You can get the ID of the person who DM'd your bot by message.author.id (keep in mind, message will need to change to whatever variable your message is stored in).
You can also get the channel ID with message.channel.id.
The channel ID is not the same as the user's ID (they are two different things), which I assumed you misunderstood from id for that channel does not matchs with the id of the user who DM the bot.
Try this:
const client = new discord.Client();
client.login('token here');
/* On message event since you want to
* recieve DM and get ID from user who sent DM to your bot.
*/
client.on("message", (msg) => {
// checks if the message's channel type is 'DM'.
if(msg.channel.type === "dm") {
// you can do anything you want here. In my case I put console.log() function.
// since you wanted user ID, you can use msg.author.id property here.
console.log(`Recieved DM from ${msg.author.tag}, DM content is`, msg.content);
}
});
Please remember, author/member ID and dm message channel ID is completely separate thing.
Also storing member related data in JSON or an SQL is not a really good idea here. I suggest you only doing that for custom data you've generated, or that would be wasting a lot of memory.
I'm hosting my bot on glitch.com, but it restarts every night.
When my bot gets started, it reads a message from a specific channel and then writes in the others. The problem with this is that I can't use any guild or channel until the bot receives a message.
How can I avoid doing this?
You can use guild and channel IDs. Every element in Discord has a unique ID (called Snowflake) that identifies it.
If you want to get a specific guild or channel, you can save its ID and use it in the code. IDs are public, so there's no risk using them (they're not like passwords or tokens).
Guilds and channels are stored in Collections and mapped by their IDs, so you can use them like this:
let guild = client.guilds.get('guild id as a string');
let channel = guild.channels.get('channel id as a string');
To get your guild's ID (or the ID of pretty much any element in Discord) you can enable the Developer mode in the settings, then right-click on the guild and select "Copy ID".
I have statistics. I am downloading from the User Id database and I am replacing the ID with its name, but if the user has left the server, there is an error because there is no such user.
I have bot.users.get(id) but when a user leaves the server, an error pops up.
Can I get the username with the ID differently if the user is not on the server?
Sorry for being late, like literally. You can perform a request to get a user from Discord by a UserResolvable with Client#fetchUser(<UserResolvable>);.
In practice, the code should look like this;
const Discord = require("discord.js");
const Client = new Discord.Client();
Client.login("YoUr.nIcE.toKe.n");
Client.on("ready", function () { // Should do that when the client is ready.
const User = Client.fetchUser("123456789012345678");
console.log(User); // Some user object.
});
Hope I helped you nonetheless.
~Q
Since client.users stores only cached users, you won't be able to retrieve their username in a reliable way from there.
DISCLAIMER: This method is really inefficient, but discord.js hasn't been made for this kind of work. If you want to make it easier, just write Unknown user (client_id)
If you're not able to get the username from a user list you could try to use messages: use channel.fetchMessages() on every channel of your guild until you find a message in which message.author.id == your_id, when you find it you can get the username with message.author.username
There's also another solution: a self-bot. Keep in mind that this one is not supported by Discord itself, and could result in a permanent ban for the account you're using.
With that said, if you use a self-bot you can use the TextChannel.search() method to quickly find a message with your author id and then grab the username from the author.