Getting input from users in Bot - python

I have a question about building a telegram bot with python.
How can I get input from the user in my python-telegram-bot?
For example, a dictionary bot, how can I get a word from the user?

I recommend to have a look at the examples on GitHub.
With python-telegram-bot v12.0.0b1 you can do it like this:
def do_something(user_input):
answer = "You have wrote me " + user_input
return answer
def reply(update, context):
user_input = update.message.text
update.message.reply_text(do_something(user_input))
def main():
updater = Updater("TOKEN", use_context=True)
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.text, reply))
updater.start_polling()
updater.idle()

I recommend pyTelegramBotAPI, not python-telegram-bot.
For me it is easier.
And you should use this:
#bot.message_handler(func=lambda message: True)
def echo_message(message):
cid = message.chat.id
mid = message.message_id
message_text = message.text
user_id = message.from_user.id
user_name = message.from_user.first_name
You can save this information in JSON if you want.

Related

How to verify user's input in telegram bot?

I'm trying to get code from user and if it's correct to start sending him options.
But the third function (send_welcome) doesn't start. Could you say what I'm missing?
#bot.message_handler(commands=['start'])
def send_text_request(message):
msg = bot.send_message(message.chat.id, "Write a code")
bot.register_next_step_handler(msg, function)
def function(message):
if message.text=='6':
print('hello')
bot.register_next_step_handler(message, send_welcome)
def send_welcome(message):
markup=types.ReplyKeyboardRemove(selective=False)
markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
itembtn1 = types.KeyboardButton("option1")
itembtn2 = types.KeyboardButton("option2")
markup.add(itembtn1, itembtn2)
msg = bot.send_message(message.chat.id, "Hello "+message.from_user.first_name+", I will help you! \n Enter the product", reply_markup=markup)

Getting the userid of a user that was tagged

I am using discordpy to build a discord bot. One of the features that I want it to have, is to be able to give a random percentage about a user.
Example:
user1: !w #user2
bot: #user2 is x% y
I am unsure how to draw the userid of user2 from the message sent by user1. Does anyone have any suggestions?
You can use the id attribute of discord.Member.
Example:
#bot.command()
def w(ctx, user: discord.Member):
user_id = user.id
print(user_id)
#client.event
async def on_message(message):
if message.content.startswith('w!cool '):
if message.mentions == []:
await message.channel.send("You should mention someone!\n```\nw!cool <mention>\n```")
return
coolness_tosend=""
for i in message.mentions:
coolness_tosend=coolness_tosend+"<#" + str(i.id) + "> is " + str(random.choice(range(100))) + "\% cool.\n"
await message.channel.send(coolness_tosend)
Links:
discord.Message.mentions in API reference
discord.Message in API reference
Do note, though, that w!cool alone without arguments won't work. It prevents conflict with commands such as w!coolpic. Don't forget to do an import random!
You've asked a question in the title and the description doesn't match it ;-;
Here's a basic code according to what you've asked in the description, customize it as you like :)
Make sure to replace 'client' with whatever you've used
#client.command()
async def cool(ctx, user: discord.Member = None):
pctg = (random.randint(0, 100))
if user == None:
await ctx.send('Mention a user')
else:
await ctx.send(f"{user.name} is {pctg}% cool")
If you want the mentioned user's ID as bot's reply then use the following -
#client.command()
async def uid(ctx, user: discord.Member):
uid = user.id
await ctx.send(uid)
WCOOL_NO_MENTION_ERROR = "You should mention someone!\n" \
+ "```\n" \
+ "w!cool <mention> ...\n" \
+ "```"
#client.event
async def on_message(message):
if message.content.startswith('w!cool '):
if not message.mentions:
return await message.channel.send(WCOOL_NO_MENTION_ERROR)
# Create a string for the response
response = str()
for mention in message.mentions:
percentage = random.choice(range(0, 100+1))
response += f"<#{mention.id}> is {percentage}% cool."
response += "\n"
await message.channel.send(response)
elif message.content == "w!cool":
return await message.channel.send(WCOOL_NO_MENTION_ERROR)
Based on my older answer from my other account but it's a little bit more readable. It works pretty much the same way with some things improved (such as caring about the situation when nothing comes after w!cool)
Also if anyone is reading this, don't use discord.py! It is unmaintained, so use a fork of it, such as Pycord.

Discord.py collect emoji reactions and make a function out of them

I am trying to make a function whenever the user reacts with the check emoji or if they react with the x. So basically I have a check if the user has a phone, if the user has a phone then you can call them. The bot sends a message in dms and reacts with a check and a x, if you click the check I want a function to happen, how can I do this?
#commands.command()
#commands.cooldown(1,120,commands.BucketType.user)
async def call(self, ctx, member : discord.Member):
phone = False
users = await bank_data()
user = ctx.author
client = discord.Client
try:
bag=users[str(user.id)]["bag"]
except:
bag=[]
for item in bag:
name = item["item"]
if name == "phone":
phone = True
if phone == False:
await ctx.reply("You must buy a phone to call someone idiot.")
if phone == True:
try:
targetBag = users[str(target.id)]["bag"]
except:
targetBag=[]
targetPhone = False
if target:
for item in targetBag:
name = item["item"]
if name =="phone":
targetPhone = True
if targetPhone == False:
await ctx.reply("Attempted user to call does not have a phone.")
if targetPhone == True:
channel = await target.create_dm()
emojis=['✅', '❌']
confirmEmoji = '✅'
message=await channel.send(f"{ctx.author} is calling you. Do you want to answer?")
for emoji in emojis:
await message.add_reaction(emoji)
You can use the wait_for() for this case. Create a response variable so that you can check and use the response to answer the phone or decline it.
You can read more about it here-
https://discordpy.readthedocs.io/en/stable/api.html#discord.Client.wait_for
There are different types of events which you can pass into wait_for() in your case it's reaction_add
Hope this helped :D

