#events.register(events.NewMessage(chats='tubot'))
async def mi_handler(event):
client = event.client
if 'A big' in event.raw_text:
async for message in client.iter_messages('tubot', limit=1, from_user='tubot'):
await message.click(0)
url = event.message.buttons[0][0].url
print(url)
await event.client.send_message('mybot', url.split('=')[1])
This code does something to me that had never happened to me before:
The code should do is: when the message appears in the ¨tubot¨, it should press the button and unlock the url, then a part of that url will send it to my bot called ¨mybot¨.
BUT:
when the message arrives in ´tubot´ the code click on the button and unlock the url, but it does not forward it to ´mybot´.
however when that message with the button already unlocked I manually forward it to "tubot" the code does forward it perfectly to ´mybot´
I have tried the following:
1- await asyncio.sleep(0.2) put an await between clicking on the button and reading the url and nothing didn't work.
2- even separate the code into two parts, one that clicks the button and another that forwards and nothing did not work
3- I made a group I put the code to click on the 'tubot' message and forward it to the group and another code that reads the message in that group with the button already unlocked and forwards the url to 'mybot' and nothing did not work. Even in the group, if I forward the message with the unlocked button, it reads me the url perfectly and it forwards me perfectly to 'mybot' but if it does the code doesn't work
Related
I have a question that I can‘t resolve it. I am using Telebot API to create a Telegram Bot, all I want to do is, when Bot sends a Button in a Group, when User clicks this Button first time, to be redirected in the Bots Private Message "http://telegram.me/<Bot_Username>?start=start", where User can Start the Bot.
My code in Python:
#bot.callback_query_handler(func=lambda call: 'begin_config' in call.data)
def query(call):
bot.message.reply_to(text="http://telegram.me/<BotName>?start=start")
#bot.message_handler(commands=['bot_config'])
def bot_config(message):
text_to_post = "Greetings, Bot here, hit the Button to configure"
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text='Bot configuration', callback_data='begin_config'))
bot.reply_to(message, text_to_reply, reply_markup=markup)
I am getting the Error: AttributeError: 'TeleBot' object has no attribute 'message'
When I use
call.message.reply_markup(text="http://telegram.me/?start=start")
I am getting the Error: AttributeError: TypeError: 'InlineKeyboardMarkup' object is not callable
I just want User, when he clicks the Button [Bot configuration] first time to get the Private Chat of the Bot, where the User can start the Bot.
enter image description here
Thank's for anyone attempting to solve my Problem, but I solved it by myself. It was unclear for me since Bot can't send Private Messages to Users, as long as they have not Start-ed the Bot. So I wanted to redirect the User to Start my Bot, by clicking the Button posted by the Bot in the Group.
In this case the Callback is not needed at all, just create a Button containing the Bots Address as Url and send it to ChatID, when User clicks the Button, it automatically invites the User to Start the Bot, after that User can Start the Bot and can get Private Messages.
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text='Bot configuration',
url="https://t.me/<Bot_Name>"))
bot.send_message(chat_id=chat_id, caption=text_to_post,
reply_markup=markup, parse_mode=ParseMode.HTML)
When I hit refresh on a page with flash message already showing, the message persist even after the refresh. How do I stop the message from showing on refresh? I noticed when I use render_template after flash the flash message will persist, but when I use redirect it doesn't. However I have to pass a non-3xx status code when I flash a message, using redirect only gets user wait on a redirection page until further action, which is not desirable either.
Method 1: Shows the right page but message persists on refresh:
flash("An error occurred.")
return render_template("page.html"), 400
Method 2: Stuck on redirection page but message doesn't persist on refresh:
flash("An error occurred.")
return redirect(url_for('show-page'), code=400)
Redirecting...
You should be redirected automatically to target URL: /page. If not click the link.
Method 2 does work as I intended if I pass a 3xx code, but I need to pass non-3xx code.
Note: The user should be on the same page throughout.
In my case, the flash message pops up to give users feedback immediately after they submit a form. The message persisted after refresh because the refresh triggered a double submit of the form. Redirect prevents the double submit problem and subsequently the persistent message. I read another post on the status code. Since this is all user-facing rather than a REST API, status code doesn't really matter, I went with method 2 with a 3xx default status code:
flash("An error occurred.")
return redirect(url_for('show-page'))
In my case all the messages were stuck in session when using the stream_template and when changing to render_template the messages were removed from the session normally.
#app.route("/startpage", methods=['GET', 'POST'])
def startpage():
if validate_token() == True:
flashes = session.get('_flashes', [])
print(flashes)
#return stream_template('start_page.html', title="Inicio")
return render_template('start_page.html', title="Inicio")
else:
return redirect(url_for('index'))
I did some tests and in my case it really was that. I didn't find anything in the Flask documentation talking about this difference in stream_template and render_template.
I am working with the bot-auth sample and after having the user logged in I need to be able to interact with the user, in my case I would like to start with an echo. I can't find a way to end the dialog and for the bot to start answering the user. Could you guide me with an example or ideas? Thanks
I wouldn't need to show the token, so at this point it would be enough for me to finish here and start interacting with the user
main_dialog.py
async def login_step(self, step_context: WaterfallStepContext) -> DialogTurnResult:
# Get the token from the previous step. Note that we could also have gotten the
# token directly from the prompt itself. There is an example of this in the next method.
if step_context.result:
await step_context.context.send_activity("You are now logged in.")
return await step_context.prompt(
ConfirmPrompt.__name__,
PromptOptions(
prompt=MessageFactory.text("Would you like to view your token?")
),
)
await step_context.context.send_activity(
"Login was not successful please try again."
)
return await step_context.end_dialog()
I could achieve my goal, which was once finished the login of the user to start, e.g, using a echo_bot or qna_bot. The problem is that I couldn't get out of the login-show token dialog loop. The solution "I found" is to create a user_state.create_property() in main_dialog.py and access properties defined get(turn_context) in dialog_bot.py. With this I was able to leave the dialogue.
I want to write a simple slack bot, which responds a given string to # mentions, however I am not able to make the official documentation code to work.
I gave all OAuth permission to the bot and have the following code:
from slack import RTMClient
#RTMClient.run_on(event="message")
def gravity_bot(**payload):
data = payload['data']
print(data.get('text'))
try:
rtm_client = RTMClient(
token="my_token_auth_code",
connect_method='rtm.start'
)
print("Bot is up and running!")
rtm_client.start()
except Exception as err:
print(err)
I think the connection is established, as the "Bot is up and running" message appears, however on the slack channel to bot seems to be offline, also I am not able to get any response in the terminal, not for direct messages, not for channel messages even after inviting the bot to given channels.
Sorry couldn't let this one go.. I figured it out and here are the steps:
Create a "Classic" app in Slack (this is the only way to get the appropriate scopes), just click this link: https://api.slack.com/apps?new_classic_app=1
From the "Add features and functionality" tab click on "bots":
Click the "Add Legacy Bot User" button (this will add the "rtm.stream" scope that you need, but that you cannot add manually)
From the basic information page, install your app in a workspace
From the OAuth & Permissions page, copy the "Bot User OAuth Access Token" (the bottom one)
Run the following code (slightly modified version of the code in the docs)
from slack_sdk.rtm import RTMClient
# This event runs when the connection is established and shows some connection info
#RTMClient.run_on(event="open")
def show_start(**payload):
print(payload)
#RTMClient.run_on(event="message")
def say_hello(**payload):
print(payload)
data = payload['data']
web_client = payload['web_client']
if 'Hello' in data['text']:
channel_id = data['channel']
thread_ts = data['ts']
user = data['user']
web_client.chat_postMessage(
channel=channel_id,
text=f"Hi <#{user}>!",
thread_ts=thread_ts
)
if __name__ == "__main__":
slack_token = "<YOUR TOKEN HERE>"
rtm_client = RTMClient(token=slack_token)
rtm_client.start()
Previous answer:
Hmm, this is tricky one... According to the docs this only works for "classic" Slack apps, so that might be the first pointer. It explicitly says that you should not upgrade your app. Furthermore, you'll need to set the right permissions (god knows which ones) by selecting the "bot" scope.
Honestly, I haven't been able to get this running. Looks like Slack is getting rid of this connection method, so you might have more luck looking into the "Events API". I know it's not the ideal solution because its not as real-time, but it looks better documented and it will stay around for a while. Another approach could be polling. Its not sexy but it works...
My guess is that your problem is that there is not a valid connection, but there is no proper error handling in the Slack library. The message is printed before you actually connect, so that doesn't indicate anything.
I'm using python-telegram-bot (python-telegram-bot.org) to communicate with Telegram from Python3
I would like to update the last reply I sent.
Currently, the code below sends the message and then sends
another message 5 seconds later.
def echo(bot, update):
update.message.reply_text("Sorry, you're on your own, kiddo.")
time.sleep(5)
update.message.reply_text("Seriously, you're on your own, kiddo.")
I'd like to update the last message instead.
I tried
bot.editMessageText("Seriously, you're on your own, kiddo.",
chat_id=update.message.chat_id,
message_id=update.message.message_id)
which works in the examples to update replace an inline keyboard with a a message, but that crashes (and does not update the last message I sent as a bot).
I believe the order of your arguments in edit_message_text() is wrong. Check out the docs for that:
def echo(bot, update):
# Any send_* methods return the sent message object
msg = update.message.reply_text("Sorry, you're on your own, kiddo.")
time.sleep(5)
# you can explicitly enter the details
bot.edit_message_text(chat_id=update.message.chat_id,
message_id=msg.message_id,
text="Seriously, you're on your own, kiddo.")
# or use the shortcut (which pre-enters the chat_id and message_id behind)
msg.edit_text("Seriously, you're on your own, kiddo.")
The docs for the shortcut message.edit_text() is here.