Python Telegram Bot Conversation Method Not Working - python

I am writing a Telegram Bot for an Income/Expense project.
I have this code using python-telegram-bot:
#!/usr/bin/python
# -*- Coding : UTF-8 -*-
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler
from settings.conf import conf
conf = conf()
updater = Updater(str(conf.token()))
SETUP ,USERNAME = range(2)
def start_method(bot, update):
""" Start Command """
startList = [["Register New Account","Integrate An Account"]]
chat_id = update.message.chat_id
replyText = update.message.text
text = """Hello And Welcome To [Bestoon](http://bestoon.ir).
This Bot Helps You Easily Access Your [Bestoon](http://bestoon.ir) Account.
Now, How Can I Help You?
"""
bot.sendChatAction(chat_id, "TYPING")
update.message.reply_text(text, parse_mode="Markdown",reply_markup=ReplyKeyboardMarkup(startList, one_time_keyboard=True))
return SETUP
def setup(bot, update):
"""Initialize The User Account For The First Time"""
chat_id = update.message.chat_id
if update.message.text == "Register New Account":
bot.sendChatAction(chat_id, "TYPING")
register_text = """Ok.
Now Send Me Your Bestoon Username.
"""
update.message.reply_text(register_text,reply_markup=ReplyKeyboardRemove())
print "Going For Username"
return USERNAME
elif update.message.text == "Integrate An Account":
bot.sendChatAction(chat_id, "TYPING")
update.message.reply_text("Sorry, Can\'t Integrate Now!", reply_markup=ReplyKeyboardRemove())
bot.sendMessage(update.message.chat_id, "Bye!")
return ConversationHandler.END
else:
bot.sendChatAction(chat_id, "TYPING")
update.message.reply_text("Invalid Command!")
def regUser(bot, Update):
chat_id = update.message.chat_id
bot.sendChatAction("chat_id", "TYPING")
update.message.reply_text("Registering Your Username")
return ConversationHandler.END
def cancel(bot, update):
bot.sendMessage(update.message.chat_id, "Bye!")
return ConversationHandler.END
conv_handler = ConversationHandler(
entry_points = [CommandHandler('start', start_method)],
states = {
SETUP: [MessageHandler(Filters.text, setup)],
USERNAME: [MessageHandler(Filters.text, regUser)]
},
fallbacks = [CommandHandler('cancel', cancel)]
)
updater.dispatcher.add_handler(conv_handler)
########## Starting Bot ##########
updater.start_polling()
updater.idle()
When I use /start it works until the Bot says:
Ok
Now Send Me Your Username
And after that it need to return Registering Your Username but it doesn't.
but I have access to /cancel command.
I need to know why this script doesn't call regUser function?

Ok I've found 2 errors wich fixed my problem.
in regUser:
first I used chat_id between double quotes,
and second I used Updater with capital U instead of updater.

Related

Store info in an excel file from telegram bot

