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.
Related
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.
I'm making a bot that replies to a user with the same message but with some words replaced by others.
Input example:
Hi, this is a keyboard example.
Excepted output:
Hi, testing is a mouse example. (the word this and keyboard have been replaced.)
My output:
Hi, testing is a mouse example.
I've tried solving this problem changing the offset and length values of event.message.entities but i couldn't.
I also tried using event.get_entities_text() but couldn't.
So, what's the simplest/best solution for this problem?
In Telethon v1, you can do this:
text = message.text
replaced = text.replace('this', 'testing')
message.text = replaced
This is because message.text contains the formatting entities as whatever the client.parse_mode says (by default, "markdown" as used by Telegram Desktop), so text would be __Hi__, **this** is a..., and replacing 'this' will keep the formatting intact.
When setting the message.text, the library automatically separates it again into raw text plus the entities.
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
)
My bot is not working as planned.
For the context of the bot, I followed a YouTuber's tutorial almost exactly (other than the algorithm for the experience) - https://www.youtube.com/watch?v=pKkrCHnun0M&t=890s
async def update_user(users, user):
if not user.id in users:
print('added new user')
users[user.id] = {}
users[user.id]['experience'] = 0
users[user.id]['level'] = 1
async def add_xp(users, user, exp):
print('added exp')
users[user.id]['experience'] += exp
I added the print function so I could track which functions have been triggered.
The first time, it worked. User data popped up in my users.json file when i typed in the channel. However, upon the second time typing anything, this happens:
It showed the same data being input twice! I was so confused because everything is the same. I will post the full code of the bot in here. Please help me make the bot possible to use.
https://pastebin.com/BkzSbVan (I removed the server ID and channel ID, so please focus on the functions)
The JSON standard requires keys to be strings, so when you use json.dump, it converts the integer IDs into strings. However, when you load that back with json.load, it stays a string, so the user dictionary will have string keys when you load it from the file. Then, when you check if the user ID is in the dictionary, it's by integer, so it's not, and it adds the integer ID as a key for the dictionary with a new initial value. At this point, you have an integer and string version of the same ID in your dictionary. When you write this back to the file with json.dump, it again converts the integer ID to a string, resulting in what you see in your screenshot.
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