Python Telegram Bot. Get message to which given message replies - python

I want to develop a Telegram bot, that acts as a bookmarking system. It should process commands that reply to other messages. The instance:
I use python-telegram-bot for development and it seems that there is no way to see that message to which /important replies. I found the Update.message.reply_to_message object, which works only when a user replies to a message from the bot itself.
def important_handler(update: Update, context: CallbackContext):
reply_to_message = update.message.reply_to_message
if reply_to_message is None:
logger.error('reply_to_message is None. But it shouldn\'t.')
update.message.reply_text('There is no message attached. Try again.')
return
# ... business logic
Is there any way to get reply_to_message attribute (or an alternative) for all the replies? Thanks in advice;)

I had the same problem. It only worked when a user replied to the bot. My issue was that the bot had Privacy Mode enabled. Once I disabled it with Botfather via /setprivacy and then it worked.

Related

Python, Deep Link directing User to Bot Private Chat after Button click

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)

Status check always showing that the user is 'offline'

So I'm getting an issue here where I'm trying to make a status check command to check if a user is online, offline, idle, or dnd, if they are on mobile or desktop, and maybe even their custom status. However, my main problem is seeing if a user is online/offline or whatever. It seems to always return 'offline' even though I know I'm not offline. Here's my code (currently its just printing to console to see)
#client.command(name="status")
async def status(ctx, user: discord.Member=None):
if not user:
user = ctx.message.author
print(user)
print(user.raw_status)
However when I initiate this command it always returns 'offline', and I haven't been able to figure out why. I've tried: user.status, user.raw_status, user.desktop_status, and just in case it was being weird or I didn't understand it, mobile_status (I'm on desktop.) If anyone has a fix to this please let me know, thanks!
If you haven't added intents to your bot, then you cannot deal with user statuses in a server. Head to "https://discord.com/developers/applications//bot" and under "Privileged Gateway Intents" tick "PRESENCE INTENT" and "SERVER MEMBERS INTENT". This will allow the bot to request presence data from users in the server.
In your bot's code, add
from discord import Intents
client = commands.Bot(command_prefix=YOUR_PREFIX, intents = Intents.all())

SlackClient Python RTM not capturing messages

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.

Why the client.listen in fbchat cannot work again?

I wan to make a chatbot that will automatically reply . it will collect reply from client.listen and then decide the reply to the user.
from fbchat import log, Client
# Subclass fbchat.Client and override required methods
class EchoBot(Client):
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
self.markAsDelivered(thread_id, message_object.uid)
self.markAsRead(thread_id)
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
# If you're not the author, echo
if author_id != self.uid:
self.send(message_object, thread_id=thread_id, thread_type=thread_type)
client = EchoBot("myaccount", "mypassword")
client.listen()
It worked fine until today.
Even it receive the message.the program still will stuck in client.listen
The output that i receive is this
Logging in myAccount...
Login of myAccount successful.
Listening...
When i try to contact my account , it still wont give me reply but it just stuck in client.listen
the output i wan to get is it will collect info from client.listen() and give me reply.
I believe that facebook has changed the structure of the website (id's, classes...) where fbchat library was scraping data from (Keep in mind that fbchat is not an official facebook library). This can happen with any API that is not official. I have hosted my bot 24/7 and all of sudden it stopped working. Your code is perfectly correct. From what I have tested so far I can tell that EchoBot class stopped working with all of it's event listeners, but at the other hand you can still send messages with client.send(...) We can only hope that developers of fbchat library will fix this soon.
See here for more info: https://github.com/carpedm20/fbchat/issues/483
2020 UPDATE
The issue was fixed in new version of fbchat 1.9.6.
Just update the module with:
pip install fbchat --upgrade

Python Telegram Bot - How to update the text of the last message my bot has sent

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.

Categories