Context: I am starting to learn how to code a telegram bot in python. I have successfully made a fun bot for my group with friends to use. However, i only want it to respond when specific words are mentioned apart from the commands that trigger it.
Example: Whenever a user says the word "wen" plus any other word(s), i want the bot to reply with: SOON!
I want the bot to only pick up some trigger words and reply and for the remainder of the chat to stay idle
Part of my code:
user_message = str(input_text).lower()
wenResponse = str("wen ").join(input_text)
if user_message + wenResponse:
return ("SOON!")
def handle_message(update,context):
text=str(update.message.text).lower()
response=sample_responses(text)
update.message.reply_text(response)
Actual result:
The bot is working but only when the user says specifically "wen". If the user adds more words after "wen" the bot doesnt pick it up.
You can just use .startswith('text') to check is a string starts with 'text'.
The .startswith('text') return True if the string starts with text, or else it will retur False.
if "wen" in str(input_text).lower():
return "soon"
This should work even if the key word isn’t the first word.
Related
I'm creating a bot that will all a certain group of users use it for sharing images to the bot.
The bot will recieve the image and forward this to a group.
I have the bot succesfully forwarding the message with the image to the group after the user confirms but I want to append the #username or userID of the person that interacted with the bot in the forwarded message.
Possibly adding a caption with the #username or #user_id of the person who submitted the post to the bot.
FILE 1
from pyrogram import (
Client,
filters
)
#Client.on_callback_query()
async def cb(client, call):
k = call.data
msgid = int(k.split("-")[1])
chat = call.message.chat.id
await call.message._client.copy_message(-100XXXXXXGROUPID, chat, msgid,
caption="")
FILE 2
Client,
filters
)
#Client.on_message(filters.private & ~filters.caption &
~filters.command("start"))
async def copy(client, message):
chat = message.chat.id
await message.copy(-100groupc)
I've tried adding the following to the caption:
client.get_chat_members(chat)
caption=chatmember.User
I don't get any error but don't get any captions.
I am a bit lost on this looking through pyrograms docs, I don't find any good examples of how to implement something like this. I read up that the bot has to "Meet" the user first but if the user is interacting with it in the bot chat wouldn't this work?
I don't know if I already understood what are you trying to do or not but hope I got it right and here is my suggestion about the situation.
Note: You can not edit a message that is forwarded and in general, you can not edit a message that you are not sender of it.
Main Answer
I just took a look at the title you wrote and saw copy_message() function.
Actually if you take a look at the copy_message() documentation you can easily send a caption with the media you are sending.
As the documentation says:
caption (string, optional) – New caption for media, 0-1024 characters after entities parsing. If not specified, the original caption is kept. Pass “” (empty string) to remove the caption.
So just write:
Client.copy_message(chat_id, from_chat_id, message_id, caption=username)
And boom, you are sending a caption with the media you've been trying to send.
Another Solution
First of all, you have to download the picture and after that you have to upload it to wherever you need.
This makes you to be the sender of the picture and after that you can edit it and add id or username of the guy to the caption. (or you can write the cation when you are uploading the picture)
But by the way if you are sure about the fact that if you forward a message from another guy to some channel you can edit that message, give it a try and comment the result down here for us but logically this should not work.
By the way, you can edit caption of an image with edit_message_caption() function and you can send a photo with send_photo() function.
Also try to take a look at the Available Methods Documentation and see which one of the function suits you
If I understood correctly, you want users to send an image to your bot, which will then be sent to a channel with a link to the original users account?
Use the bound method message.copy() with message.from_user.mention as the caption.
#app.on_message(
filters.photo # filter for images only
& filters.user(approved_users) # only users in this list are allowed
)
def copy_to_channel(_, message):
message.copy( # copy() so there's no "forwarded from" header
chat_id=target_chat, # the channel you want to post to
caption=message.from_user.mention # mentions the posting user in the new message
)
I have a weird problem and can't find a solution for it. I want to get the best user from my JSON leaderboard and it's working. But now I want to check if the message.author and the user from the leaderboard have the same User-ID. If yes, then an action should run.
My code:
with open("level.json", "r") as a:
level = json.load(a)
high_score_list = sorted(level, key=lambda x: level[x].get('secXP'), reverse=True)
print(f"User2: {high_score_list[0]} + msg author: {message.author.id} - {message.author.name}")
# thats not working
if message.author.id == high_score_list[0]:
embed.set_author(name=f'best leaderboard user!)
embed.color = 0x686de0
Even if the User-IDs are the exact same from the if check, the bot doesn't do it. I tried "print" Lines at the if check, but even this is not running.
I'd assume your issue is with datatypes. Check your json whether the highscorelist has text or number entries. The author's id is always of type int so if your highscore is a string they won't ever be equal.
I am making a Telegram trading bot that will create an order after receiving a string from the user. How can I make the bot receive that string?
You can use the text handler. It passes a dictionary to the function. The dictionary contains a lot of useful information such as the message text, user's name, and id, etc.
#bot.message_handler(content_types=["text"])
def handle_text(message):
print(message)
your_str = message.text
You may also consider the documentation and the examples in particular.
I'm trying to make a profanity filter for my bot. I allowed server admins to make their own list of bad words which my bot uses for their server. In the on_message function I used this code to check if a user's message contains a word from the filter:
file = open(f"configs/antiswearvalues/customantiswear/{message.guild.id}.txt")
res = [ele for ele in file.read() if (ele in message.content)]
if bool(res):
await message.channel.send("you did a bad. time for the boot.")
The problem is the bot still said you did a bad. time for the boot. even if the message contained a snippet from the elements and not an entire element.
So if the list was ['omg', 'crap', 'hell'], the bot would still warn the user if their message contained h or cr because hell and crap contain those.
My question is: How can I make my bot properly check if a user's message contains an element from a list?
You should consider using json. Getting a word blacklist will be way easier than parsing a txt file without using any library:
Your json file (eg. blacklist.json):
['omg', 'crap', 'hell']
Your python code:
from json import loads
#client.event
async def on_message(message):
with open("blacklist.json", "r"):
data = loads(file.read())
for word in data:
if word in message.content:
await message.channel.send("you did a bad. time for the boot.")
return
Your code isn't working as intended because you didn't parsed your file data, you were exploring a string, not a list.
I am adding profile cards onto my Discord bot, but I've come across one issue. When someone types !profile #user I am not sure how to properly parse for #user so the bot knows which profile card to lookup.
I first parse message.content and then remove the 9 first chars of the message content (which is always !profile) but the rest of the message content returns the user_id which looks <#289583108183948460> instead of the user's discrim. I have tried using re.sub to remove the special characters (#, >, and <) like this:
a = str(message.content[9:])
removeSpecialChars = re.sub("[!##$%^&*()[]{};:,./<>?\|`~-=_+]", " ", a)
print(removeSpecialChars)
But the weird characters are still there when I only want the number so I can search it in the database easily. I'm sure there's a way better way to do this though but I can't figure it out.
discord.py's message objects include a Message.mentions attribute so you can iterate over a list of Member. Here are the doc listings for async and rewrite.
With this you can simply iterate over the mentions as so:
for member in ctx.message.mentions:
# do stuff with member
what you actually want
discord.py allows you to grab discord.Member objects from messages with type hinting. simply add the following to the command
#bot.command()
async def profile(ctx, member: discord.Member=None):
member = member or ctx.message.author