davidmckenzie / telebagger

Simple Telegram to Discord one-way relay service
The Unlicense
30 stars 14 forks source link

Telelooper doen't work anymore after Telethon got an update #4

Closed Argon007 closed 5 years ago

Argon007 commented 5 years ago

Hi,

Can someone please help me? The Telelooper and Telebagger scripts aren't working anymore since Telethon was updated. I'm not a coder so it's difficult to see what's really wrong.

I tried some things and got a but further in it, but now i'm stuck.

This is what I have right now:

from discord_hooks import Webhook
from telethon import TelegramClient
from telethon.tl.functions.messages import GetDialogsRequest, GetHistoryRequest
from telethon.tl.functions.channels import GetFullChannelRequest
from telethon.tl.functions.updates import GetChannelDifferenceRequest
from telethon.tl.types import UpdateShortMessage, UpdateNewChannelMessage, PeerUser, PeerChat, PeerChannel, InputPeerEmpty, Channel, ChannelMessagesFilter, ChannelMessagesFilterEmpty
from time import sleep
import json
import os
import requests
import logging
import pprint
pp = pprint.PrettyPrinter(indent=4)
#logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M')
logger = logging.getLogger('telebagger')

with open('config.json') as config_file:
    config = json.load(config_file)

try:
    url = config['discord']['url']
    api_id = config['telegram']['api_id']
    api_hash = config['telegram']['api_hash']
    phone = config['telegram']['phone']
    channel_id = config['telegram']['channel_id']
    everyone = config['telegram']['everyone']
    loglevel = config['telegram']['loglevel']
except:
    logger.error('Error processing config file')

logger.setLevel(loglevel)

print('Connecting to Telegram...')

tclient = TelegramClient('session_name', api_id, api_hash).start()
tclient.connect()
if not tclient.is_user_authorized():
    tclient.send_code_request(phone)
    myself = tclient.sign_in(phone, input('Enter code: '))

lastmessage = 0
last_date = None
chunk_size = 20
chan_type = 'channel'
result = tclient(GetDialogsRequest(
                 offset_date=last_date,
                 offset_id=0,
                 offset_peer=InputPeerEmpty(),
                 limit=chunk_size,
         hash=0
             ))
pp.pprint(result)
print("\nAvailable Channels:")
for p in result.chats:
    if type(p) is Channel:
        print(str(p.id)+": "+p.title)
        if p.id == channel_id:
            channel_name = p.title
            print(p.stringify())
            chan_type = 'channel'
for u in result.users:
    print(str(u.id)+": "+u.first_name)
    if u.id == channel_id:
        channel_name = u.first_name
        print(u.stringify())
        chan_type = 'user'
# for d in result.dialogs:
#     print(d.stringify())

if chan_type == 'channel':
    channelEnt = tclient.get_input_entity(PeerChannel(channel_id))
else:
    channelEnt = tclient.get_input_entity(PeerUser(channel_id))

try:
    logger.info("\nListening for messages from channel '{}' with ID '{}'".format(channel_name,channel_id))
except:
    logger.error("Whoops! Couldn't find channel ID '{}'".format(channel_id))

history = tclient(GetHistoryRequest(peer=channelEnt,
                                            offset_date=last_date,
                                            offset_id=0,
                                            add_offset=0,
                                            limit=10,
                                            max_id=0,
                                            min_id=0,
                                            hash=0
                                        ))
history.messages.reverse()
logger.info("\nLast 10 Messages:\n")
for m in history.messages:
    datetime = m.date.strftime('%Y-%m-%d %H:%M:%S')
    try:
        logger.info(datetime+" "+str(m.id)+": "+m.message)
    except:
        continue
    if m.id > lastmessage:
        lastmessage = m.id
    try:
        logger.info("Relaying Message {}".format(m.id))
        media = m.media
        if media is not None:
            logger.info("Would download image")
            logger.debug(media)
            # download_res = tclient.download_media(
            #     media, './downloads/')
            # logger.info("Download done: {}".format(download_res))
            # files = {'file': (open(download_res, 'rb'))}
            # response = requests.post(url, files=files)
            # logger.debug(response.text)
            # os.remove(download_res)
            # logger.debug("File deleted")
        if not m.message == '':
            if everyone:
                msgText = "@noteveryone {}".format(m.message)
            else:
                msgText = "{}".format(m.message)
            #msg = Webhook(url,msg=msgText)
            #msg.post()
    except:
        logger.info('Ignoring empty message {} action: {}'.format(m.id, m.action))
    try:
        logger.info(datetime+" "+str(m.id)+": "+m.message)
    except:
        logger.debug(m)

