Getting one message using the telegram python API? - python

I want to create a telegram bot that, after seeing the command /define, asks for the word.
I want to extract the word sent by the user after the bot asks for it. How do I do it?
import telegram
from telegram.ext import Updater
from telegram.ext import MessageHandler, Filters
from telegram.ext import CommandHandler
updater = Updater(token='******************')
dispatcher = updater.dispatcher
def define(bot, update):
bot.send_message(chat_id=update.message.chat_id, text="Enter word")
word = '''get content of following message'''
definition = get_definition(word)
bot.send_message(chat_id=update.message.chat_id, text=definiton)
definition_handler = CommandHandler('define', define)
dispatcher.add_handler(definition_handler)
updater.start_polling()

First of all, you require pyTelegramBotAPI library;
Then, you want to add #BotFather in Telegram and follow the instructure #6. You need to obtain the bot token which is a unique set of letters and digits for your bot, just like a codename. After you have registered a bot via #BotFather, it will give you the token.
Actually, the token is the only thing you need to create any bot you want. The codes for the bot like yours should follow the same logic structure:
# -*- coding: utf-8 -*-
import telebot # importing pyTelegramBotAPI library
import time
import sys
bot = telebot.Telebot(token='YOUR API TOKEN') # supply your future bot with the token you have received
#bot.message_handler(commands=['define', 'Define'])
def echo_msg(message):
echo = bot.send_message(chat_id=message.chat.it,
text='What word would you want me to extract, sir?')
bot.register_next_step_handler(message=echo, callback=extract_msg)
def extract_msg(message):
msg.append(message.text)
print(msg)
def main_loop():
bot.polling(none_stop=True)
while True:
time.sleep(1)
if __name__ == '__main__':
try:
main_loop()
except KeyboardInterrupt:
print(sys.stderr '\nExiting by user request'\n')
sys.exit(0)
Okay, each bot requires a message_handler to process the incoming information.
In your case, it is a command that triggers the bot to ask for a word to extract into a list. If you do not define bot.register_next_step_handler(), this command will not do any action at all (except the fact it asks for a word).
The function extract_msg() appends the next word written by a user and prints out the msg list into your console.
The function main_loop() runs the bot until suspension and provokes it to idle for a second after each word extraction. To stop the bot, press Ctrl + C.
I hope that suffices. The next step would be to track the person who types /define or /Define and extract his/her word request. Also, it would be better to make msg list more descriptive, or implement absolutely different extraction method. This one is simply informative and hardly applicable in practice.

I fixed an error in when calling stderr:
# -*- coding: utf-8 -*-
import telebot # importing pyTelegramBotAPI library
import time
import sys
bot = telebot.Telebot(token='YOUR API TOKEN') # supply your future bot with the token you have received
#bot.message_handler(commands=['define', 'Define'])
def echo_msg(message):
echo = bot.send_message(chat_id=message.chat.it,
text='What word would you want me to extract, sir?')
bot.register_next_step_handler(message=echo, callback=extract_msg)
def extract_msg(message):
msg.append(message.text)
print(msg)
def main_loop():
bot.polling(none_stop=True)
while True:
time.sleep(1)
if __name__ == '__main__': try:
main_loop() except KeyboardInterrupt:
print(sys.stderr('\nExiting by user request'\n'))
sys.exit(0)

Related

Message from a telegram bot without a command(python)

I want to send a Message(call a function) every day at a given Time. Sadly this is not possible with message.reply_text('Test'). Is there any way i can do this? I could not find anything.
This is my current code:
import telegram.ext
from telegram.ext import CommandHandler, MessageHandler, Filters
import schedule
import time
API_KEY = 'XXXXXXXXXXX'
updater = telegram.ext.Updater(API_KEY)
dispatcher = updater.dispatcher
def start(update, context):
update.message.reply_text('Welcome!')
# problem:
def Test(update, context):
update.message.reply_text('Works!!!')
# running special functions every Day at a given Time
schedule.every().day.at("10:00").do(Test)
while True:
schedule.run_pending()
time.sleep(1)
def main():
# add handlers for start and help commands
dispatcher.add_handler(CommandHandler("start", start))
# start your bot
updater.start_polling()
# run the bot until Ctrl-C
updater.idle()
The schedule part works, I just don`t know how to send this Message.
Thanks for your help!
Update object, inside of the message field, has the from field which is a User Telegram object containing the user's ID.
Once you have the user's ID, you can use the sendMessage method in order to reply him easily.
To conclude, instead of:
update.message.reply_text('Welcome!')
You could do like so:
user_id = update.message.from.id
updater.sendmessage(chat_id=user_id, text="Welcome!")

Can't send audio file with telegram bot

I've got stuck trying to get my bot to send audio file and tried reading everything I can and for some reason still not working...
this is my code, its quite long so i've just included relevant parts:
import Constants as keys
from telegram.ext import *
from telegram import ReplyKeyboardMarkup,InlineKeyboardButton, InlineKeyboardMarkup, CallbackQuery, Update
import time
import Responses as R
import song
import logging
import emoji
import random
import requests
def yes_command(update, context):
time.sleep(5)
update.message.reply_text("Let's test here, press play to listen.")
time.sleep(3)
update.message.reply_audio("press play", audio=open("C:/Users/0836/Documents/omsk/bot2/song/bootgong.mp3"))
def main():
updater = Updater(keys.API_KEY, use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler("start", start_command))
dp.add_handler(CommandHandler("play", play_command))
dp.add_handler(CommandHandler("no", no_command))
dp.add_handler(CommandHandler("yes", yes_command))
dp.add_handler(MessageHandler(Filters.text, handle_message))
dp.add_handler(MessageHandler(Filters.photo, photo_command))
updater.start_polling()
updater.idle()
main()
I'm really new to bots and python so not sure what i'm doing wrong, please help! I've seen stuff about uploading it to a telegram server but not sure how?
try to add 'rb' in open
update.message.reply_audio(open("C:/Users/0836/Documents/omsk/bot2/song/bootgong.mp3", "rb"), title="press play")

How can I handle audio messages in pyTelegramBotAPI?

I'm using pyTelegramBotAPI as framework to create a telegram bot.
I'm having some troubles with handle audio messages and I can't understand where I am wrong.
Here my code:
# If user send an audio and it's a private chat
#bot.message_handler(content_types=["audio"])
def react_to_audio(message):
if message.chat.type == "private":
bot.reply_to(message, """What a nice sound! I'm not here to listen to some audio, tho. My work is to wish a good night to all members of a group chat""")
Can anyone help me?
i don't specifically know well how to use pyTelegramBotAPI because also i got problems i couldn't solve so i abandoned it for python-telegram-bot which is better documented in comparison to pyTelegramBotAPI, has a bigger community, is more actively developed and also have an active Telegram group where you can directly ask for help from other developers using this wrapper.
So if you are interested to change to python-telegram-bot, the code for your bot would look something like this:
from telegram import Update
from telegram.ext import Updater, MessageHandler, Filters
token = "" #Insert your token here
def message_handler(update, context):
update.message.reply_text("Hello")
def audio_handler(update, context):
if update.message.chat.type == "private": #Checks if the chat is private
update.message.reply_text("What a nice sound! I'm not here to listen to some audio, tho. My work is to wish a good night to all members of a group chat")
def main():
"""Start the bot."""
updater = Updater(token, use_context=True)
# Get the dispatcher to register handlers
dispatcher = updater.dispatcher
# on noncommand i.e message
# Use this if you want to handle also other messages
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, message_handler))
dispatcher.add_handler(MessageHandler(Filters.audio & ~Filters.command, audio_handler))
# Start the Bot
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()
Here are also some official examples of bots made with this wrapper and the that you can use to better understand the wrapper, if you want more info regard this feel free to DM me on telegram #Husnainn.

What's a good way to parse an input into a command, parameters, and values for those parameters?

I'm trying to make a Discord bot using the discord.py module (in Python) that is able to parse out commands. The trouble I'm having is that I want each command to be able to have parameters, denoted by a "-".
For example if someone sent "sm!poll -m='Test' -s" the bot should return "{user} asked: Test". If someone sent "sm!poll -m='Test-2'" the bot should reply with "#everyone {user} asked: Test-2"
Therein lies the problem. I'm using - to denote a parameter, but I also want to be able to use it inside of the poll that the bot sends. Here's the code I have so far:
async def on_message(message):
if message.content.startswith('sm!'):
cmd=(message.content+'! ').split('!')[1]#finds everything after sm!
param=(cmd+"- ").split('-')[1:]# separates out all of the parameters
paramDict={}# makes a dictionary to hold the parameters
for i in param:
temp=i.split('=')# tries to split each parameter into a parameter and a value
try:
temp[1]
except IndexError:# if there is no value, sets the value to true
temp.append(True)
paramDict[temp[0]]=temp[1]
The end goal is to have a variable called "cmd" that I can use startswith on, and a dictionary full of all of the parameters in the message.
Basically, if - is between quotes, ignore it, but if it outside of quotes, treat it as a parameter.
Thanks for your help!
Thanks for your help #KarlKnechtel!
I used shlex.split to separate the message by spaces, keeping anything inside of quotes intact.
import shlex
async def on_message(message):
if message.content.startswith('sm!'):
cmd=message.content.split('!',1)[1]
sep=shlex.split(cmd)
params={}
params['cmd']=sep[0]
for i in sep[1:]:
try:
params[i.split('=',1)[0]]=i.split('=',1)[1]
except IndexError:
params[i.split('=',1)[0]]=True
Using the on_message() function to manage your commands is not the right way to do.
I recommend you to use the Commands extension.
This is how you're supposed to import it :
from discord.ext import commands
Commands in __main__
If you want your commands to be in your __main__ file, this is how you would create a command :
# In __main__.py
#bot.command()
async def hello(context, my_arg):
await context.send(f"Hello {my_arg}")
Usage :
.hello world
Output :
Hello world
Commands out of __main__
Or, if you want your command to be stored in an external file and to manage it as an object, you can use the discord.py extension system.
Your command will be written inside an object called Cog.
This is how you do it :
# Inside my_cog.py
from discord.ext import commands
class MyCommand(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def my_command(self, context):
"""
DO SOMETHING
"""
# OUT OF THE CLASS
def setup(bot):
bot.add_cog(MyCommand(bot))
Now you have to tell your bot where he can find the command you just wrote :
# In __main__.py
import discord
import asyncio
import os
from discord.ext import commands
class Main:
def __init__(self):
# Private
self.__TOKEN = os.environ["YOUR_TOKEN"] # Safety first, use os.environ !
self.__prefix = ['.'] # You can store multiple prefixes
self.__extensions = ["extensions.my_command"] # Path to my_command.py file
def run(self):
bot = commands.Bot(command_prefix=self.__prefix)
"""
YOUR STUFF
"""
# Load your extensions
for extension in self.__extensions
await asyncio.sleep(0)
bot.load_extension(extension)
client.run(self.__TOKEN)
if __name__ == "__main__":
Main().run()
This is how you manage commands using discord.py.
I highly recommend you to read the doc' ;)
Hope it helped ! Have fun working with discord.py !

The telegram bot does not work for Persian messages

I create a telegram bot whit python-telegram-bot.I want to post the message to the group after sending messages to the group,and the bot check the message, and if the word in the mlist is in messages, the bot will delete the message, but if the messages are in Persian, the bot will not delete it, but if the message In Latin, the bot will delete it.Look at the messages in the mlist, when the bot sends Hello to the group, it delete it, but when the سلام sends to the group it does not delete the bot.
# -*- coding: cp1256 -*-
#!/usr/bin/python
import os, sys
from telegram.ext import Filters
from telegram.ext import Updater, MessageHandler
import re
def delete_method(bot, update):
if not update.message.text:
print("it does not contain text")
return
mlist=['Hello', 'سلام']
for i in mlist:
if re.search(i, update.message.text):
bot.delete_message(chat_id=update.message.chat_id,message_id=update.message.message_id)
def main():
updater = Updater(token='TOKEN')
dispatcher = updater.dispatcher
dispatcher.add_handler(MessageHandler(Filters.all, delete_method))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
# for exit
# updater.idle()
The bot should delete messages while sending the Persian messages in the mlist to the group, but it will not do this, but if the messages in the mlist are in Latin and will be sent to the group, messages will be deleted. . There is no error at all
First you need to debug your program to see if it reaches inside the if clause or not.
and also change the first line to:
# -*- coding: utf-8 -*-
see if it works..

Categories

Resources