I want to program a telegram bot that collects information from people who want to join a project and stores this information in an excel file
from typing import NoReturn
from time import sleep
from email import *
from tkinter import*
from turtle import *
from telegram import*
import telegram
from telegram.ext import*
from xlsxwriter.workbook import Workbook
import pandas as pd
import openpyxl as xl
from telegram.error import NetworkError, Unauthorized
print('bot started....')
wb=''
full_name=''
birth_date=''
phone=''
ONE=""
TWO=""
THREE=''
x=0
FIRST=''
SECOND=''
users = {
# user_id:{'key':'value'}
}
UPDATE_ID = None
def echo (bot: telegram.Bot) -> None:
"""Echo the message the user sent."""
global UPDATE_ID
for update in bot.get_updates(offset=UPDATE_ID, timeout=10):
UPDATE_ID = update.update_id + 1
def start(update: Update, context: CallbackContext) :
global UPDATE_ID
if not UPDATE_ID in users:
users[UPDATE_ID] = {}
keyboard = [[InlineKeyboardButton(text="I want to join", callback_data='one')]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(text="Welcome", reply_markup=reply_markup)
def Aplly(update, context):
global full_name, birth_date, phone
full_name=''
birth_date=''
phone=''
x=0
query = update.callback_query
query.answer()
query.message.reply_text(text='Full name')
def handlmsg(update, context):
global x, full_name, birth_date, phone, chat_idd,university,College,year,email,address,Study_major,reasons
if x==0:
full_name={'full_name':update.message.text}
update.message.reply_text(text="birth day")
if x ==1:
birth_date={'birth_date':update.message.text}
update.message.reply_text(text="Phone")
if x ==2:
phone=update.message.text
update.message.reply_text(text="completed...")
print(full_name)
print(birth_date)
print(phone)
keyboard = [[InlineKeyboardButton(text="Confirm", callback_data='two')],
[InlineKeyboardButton(text="to retreat", callback_data='three')]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(text="Confirm", reply_markup=reply_markup)
return SECOND
def save(update,context):
global UPDATE_ID,wb
query = update.callback_query
query.answer()
query.edit_message_text(text="Done")
header =['full name', 'birth date', 'phone','chadt_id']
data = [full_name,birth_date, phone, UPDATE_ID]
wb = xl.load_workbook('sample.xlsx')
page = wb.active
page.title = 'companies'
page.append(header)
companies = [data]
for info in companies:
page.append(info)
wb.save('sample12.xlsx')
wb = xl.load_workbook('sample12.xlsx')
page = wb.active
sheet = wb['companies']
for i in range(1,sheet.max_row+1):
cell1=sheet.cell(row=i, column=10).value
x=int(UPDATE_ID)
if x==cell1:
page.delete_rows(i)
wb.save('sample112.xlsx')
doc_file = open('sample112.xlsx', 'rb')
return context.bot.send_document(844534481, doc_file)
def main() -> NoReturn:
"""Run the bot."""
updater = Updater('Tokn', use_context=True)
global UPDATE_ID
bot = telegram.Bot('tokn')
try:
UPDATE_ID = bot.get_updates()[0].update_id
except IndexError:
UPDATE_ID = None
while True:
try:
echo(bot)
except NetworkError:
sleep(1)
except Unauthorized:
UPDATE_ID += 1
updater = Updater('Tokn', use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(MessageHandler(Filters.text, handlmsg))
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
FIRST: [updater.dispatcher.add_handler(CallbackQueryHandler(Aplly, pattern='one'))],
SECOND: [updater.dispatcher.add_handler(CallbackQueryHandler(save, pattern='two')),
updater.dispatcher.add_handler(CallbackQueryHandler(Aplly, pattern='three'))]},
fallbacks=[CommandHandler('start', start)],)
updater.start_polling()
updater.idle()
main()
The problem occurs when two people want to use the bot at the same time, it treats them as one person
It stores their data in the same field
I think i need to use a dictionary but I didn't know how to relate it to the if and the counter

How to tag and reply to welcome a member in a welcome bot Telegram?

I have this welcome bot for telegram from github. I would like that every time a new user joins the group in addition to sending him the message it was mentioned and reply to "id has join in group" as the classic group help does.
I attach below the code to work on:
#run_async
def send_async(context, *args, **kwargs):
context.bot.send_message(*args, **kwargs)
def check(update, context, override_lock=None):
"""
Perform some checks on the update. If checks were successful, returns True,
else sends an error message to the chat and returns False.
"""
chat_id = update.message.chat_id
chat_str = str(chat_id)
if chat_id > 0:
send_async(
context, chat_id=chat_id, text="Please add me to a group first!",
)
return False
locked = override_lock if override_lock is not None else db.get(chat_str + "_lck")
if locked and db.get(chat_str + "_adm") != update.message.from_user.id:
if not db.get(chat_str + "_quiet"):
send_async(
context,
chat_id=chat_id,
text="Sorry, only the person who invited me can do that.",
)
return False
return True
# Welcome a user to the chat
def welcome(update, context, new_member):
""" Welcomes a user to the chat """
message = update.message
chat_id = message.chat.id
logger.info(
"%s joined to chat %d (%s)",
escape(new_member.first_name),
chat_id,
escape(message.chat.title),
)
# Pull the custom message for this chat from the database
text = db.get(str(chat_id))
# Use default message if there's no custom one set
if text is None:
text = "Hello $username! Welcome to $title 😊"
# Replace placeholders and send message
text = text.replace("$username", new_member.first_name)
text = text.replace("$title", message.chat.title)
send_async(context, chat_id=chat_id, text=text, parse_mode=ParseMode.HTML)
this is the result I would like to achieve.
would anyone know how to help me in this simple task? Thank you!
it's complicated code... keep it simple.
you have an event in group "new chat members". so handle this event and send reply with first_name and link to the account.
Pyrogram example:
from pyrogram import Client
from pyrogram import filters
ACCOUNT = '77777777777'
config = 'config.ini'
__client = Client(session_name=ACCOUNT, config_file=config)
def user_link(user):
USER_LINK = '{first_name} : #{username}'
USERID_LINK = '{first_name} : {id}'
return USER_LINK.format(**user.__dict__) if user.username else USERID_LINK.format(**user.__dict__)
#__client.on_message(filters.new_chat_members)
def welcome(client, message):
users = ", ".join([user_link(message.from_user.__dict__) for m in message.new_chat_members])
message.reply(f"Hello, {users}")

Retrieving data from 2 python scripts

This is the first script which get's data from a website:
import requests
def get_prices():
name = "SeedifyFund"
crypto_data = requests.get("https://api.pancakeswap.info/api/tokens").json()["data"]
data = None
for i in crypto_data:
current = crypto_data[i]
if current['name'] == name:
data = {
"PriceUSD": current["price"],
"PriceBNB": current["price_BNB"],
}
return data
if __name__ == "__main__":
print(get_prices())
The code above outputs the following: {'PriceUSD': '1.022239219137518991087869433174527', 'PriceBNB': '0.002452203037583603303073246037795846'}
I'm having issue an issue with the second script. I want it to use the data that it has collected above and print it in a telegram bot when the user types /price. The code for the second script:
import telegram
from telegram.ext import Updater
from telegram.ext import CommandHandler
from tracker import get_prices
telegram_bot_token = "API TOKEN"
updater = Updater(token=telegram_bot_token, use_context=True)
dispatcher = updater.dispatcher
def price(update, context):
chat_id = update.effective_chat.id
message = ""
crypto_data = get_prices()
for i in crypto_data:
bnbprice = crypto_data[i]["pricebnb"]
usdprice = crypto_data[i]["priceusd"]
message += f"1 SFUND = \n${usdprice:,.2f} USD\n{bnbprice:.3f} BNB\n\n"
context.bot.send_message(chat_id=chat_id, text=message)
dispatcher.add_handler(CommandHandler("price", price))
updater.start_polling()
When the user types /price in the telegram chat it give this error:
coin = crypto_data[i]["pricebnb"]
TypeError: string indices must be integers
Could someone tell me what I'm doing wrong and help me solve the issue. Many thanks

TELEPOT Keep getting error 400 when chat not found when trying to call back query to send a message

This is my code, my conf.py file is just the API token which i have double checked and the timezone.
I am trying to get my bot to respond to a button click by sending a message or a photo. I understand i need to use the sendPhoto function but i dont know how to make it activate on the callback
import sys
import time
import os
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton
from telepot.delegate import (
per_chat_id, create_open, pave_event_space, include_callback_query_chat_id)
def on_chat_message(msg):
content_type, chat_type, chat_id = telepot.glance(msg)
if content_type == 'text':
if msg['text'] == '/start':
bot.sendMessage(chat_id, 'Welcome to #UK_Cali Teleshop\n Created by JonSnow 2021',reply_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Feedback",callback_data='a'), InlineKeyboardButton(text="You",callback_data='b'),InlineKeyboardButton(text="PGP",callback_data='c'), InlineKeyboardButton(text="Cunt",callback_data='d')],
[InlineKeyboardButton(text="Products",callback_data='e')]
]
))
bot.sendMessage(chat_id, 'Quanti anni hai?', reply_markup=keyboard)
def on_callback_query(msg):
query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
print('Callback Query:', query_id, from_id, query_data)
if query_data=='a':
bot.sendMessage(query_id, 'ddd')
bot = telepot.Bot('1646167995:AAGsOwfjcryYYkoah69QJ6XGA7koUywmuRk')
MessageLoop(bot, {'chat': on_chat_message,
'callback_query': on_callback_query}).run_as_thread()
print('Listening ...')
while 1:
time.sleep(10)
you get your 400 error because the chat id is not quesry_id that represents the query, but from_id that represents the chat so:
def on_callback_query(msg):
query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
print('Callback Query:', query_id, from_id, query_data)
if query_data=='a':
bot.sendMessage(from_id, 'ddd')

