pyTelegramBotAPI message handlers can't see photo - telegram

I need my telegram bot to forward messages from the private chat to the customer care staff group.
I run this code:
#bot.message_handler(func=lambda message: message.chat.type=='private')
def forwarder(message):
bot.forward_message(group, message.chat.id, message.id)
bot.send_message(group, '#id'+str(message.chat.id))
It works smoothly with text messages, but does nothing with photos.
Even if I remove all previous message handlers, so there is no conflict with them to handle photos, it still keeps doing nothing.
If I use the get.updates() method I can check "manually" if the photo has arrived and I find it.
Edit: Even if i just run this code only
import telebot
bot = telebot.TeleBot("MY TOKEN")
#bot.message_handler(func=lambda message: True)
def trivial(message):
print('yes')
bot.polling()
I get 'yes' for text messages and absolutely nothing, not even raised exceptions for photos.

If you add content_types as a parameter you will receive whatever is specified in the argument (which takes an array of strings). Probably the default value for that parameter is set to ['text']. Which will only listen for 'text' messages.
To get the results you're looking for
your test code will look like:
import telebot
bot = telebot.TeleBot("MY TOKEN")
#bot.message_handler(func=lambda, message: True, content_types=['photo','text'])
def trivial(message):
print('yes')
bot.polling()
And your working code:
#bot.message_handler(func=lambda, message: message.chat.type=='private', content_types=['photo','text'])
def forwarder(message):
bot.forward_message(group, message.chat.id, message.id)
bot.send_message(group, '#id'+str(message.chat.id))

In Telegram Bot API there is a resource /sendphoto
See:
Sending message in telegram bot with images
Try to find the related method in the PyTelegramBotApi.
Or implement the function to send a photo your own (e.g. using requests library in Python). Then you can use it in the message-handlers of your bot, to forward images.

Related

Aiogram bot to answer my message in private chats but to reply my message in group chats