while True:
    try:
        messages = tclient(GetHistoryRequest(peer=channelEnt,
                                            offset_date=last_date,
                                            offset_id=0,
                                            add_offset=0,
                                            limit=50,
                                            max_id=0,
                                            min_id=lastmessage,
                                            hash=0
                                        ))
        if len(messages.messages) > 0:
            logger.debug('New Messages: ')
            logger.debug(messages)
            for m in messages.messages:
                datetime = m.date.strftime('%Y-%m-%d %H:%M:%S')
                if m.id > lastmessage:
                    lastmessage = m.id
                try:
                    logger.info("Relaying Message {}".format(m.id))
                    media = m.media
                    if media is not None:
                        logger.info("Will download image")
                        logger.debug(media)
                        download_res = tclient.download_media(
                            media, './downloads/')
                        logger.info("Download done: {}".format(download_res))
                        files = {'file': (open(download_res, 'rb'))}
                        response = requests.post(url, files=files)
                        logger.debug(response.text)
                        os.remove(download_res)
                        logger.debug("File deleted")
                    if not m.message == '':
                        if everyone:
                            msgText = "@everyone {}".format(m.message)
                        else:
                            msgText = "{}".format(m.message)
                        msg = Webhook(url,msg=msgText)
                        msg.post()
                except:
                    logger.info('Ignoring empty message {} action: {}'.format(m.id, m.action))
                try:
                    logger.info(datetime+" "+str(m.id)+": "+m.message)
                except:
                    logger.debug(m)
        sleep(2)
        continue
    except KeyboardInterrupt:
        break

tclient.disconnect()

But when I run it I get the following error:

Connecting to Telegram...
10-29 11:45 telethon.network.mtprotosender INFO     Connecting to 149.154.167.91                                                                                                                                                             :443...
10-29 11:45 telethon.network.mtprotosender INFO     Connection to 149.154.167.91                                                                                                                                                              complete!
<coroutine object __call__ at 0x7f6b6b479888>

Available Channels:
Traceback (most recent call last):
  File "telelooper.py", line 61, in <module>
    for p in result.chats:
AttributeError: 'coroutine' object has no attribute 'chats'
sys:1: RuntimeWarning: coroutine '__call__' was never awaited

So there is a connection, because I received the SMS, but now it says something about the attribute 'chats'.

Or does anyone know another solution to forward Telegram posts to Discord? Many thanks !

davidmckenzie commented 5 years ago

Does it work with previous version?

pip install -I telethon=1.2

Argon007 commented 5 years ago

1.2 or the newest 1.3 version are giving me the samer error messages. Seems to be broken when Telethon went to version 1.x it seems.

I already changed this line to get it starting:

tclient = TelegramClient('session_name', api_id, api_hash).start()

But no idea how to solve this one:

Traceback (most recent call last):
  File "telelooper.py", line 61, in <module>
    for p in result.chats:
AttributeError: 'coroutine' object has no attribute 'chats'

I rely on you to solve this. But if you don't have time to have a quick look into it, no problem! In the end it's a hobby project and not a paid one :-)

thank you in advance!

P.S or do you know another project that can forward Telegram messages -> Discord without being a bot on the Telegram side?

davidmckenzie commented 5 years ago

So the version I'm using which works is 0.19.1.4, reading the docos for the 1.0 change it would require a fair bit of refactoring. It "aint broke" at the moment for me so unless something changes in the Telegram API it's unlikely I'll be refactoring for the new version.

So my suggestion would be to either manually install 0.19.1.4, or try the telethon-sync branch mentioned in the docos here.

If you’re not ready for this, you can pip install telethon-sync. It’s a synchronous branch that mimics the asyncio version with threads and should work under Python 3.4

Argon007 commented 5 years ago

Hi,

forgot to answer you about this topic. I installed version 0.19.1.4 and like you mentioned, everything is working fine!

Great work and thanks!