patch 10725c4fff915a1c95e95b5f998f26c97b146d5e Author: E. Bosch Date: Wed Jan 22 00:35:42 CET 2025 * telegram: Try to fix ChatAdminRequiredError when getting participants from a channel reported in https://github.com/prsai/irgramd/issues/1 patch 0c96892ec68150c96ef7ba50ec4e2db3db2296e4 Author: E. Bosch Date: Thu Jan 16 22:00:14 CET 2025 * exclam: Fix send a reaction when there was already a previous reaction from other user on the same message, for some reason the 'message' attribute is not received patch 89bc0957a4fb31bf8066e338bc4548cd2d52c821 Author: E. Bosch Date: Sat Nov 2 20:20:45 CET 2024 * telegram, irc: Set topic in IRC with Telegram channel/chat description patch 86ef89f9f9220ecde8477db2aa673f94f32656ab Author: E. Bosch Date: Sat Oct 26 20:43:28 CEST 2024 * telegram: Fix op and founder detection in channels patch 6d99fce9643fbdda1594f99331f4a4642ecc7f0f Author: E. Bosch Date: Sat Oct 26 20:35:11 CEST 2024 * telegram: Fix handler for next reactions when the event is empty patch efaf8df4b3fa314997615e2fc07a3decb3a7cfba Author: E. Bosch Date: Sat Oct 26 13:01:02 CEST 2024 * exclam: Reorder handler list so commands are listed ordered in help diff -rN -u old-irgramd-1/exclam.py new-irgramd-1/exclam.py --- old-irgramd-1/exclam.py 2025-04-19 16:38:10.781806491 +0200 +++ new-irgramd-1/exclam.py 2025-04-19 16:38:10.801806457 +0200 @@ -18,13 +18,13 @@ def __init__(self, telegram): self.commands = \ { # Command Handler Arguments Min Max Maxsplit - '!re': (self.handle_command_re, 2, 2, 2), - '!ed': (self.handle_command_ed, 2, 2, 2), '!del': (self.handle_command_del, 1, 1, -1), + '!ed': (self.handle_command_ed, 2, 2, 2), '!fwd': (self.handle_command_fwd, 2, 2, -1), - '!upl': (self.handle_command_upl, 1, 2, 2), - '!reupl': (self.handle_command_reupl, 2, 3, 3), + '!re': (self.handle_command_re, 2, 2, 2), '!react': (self.handle_command_react, 2, 2, -1), + '!reupl': (self.handle_command_reupl, 2, 3, 3), + '!upl': (self.handle_command_upl, 1, 2, 2), } self.tg = telegram self.irc = telegram.irc @@ -205,8 +205,8 @@ except ReactionInvalidError: reply = ('!react: Reaction not allowed',) else: - self.tmp_tg_msg = update.updates[0].message - reply = True + self.tmp_tg_msg = getattr(update.updates[0], 'message', None) + reply = bool(self.tmp_tg_msg) else: reply = ('!react: Unknown reaction',) else: diff -rN -u old-irgramd-1/include.py new-irgramd-1/include.py --- old-irgramd-1/include.py 2025-04-19 16:38:10.785806484 +0200 +++ new-irgramd-1/include.py 2025-04-19 16:38:10.801806457 +0200 @@ -11,3 +11,4 @@ VERSION = '0.2' NICK_MAX_LENGTH = 20 CHAN_MAX_LENGTH = 50 +MAX_LINE = 400 diff -rN -u old-irgramd-1/irc.py new-irgramd-1/irc.py --- old-irgramd-1/irc.py 2025-04-19 16:38:10.785806484 +0200 +++ new-irgramd-1/irc.py 2025-04-19 16:38:10.805806450 +0200 @@ -18,7 +18,7 @@ # Local modules -from include import VERSION, CHAN_MAX_LENGTH, NICK_MAX_LENGTH +from include import VERSION, CHAN_MAX_LENGTH, NICK_MAX_LENGTH, MAX_LINE from irc_replies import irc_codes from utils import chunks, set_replace, split_lines from service import service @@ -259,7 +259,7 @@ real_chan = self.get_realcaps_name(chan) users_count = len(self.irc_channels[chan]) topic = await self.tg.get_channel_topic(chan, [None]) - await self.reply_code(user, 'RPL_LIST', (real_chan, users_count, topic)) + await self.reply_code(user, 'RPL_LIST', (real_chan, users_count, topic[:MAX_LINE])) await self.reply_code(user, 'RPL_LISTEND') async def handle_irc_names(self, user, channels): @@ -612,7 +612,7 @@ founder = list(self.irc_channels_founder[chan])[0] else: founder = self.service_user.irc_nick - await self.reply_code(user, 'RPL_TOPIC', (channel, topic)) + await self.reply_code(user, 'RPL_TOPIC', (channel, topic[:MAX_LINE])) await self.reply_code(user, 'RPL_TOPICWHOTIME', (channel, founder, timestamp)) async def irc_namelist(self, user, channel): diff -rN -u old-irgramd-1/telegram.py new-irgramd-1/telegram.py --- old-irgramd-1/telegram.py 2025-04-19 16:38:10.797806464 +0200 +++ new-irgramd-1/telegram.py 2025-04-19 16:38:10.805806450 +0200 @@ -15,7 +15,8 @@ import collections import telethon from telethon import types as tgty, utils as tgutils -from telethon.tl.functions.messages import GetMessagesReactionsRequest +from telethon.tl.functions.messages import GetMessagesReactionsRequest, GetFullChatRequest +from telethon.tl.functions.channels import GetFullChannelRequest # Local modules @@ -176,16 +177,21 @@ self.irc.iid_to_tid[chan] = chat.id self.irc.irc_channels[chan] = set() # Add users from the channel - async for user in self.telegram_client.iter_participants(chat.id): - user_nick = self.set_ircuser_from_telegram(user) - if not user.is_self: - self.irc.irc_channels[chan].add(user_nick) - # Add admin users as ops in irc - if isinstance(user.participant, tgty.ChatParticipantAdmin): - self.irc.irc_channels_ops[chan].add(user_nick) - # Add creator users as founders in irc - elif isinstance(user.participant, tgty.ChatParticipantCreator): - self.irc.irc_channels_founder[chan].add(user_nick) + try: + async for user in self.telegram_client.iter_participants(chat.id): + user_nick = self.set_ircuser_from_telegram(user) + if not user.is_self: + self.irc.irc_channels[chan].add(user_nick) + # Add admin users as ops in irc + if isinstance(user.participant, tgty.ChatParticipantAdmin) or \ + isinstance(user.participant, tgty.ChannelParticipantAdmin): + self.irc.irc_channels_ops[chan].add(user_nick) + # Add creator users as founders in irc + elif isinstance(user.participant, tgty.ChatParticipantCreator) or \ + isinstance(user.participant, tgty.ChannelParticipantCreator): + self.irc.irc_channels_founder[chan].add(user_nick) + except: + self.logger.warning('Not possible to get participants of channel %s', channel) def get_telegram_nick(self, user): nick = (user.username @@ -307,8 +313,16 @@ else: entity = await self.telegram_client.get_entity(tid) entity_cache[0] = entity + if isinstance(entity, tgty.Channel): + full = await self.telegram_client(GetFullChannelRequest(channel=entity)) + elif isinstance(entity, tgty.Chat): + full = await self.telegram_client(GetFullChatRequest(chat_id=tid)) + else: + return '' entity_type = self.get_entity_type(entity, format='long') - return 'Telegram ' + entity_type + ' ' + str(tid) + ': ' + entity.title + topic = full.full_chat.about + sep = ': ' if topic else '' + return entity_type + sep + topic async def get_channel_creation(self, channel, entity_cache): tid = self.get_tid(channel) @@ -574,9 +588,9 @@ self.logger.debug('Handling Telegram Next Reaction (2nd, 3rd, ...): %s', pretty(event)) reactions = event.reactions.recent_reactions - react = max(reactions, key=lambda y: y.date) - - if self.last_reaction != react.date: + react = max(reactions, key=lambda y: y.date) if reactions else None + + if react and self.last_reaction != react.date: self.last_reaction = react.date id = event.msg_id msg = await self.telegram_client.get_messages(entity=event.peer, ids=id) diff -rN -u old-irgramd-1/utils.py new-irgramd-1/utils.py --- old-irgramd-1/utils.py 2025-04-19 16:38:10.797806464 +0200 +++ new-irgramd-1/utils.py 2025-04-19 16:38:10.809806444 +0200 @@ -20,6 +20,8 @@ FILENAME_INVALID_CHARS = re.compile('[/{}<>()"\'\\|&#%?]') SIMPLE_URL = re.compile('http(|s)://[^ ]+') +from include import MAX_LINE + # Utilities class command: @@ -61,9 +63,8 @@ return (x + mark if n != length else x for n, x in enumerate(items, start=1)) def split_lines(message): - MAX = 400 messages_limited = [] - wr = textwrap.TextWrapper(width=MAX) + wr = textwrap.TextWrapper(width=MAX_LINE) # Split when Telegram original message has breaks messages = message.splitlines()