How to retrieve a message link if it contains a specific string? - discord.py

I tried doing something like this
ctx = message
"https://discordapp.com/channels/"+ctx.guild.id+"/"+ctx.channel.id+"/"+ctx.id
"https://discordapp.com/channels/"+guild.id+"/"+ctx.channel.id+"/"+ctx.id
Neither worked
If you're confused, Lets say if the message contains "hi" I want it to copy the message link and post it, so if someone clicks on the link it redirects them to that message
Thank you for reading.

#client.command()
async def keyword(ctx, *, word: str): # Usage: !keyword hi
messages = await ctx.channel.history(limit=200).flatten() # Get last 200 messages
for msg in messages: # Iterate through all messages.
if word in msg.content:
await ctx.send(msg.jump_url) # Send the jump link to the message containing the word.

discord.Message.jump_url
Reference:https://discordpy.readthedocs.io/en/latest/api.html?highlight=jump_url#discord.Message.jump_url

Related

How to rig a bot's command to only a certain user

I've been making this pp size machine, which is somewhat like dank memer's one
#client.command()
async def pp(ctx,member : discord.Member):
size=random.randint(1,10)
message = "8"
for x in range (size):
message= message + "="
if x == size-1:
message = message + "D"
if member == "PROTATO#6826":
message = "8D"
ppsize = discord.Embed(color=discord.Colour.orange(), title=f"PP size",description=f"""{member}'s penis
{message} """)
await ctx.send(embed = ppsize)
But i want to rig the command for a certain user to only show "8D" instead of the random lengths.
But no matter what it is the
if member == "PROTATO#6826":
message = "8D"
code doesnt run or gets over looked?
Can someone help me out with this?
You can check if the member mentioned has the same id as a specific user. You can either enable developer mode on discord, or you can print the member.id at the very beginning. Do view a code example below.
#client.command()
async def pp(ctx, member: discord.Member):
print(member.id) # this would print a user's unique id
message = "Hey!"
if member.id == 394506589350002688: # replace this id with what was printed at the start
message = "Hello!"
await ctx.send(message)
Similar Questions:
How to check if message was sent by certain user? - SO
How do I detect if the message is sent by a specific user id? - SO

Discord.py file logging, change number of messages

I've got this code that I use for discord channel logging. It basically gets the last 10,000 messages in a channel, and makes a .txt file with those messages in it, with the !log command. However, how would I make it so optionally users can type a number after !log, and it will log that number of previous messages? EG: "!log" on it's own logs the last 10,000 messages, but "!log 100" would log the last 100 messages. But I have no clue how to do that.
Here's my code:
#commands.has_any_role('Logger', 'logger')
#bot.command()
async def log(ctx):
try:
channel = ctx.message.channel
await ctx.message.delete()
await channel.send(ctx.message.author.mention+" Creating a log now. This may take up to 5 minutes, please be patient.")
messages = await ctx.channel.history(limit=10000).flatten()
numbers = "\n".join([f"{message.author}: {message.clean_content}" for message in messages])
f = BytesIO(bytes(numbers, encoding="utf-8"))
file = discord.File(fp=f, filename='Log.txt')
await channel.send(ctx.message.author.mention+" Message logging has completed.")
await channel.send(file=file)
except:
embed = discord.Embed(title="Error creating normal log:", description="The bot doesn't have necessary permissions to make this log type. Please confirm the bot has these permissions for this channel: View Channel, Read and Send Messages, Attatch Files (used for sending the log file), Manage Messages (used for deleting the command the user sends when making a log).", color=0xf44336)
await channel.send(embed=embed)
Any help about how to make it so they can optionally provide a number, which would then log that amount, would help a lot. Thanks!
Take the number of messages to be logged as a parameter
...
#bot.command()
async def log(ctx, limit: int=1000):
...
then use the value of the parameter
...
messages = await ctx.channel.history(limit=limit).flatten()
...
docs: https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#parameters

Discord.py logging messages

I've got this code, which when I type !snapshot should log the last 100 messages in the channel, and make them into a text file:
snapshot_channel = (my snapshot channel ID)
#commands.has_permissions(administrator=True)
#bot.command()
async def snapshot(ctx):
channel = bot.get_channel(snapshot_channel)
await ctx.message.delete()
messages = message in ctx.history(limit=100)
numbers = "\n".join(
f"{message.author}: {message.clean_content}" for message in messages
)
f = BytesIO(bytes(numbers, encoding="utf-8"))
file = discord.File(fp=f, filename="snapshot.txt")
await channel.send("Snapshot requested has completed.")
await channel.send(file=file)
I've got BytesIO imported, and it works fine for a different command which purges messages and logs them, but this code which should just make a log and then send it in the channel doesn't work. Please can you send me what it should look like for it to work. Thanks!
TextChannel.history is an async generator, you're not using it properly
messages = await ctx.channel.history(limit=100).flatten()
numbers = "\n".join([f"{message.author}: {message.clean_content}" for message in messages])
Another option would be
numbers = ""
async for message in ctx.channel.history(limit=100):
numbers += f"{message.author}: {message.clean_content}"

Discord.py embed is only showing one word

So I'm trying to make a !say (message goes here) command for my discord bot. Here's the code I've got so far:
async def say(ctx, message):
embed=discord.Embed(title="New Say Message", description=(message), color=0xff0000)
await ctx.send(embed=embed)
If I do "!say Hello", it works fine. However, if I do "!say How are you", it just shows the word "How" in the embed. Here's what I mean: https://gyazo.com/b146fff6c1d7c99a47db9c218dd753f1.
What do I need to do/change to make it show the full message. Thanks!
Your function signature is set up incorrectly. You only accept one argument from the bot with async def say(ctx, message); in order to consume a variable-length of arguments in python, you need *. Then you would consume that variable length as a list.
Example:
async def say(ctx, *message):
embed=discord.Embed(title="New Say Message", description=(" ".join(message)), color=0xff0000)
await ctx.send(embed=embed)

How to make a Discord Bot reply to a specific message rather than every message including a word

I have a bot that I want to reply to a specific word, and it does. However, if you type any message including that word, it will also reply. How do I stop that?
For example. If I was to say "Who", the bot would reply with "go away lucas"
However, if I was to say "Who is this person?" the bot would still reply with "go away lucas"
Is there any fix to this? Thanks!
async def on_message(message):
if message.content.startswith('who'):
msg = 'who'.format(message)
await message.channel.send('go away lucas')
await bot.process_commands(message)
I see you are using startswith().
the command startswith() returns True if the message starts with the desired string for example:
a = "who"
b = "who is lucas"
print(a.startswith("who"))
print(b.startswith("who"))
The output will be:
True
True
If you want the command to work only when the content of the message is "who", try this:
async def on_message(message):
if message.content == "who":
msg = 'who'.format(message)
await message.channel.send('go away lucas')
await bot.process_commands(message)

Resources