The NewMessage
event of telethon has an argument named from_users
which controls the event to only occur when the new message is from those users.
This argument accept entity
as input.
In order to get this entity, one must run the client and call the get_entity
method.
The problem is, when you run the client, the event is already set and prints out an error, because the input arguments are None or missing. and if you don't run the client, you don't have the desired_channel
entity to provide to NewMessage
event. at least this is my understanding of documentation and how the code is currently behaving for me.
i'm trying the following:
receiver.py:
from telethon import TelegramClient
from telegram.api_library import (
write_in_saved_messages,
get_entity_data,
)
from user_files.user_settings import (
USER_SESSION_NAME,
USER_TELEGRAM_API_HASH,
USER_TELEGRAM_API_ID,
)
telegram_client: TelegramClient = TelegramClient(
USER_SESSION_NAME, USER_TELEGRAM_API_ID, USER_TELEGRAM_API_HASH
async def main():
"""The main loop of message receiver"""
# This calls a function that writes in saved messages section from another module
await write_in_saved_messages(telegram_client, "Message Receiver started!")
# Get channel entity
# This also calls a function that gets entity of a given channel name from another module
desired_channel = await get_entity_data(
telegram_client, "desired_channel_name"
)
# Create the event
@events.register(
events.NewMessage(
incoming=True,
from_users=(desired_channel),
)
)
async def message_received(event):
"""This function will be called when a new message comes from the desired channel
Args:
event (_type_): Event containing information about the message
"""
incoming_message_text = event.message
sender_id = (await event.get_input_sender()).channel_id
print(f"Message from {sender_id}:\n{incoming_message_text}")
def start_receiver():
"""Start the receiver"""
with telegram_client:
telegram_client.loop.create_task(main())
telegram_client.add_event_handler(message_received)
telegram_client.run_until_disconnected()
How should i do it? How to have an entity
before running the client and getting the needed entity
?? i'm confused
So the following code does work as i want, but i don't think this is the way it should be done.
I edited the event to this:
@events.register(
events.NewMessage(
incoming=True, # I removed the (from_users) argument
)
)
async def message_received(event):
"""This function will be called when a new message comes from the defined channels
Args:
event (_type_): Event containing information about the message
"""
incoming_message_text = event.message.message
# We use try block here as we are going to get (channel_id) for all incoming messages
# because we are getting all incoming chats, this also includes users
# which don't have (channel_id) so an exception occurs
try:
sender_id = (await event.get_input_sender()).channel_id
if sender_id == desired_channel_id:
print(f"Message from {sender_id}:\n{incoming_message_text}")
# If Sender is NOT a channel, this exception occurs, we ignore it
except AttributeError as e:
print(e)
This is a hacky/inefficient way of getting the job done and i accept it, yet i don't know the correct way.
Until someone responds with a better answer, others facing this issue can use this hack at least.