How to return a command when pressing on a button with Telegram Bot

I am trying to return a command with python-telegram-bot when I press a button with InlineKeyboardButton. I am trying the following but with no luck:
bot.send_message(chat_id=chat_id,
text='/help',
parse_mode=telegram.ParseMode.HTML)
First define your button by callback data:
import telegram
HELP_BUTTON_CALLBACK_DATA = 'A unique text for help button callback data'
help_button = telegram.InlineKeyboardButton(
text='Help me', # text that show to user
callback_data=HELP_BUTTON_CALLBACK_DATA # text that send to bot when user tap button
)
Show help button to user in start command or another way:
def command_handler_start(bot, update):
chat_id = update.message.from_user.id
bot.send_message(
chat_id=chat_id,
text='Hello ...',
reply_markup=telegram.InlineKeyboardMarkup([help_button]),
)
Define help command handler:
def command_handler_help(bot, update):
chat_id = update.message.from_user.id
bot.send_message(
chat_id=chat_id,
text='Help text for user ...',
)
Handle callback data:
def callback_query_handler(bot, update):
cqd = update.callback_query.data
#message_id = update.callback_query.message.message_id
#update_id = update.update_id
if cqd == HELP_BUTTON_CALLBACK_DATA:
command_handler_help(bot, update)
# elif cqd == ... ### for other buttons
At last add handlers to your bot and start polling
update = telegram.ext.Updater('BOT_TOKEN')
bot = update.bot
dp = update.dispatcher
print('Your bot is --->', bot.username)
dp.add_handler(telegram.ext.CommandHandler('start', command_handler_start))
dp.add_handler(telegram.ext.CommandHandler('help', command_handler_help))
dp.add_handler(telegram.ext.CallbackQueryHandler(callback_query_handler))
update.start_polling()

Categories