for telegram api, Message.reply_html("Hello") has quote which defaults to True in groups and False in private chats (https://docs.python-telegram-bot.org/en/v20.0a4/telegram.message.html#telegram.Message.reply_html). Does aiogram have similar features?
Basically I want the bot to not reply my message in private chats but reply my message in group chats. This is because when creating discussion groups in channels, in order for the bot's reply to be shown in the discussion group, it has to reply to the message of the one who sent the message.
I know that aiogram has both message.reply which replies to the user regardless whether hes in a group or not and message.answer which answers the user regardless whether hes in a group or not too. Theres also a chat type filter which filters messages to private user vs messages to supergroup but to do that, I will need to repeat my code twice which is kinda pointless right when the only difference is a message and a reply?
I tried message.reply('text', reply=False) but that just removes the reply from both groups and private chat, which is equivalent to just message.answer. Any help is appreciated! Thanks!
sorry for my bad English. Aiogram has Filters, namely aiogram.dispatcher.filters.ChatTypeFilter, which inherits BounbdFilter. With which we can create customizable filters for our tasks. More information you can found in documentation. I wrote simple example of a bot that works only in a group. In private chat he doesn't works.
from aiogram.dispatcher.filters import BoundFilter
from aiogram import types
# filter.py
class IsGroup(BoundFilter):
async def check(self, message: types.Message) -> bool:
return message.chat.type in (
types.ChatType.GROUP,
types.ChatType.SUPER_GROUP,
)
# handlers.py
#dp.message_handler(IsGroup(), content_types=types.ContentType.NEW_CHAT_MEMBERS)
async def new_member(message: types.Message):
members = ", ".join([m.get_mention(as_html=True) for m in message.new_chat_members])
await message.reply(f"Hello, {members}.")
We are creating a chat and if we add new member bot wrote "Hello, {member}". And if you want use bot only in a chat you need add in the decorator #dp.message_handler IsGroup() And make it the first argument

Can I share an object between telegram commands of a bot?

I want to create an object when the user press /start in a Telegram bot, and then share this object among all the commands of the bot. Is this possible? As far as I understand, there's only one thread of your bot running in your server. However, I see that there is a context in the command functions. Can I pass this object as a kind of context? For example:
'''
This is a class object that I created to store data from the user and configure the texts I'll display depending on
the user language but maybe I fill it also with info about something it will buy in the bot
'''
import configuration
from telegram import Update, ForceReply
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
# Commands of the bot
def start(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
s = configuration.conf(update) #Create the object I'm saying
update.message.reply_markdown_v2(s.text[s.lang_active],
reply_markup=ForceReply(selective=True),
)
def check(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
s = configuration.conf(update) # I want to avoid this!
update.message.reply_markdown_v2(s.text[s.lang_active],
reply_markup=ForceReply(selective=True),
)
... REST OF THE BOT
python-telegram-bot already comes with a built-in mechanism for storing data. You can do something like
try:
s = context.user_data['config']
except KeyError:
s = configuration.confi(update)
context.user_data['config'] = s
This doesn't have to be repeated in every callback - you can e.g.
use a TypeHandler in a low group to create the config if needed. then in all handlers in higher groups, you don't need to worry about it
use a custom implementation of CallbackContext that adds a property context.user_config
Disclaimer: I'm currently the maintainer of python-telegram-bot.

how to know where user starting chat? from inside group or from inside bot directly?

I have created telegram bot using telegraf.js
The bot is working correctly, however I need to handle a different thing if the user send message from inside bot directly, let's say the bot should replay with help commands documentations (for example).
the question is:
how to recoginze where the user start chatting? from inside chat group or from inside bot directly?
I tried
var groupInfo =await ctx.telegram.getChat()
without success
I thing the solution would be simple, but I can't find it till now.
thank you in advanced.
You should checkout Telegram docs for Chat type. It has a field called Type and according to the docs:
Type of chat, can be either “private”, “group”, “supergroup” or “channel”
So in telegraf.js you can check the field this ways:
bot.on('text', (ctx) => {
return ctx.reply(`Chat type is: ${ctx.message.chat.type}`)
})
In your case, ctx.message.chat.type == "private" would be messages that are sent to your bot privately and ctx.message.chat.type == "group" or ctx.message.chat.type == "supergroup" are messages sent to groups.

Telegram Bot is getting all channel messages

I want to create a telegram bot to send updates to the groups/channel in which it is added. I used BotFather to create a bot. However, in https://api.telegram.org/bot<BOTAPI>/getUpdates, I'm getting all the messages sent in a channel like this: "channel_post":{"message_id":59,"chat":{"id":-1001192794322,"title":"Nseindia","username":"nseindia_updates","type":"channel"},"date":1588581996,"text":"AMBUJACEM : Bear\nAPOLLOHOSP : Bullish Reversal\nKOTAKBANK : Bullish\nMOTHERSUMI : Bear"}}
This is not a problem now, but as time goes, the json file could get very large and could pose a problem.
Is there any way such that I don't get all the messages in the json present in https://api.telegram.org/bot<BOTAPI>/getUpdates
you should specify the update_id of the latest update you've processed as an offset parameter to getUpdates to make them(updates with less update_id) marked processed and that way they wont come up the next time you call getUpdates.
In telegram's Bot API Docs it says:
By default, updates starting with the earliest unconfirmed update are
returned. An update is considered confirmed as soon as getUpdates is
called with an offset higher than its update_id.

Discord Bot python 3.6 report command

I am making a custom discord bot in python. I am trying to add a !report command.
I am very confused and cant find the answer anywhere. Can anyone help me make it?
I want any user to be able to do !report #example reason.
and save it in a database such as excel or sql3 or preferably in a staff channel.
how would I do this?
I have tried to use on_message()
You could use the on_message() command:
#client.event
async def on_message(message):
if message.content.startswith("!report"):
report_channel = client.get_channel(channel id)
member = text.split(" ")[1]
reason = ' '.join(text.split(" ")[1:])
await report_channel.send(f"Member: {member}, Reason: {reason}")
So the first thing is to look to see if the person used the "!report" command with an if statement.
Next, you find the member by taking the second word of the message.
After that, you find the reason by taking the rest of the words in the message.
Then you send it to the pre-defined report channel on discord.

Resources