如何从事件循环外部(即从 python-telegram-bot 线程)发送带有 discord.py 的消息?

M. *_*ing 2 python-3.x python-asyncio python-telegram-bot discord.py

我想通过使用库 python-telegram-bot 和 discord.py (版本 1.0.0)来制作一个在不和谐和电报之间进行通信的机器人。然而问题是 discord.py 使用异步函数和 python-telegram-bot 线程。使用下面的代码,对于在 discord 中发布的消息(机器人将它们正确发送到电报),一切正常,但反之则行不通(机器人从电报获取消息并将其发送到不和谐)。我以前在尝试channel.send在同步函数中运行 discords函数时遇到了语法/运行时错误的问题(因此要么只返回一个生成器对象,要么抱怨我无法使用await在同步函数中使用)。然而,与此同时,python-telegram-bot 的MessageHandler需要一个同步函数,所以当给他一个异步函数时,Python 抱怨从来没有为异步函数调用“await”。我现在试图用async_to_sync方法从asgiref库运行我的异步broadcastMsgMessageHandler,但是代码仍然不将消息发送给不和谐!它似乎正确地调用了该函数,但仅在 line 之前print('I get to here')。没有错误显示,也没有不和谐的消息弹出。我想这与我必须在 discord.py 事件循环中将该函数注册为任务这一事实有关,但是注册仅在它发生之前才有效botDiscord.run(TOKENDISCORD)已经被执行,这当然必须在之前发生。因此,将我的问题归结为一个问题:我如何能够与来自另一个线程(来自电报MessageHandler)的 discord.py 事件循环进行交互。或者,如果这是不可能的:如何在不处于 discord.py 事件循环中的情况下使用 discord.py 发送消息?

感谢您的帮助

import asyncio
from asgiref.sync import async_to_sync
from telegram import Message as TMessage
from telegram.ext import (Updater,Filters,MessageHandler)
from discord.ext import commands
import discord

TChannelID = 'someTelegramChannelID'
DChannel = 'someDiscordChannelObject'

#%% define functions / commands
prefix = "?"
botDiscord = commands.Bot(command_prefix=prefix)
discordChannels = {}


async def broadcastMsg(medium,channel,message):
    ''' 
    Function to broadcast a message to all linked channels.
    '''
    if isinstance(message,TMessage):
        fromMedium = 'Telegram'
        author = message.from_user.username
        channel = message.chat.title
        content = message.text
    elif isinstance(message,discord.Message):
        fromMedium = 'Discord'
        author = message.author
        channel = message.channel.name
        content = message.content
    # check where message comes from        
    textToSend = '%s wrote on %s %s:\n%s'%(author,fromMedium,channel,content)
    # go through channels and send the message
    if 'telegram' in medium:
        # transform channel to telegram chatID and send
        updaterTelegram.bot.send_message(channel,textToSend)

    elif 'discord' in medium:
        print('I get to here')
        await channel.send(textToSend)

    print("I do not get there")


@botDiscord.event
async def on_message(message):
    await broadcastMsg('telegram',TChannelID,message)

def on_TMessage(bot,update):
    # check if this chat is already known, else save it
    # get channels to send to and send message
    async_to_sync(broadcastMsg)('discord',DChannel,update.message)


#%% initialize telegram and discord bot and run them
messageHandler = MessageHandler(Filters.text, on_TMessage)
updaterTelegram = Updater(token = TOKENTELEGRAM, request_kwargs={'read_timeout': 10, 'connect_timeout': 10})
updaterTelegram.dispatcher.add_handler(messageHandler)
updaterTelegram.start_polling()
botDiscord.run(TOKENDISCORD)  
Run Code Online (Sandbox Code Playgroud)

use*_*342 6

如何在不处于 discord.py 事件循环中的情况下使用 discord.py 发送消息?

要从事件循环线程外部安全地调度协程,请使用asyncio.run_coroutine_threadsafe

_loop = asyncio.get_event_loop()

def on_TMessage(bot, update):
    asyncio.run_coroutine_threadsafe(
        broadcastMsg('discord', DChannel, update.message), _loop)
Run Code Online (Sandbox Code Playgroud)