discord.pypython-telegram-bot

Looping error from telegram to discord in python


I pulled this code from a github repo https://github.com/Sqble/Telegram-To-Discord-Bot-Fixed/blob/master/forwardgram.py and am running into a couple errors on the loop.

from telethon import TelegramClient, events
from telethon.tl.types import InputChannel
import yaml
import discord
import asyncio

message = []

with open('config.yml', 'rb') as f:
config = yaml.safe_load(f)



"""
TELEGRAM CLIENT STUFF
"""
client = TelegramClient("forwardgram", config["api_id"], 
config["api_hash"])
client.start()

#Find input telegram channels
input_channels_entities = []

for d in client.iter_dialogs():
if d.name in config["input_channel_names"]: #or d.entity.id in 
config["input_channel_id"]:
input_channels_entities.append( 
InputChannel(d.entity.id,d.entity.access_hash) )

if input_channels_entities == []:
print("No input channels found, exiting")
exit()


#TELEGRAM NEW MESSAGE
@client.on(events.NewMessage(chats=input_channels_entities))
async def handler(event):
# If the message contains a URL, parse and send Message + URL
try:
    parsed_response = (event.message.message + '\n' + 
event.message.entities[0].url )
    parsed_response = ''.join(parsed_response)
# Or we only send Message    
except:
    parsed_response = event.message.message

globals()['message'].append(parsed_response)



"""
DISCORD CLIENT STUFF
"""
discord_client = discord.Client(intents=discord.Intents.default())

async def background_task():
global message
await discord_client.wait_until_ready()
discord_channel = discord_client.get_channel(config["discord_channel"])
while True:
    if message != []:
        await discord_channel.send(message[0])
        message.pop(0)
    await asyncio.sleep(0.1)

discord_client.loop.create_task(background_task())



"""
RUN EVERYTHING ASYNCHRONOUSLY
"""

print("Listening now")
asyncio.run( discord_client.run(config["discord_bot_token"]) )
asyncio.run( client.run_until_disconnected() )

The above returns this error and I cant figure out why. C:\Discord Bot\Telegram-To-Discord-Bot-Fixed-master>python forwardgram.py Traceback (most recent call last): File "C:\Discord Bot\Telegram-To-Discord-Bot-Fixed-master\forwardgram.py", line 62, in discord_client.loop.create_task(background_task()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\discord\client.py", line 145, in getattr raise AttributeError(msg) AttributeError: loop attribute cannot be accessed in non-async contexts. Consider using either an asynchronous main function and passing it to asyncio.run or using asynchronous initialisation hooks such as Client.setup_hook


Solution

  • Running a synchronous function that blocks the loop (run_until_disconnected()) is always problematic. I recommend you adopt a strategy using loop.run_in_executor(), where you will run your telegram bot in a separate thread. Try this:

    # run tg bot
    @discord_client.event
    async def on_ready():
        loop = discord_client.loop
        await loop.run_in_executor(None, client.run_until_disconnected)
    
    # run discord bot
    discord_client.run(config["discord_bot_token"])