Discord Bot DM Questionnaire discord py

I'm basically trying to make an application/questionnaire discord bot. When triggered, the bot is supposed to notify the user via dm and asks if user wants to proceed. User replies with "proceed" and bot starts with the first question and wait for a response from user. Bot then takes response and store it and proceeds with the next question and it loops until it finishes the last question. I'm stuck at the part where the bot sends the first question and I get no response when I answer. Any help would be appreciated.
PS. I'm fairly new to python and discord py
#bot.command()
async def apply(ctx):
Name = ''
Age = ''
user = ctx.author
name = ctx.author.display_name
q = ['What is your full real name?',
'What is your age?']
i = 0
#embed
message = 'Thank you ' + name + \
' for taking interest in Narcos City Police Department. You will be asked a series of question which you are required to answer to the fullest of your ability. Please reply with *proceed* to start your application.'
embedmsg =discord.Embed(title = 'NARCOS CITY POLICE DEPARTMENT', color = Police)
embedmsg.set_thumbnail(url = thumbnail)
embedmsg.add_field(name = 'Human Resources:', value = message)
#initial bot response
dmchannel = await ctx.author.send(embed=embedmsg)
#check
def check(m):
return m.author == ctx.author and m.channel == ctx.author.dm_channel
msg = await bot.wait_for('message', check=check)
if msg.content == 'proceed':
async def askq(q):
await ctx.author.send(q)
msg
return msg.content
Name = await askq(q[0])
Age = await askq(q[1])
Your check function is a bit messed up. You can try the following:
#bot.command
async def apply(ctx):
await ctx.author.send("Filler") # Sends a message to the author
questions = ["", "", ""] # Create your list of answers
answers = [] # Empty list as the user will input the answers
def check(m):
return ctx.author == m.author and isinstance(m.channel, discord.DMChannel) # Check that the messages were sent in DM by the right author
for i in questions:
await ctx.author.send(i) # Sends the questions one after another
try:
msg = await bot.wait_for('message', timeout=XXX, check=check)
except asyncio.TimeoutError:
await ctx.author.send("Timeout message.")
return # Will no longer proceed, user has to run the command again
else:
answers.append(msg) # Appends the answers, proceed
[OPTIONAL PART]
channel = bot.get_channel(ChannelID)
e = discord.Embed(color=ctx.author.color)
e.title = "New application"
e.description = f"First answer: {answers[0].content} [...]"
await channel.send(embed=e)
What did I do in the code?
Built in a different check to make sure the answers were sent in a DM channel by the author of the command
Put the answers into a list (answers.append(msg))
Sent the answers in an embed to a channel of your choice
!! Note that with this method the bot will directly start to ask your questions !!
If you want to first ask if the user wants to start with the questions you can build in something like:
try:
preply = await self.bot.wait_for("message", check=check, timeout=43200)
while preply.content != "proceed": # If answer is not "proceed"
await ctx.author.send("If you want to proceed please run the command again and type `proceed`")
preply = await self.bot.wait_for("message", check=check, timeout=XXX)
await ctx.author.send("We will now proceed.") # If answer is "proceed"
[Rest of the code above in the right indentation.)

how to take input from user on slack to proceed further?

Im working on chatbot where bot ask users name and then bot replies with Greeting + name. This works when I use this on terminal with input() but not able to figure out how to accept input from slack and use that input.
def start(request, channel):
response = ('\n\nHello!')
send_response(response, channel)
name = ('Please tell me your name.\n')
send_response(name, channel)
name = request
greet = "Hello" + name
send_response(greet, channel)
def send_response(response,channel):
slack_client.api_call("chat.postMessage", channel=channel, text=response, as_user=True)
def parse_slack_output(slack_rtm_output):
output_list = slack_rtm_output
if output_list and len(output_list) > 0:
for output in output_list:
if output and 'text' in output and AT_BOT in output['text']:
# return text after the # mention, whitespace removed
return output['text'].split(AT_BOT)[1].strip(), \
output['channel']
return None, None
if __name__ == "__main__":
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if slack_client.rtm_connect():
print ("connected and running!")
while True:
request, channel = parse_slack_output(slack_client.rtm_read())
if request and channel:
start(request, channel)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print("Connection failed. Invalid Slack token or bot ID?")
As per slack doc, dialog.open() method is the way to achieve your requirement.
https://api.slack.com/dialogs.
EDIT:
And RASA NLU-CORE gives more option for conversational based ChatBots. http://rasa.com/docs/core/quickstart/
Slot Filling is what you need to look into to store the name or any other values and use it further in the conversation.

Categories

Resources