gpt4 book ai didi

python - 使用带有 discord.py 的 tweepy 将推文发布到特定 channel

转载 作者:行者123 更新时间:2023-12-04 11:36:20 45 4
gpt4 key购买 nike

因此,我正在尝试使用教程、文档和在线示例的组合来自学一些 Python,以构建一个 Discord 机器人,该机器人实现了一个或多个现有机器人的某些功能。其中一个功能是将(新)推文从一组特定的 Twitter 帐户发布到我的 Discord 服务器上的特定 channel 。我找到了一些零碎的代码,我拼凑起来从 Twitter 流中读取,并在这里和那里“调整”了一些东西以尝试实现这一目标。
但是,我一直遇到实际获取 on_status 的问题。正确执行的代码。我尝试了多种方法来使其正常工作,但是我尝试的所有方法都会导致某种错误。以下是我一直在测试的最新迭代中的相关代码(已编辑):

import discord
import tweepy

from discord.ext import commands
from tweepy import Stream
from tweepy.streaming import StreamListener

class TweetListener(StreamListener):
def on_status(self, status):
if status.in_reply_to_status_id is None:
TweetText = status.text

for DGuild in MyBot.guilds:
for DChannel in DGuild.text_channels:
if DChannel.name == 'testing':
TwitterEmbed = discord.Embed(title='New Tweet', description='New Tweet from my timeline.', color=0xFF0000)
TwitterEmbed.set_author(name='@TwitterHandle', icon_url=bot.user.default_avatar_url)
DChannel.send(TweetText, embed = TwitterEmbed)

DISCORD_TOKEN = 'dtoken'
TWITTER_CONSUMER_KEY = 'ckey'
TWITTER_CONSUMER_SECRET = 'csecret'
TWITTER_ACCESS_TOKEN = 'atoken'
TWITTER_ACCESS_SECRET = 'asecret'

MyBot = commands.Bot(command_prefix='!', description='This is a testing bot')
TwitterAuth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
TwitterAuth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_SECRET)
TweetAPI = tweepy.API(TwitterAuth)
NewListener = TweetListener()
NewStream = tweepy.Stream(auth=TweetAPI.auth, listener=NewListener)
NewStream.filter(follow=['USER IDS HERE'], is_async=True)

@bot.event
async def on_ready():
print(MyBot.user.name,'has successfully logged in ('+str(MyBot.user.id)+')')
print('Ready to respond')

MyBot.run(DISCORD_TOKEN)
channel.send()当我将推文发布到我的测试帐户的时间线时,方法会生成以下消息:
RuntimeWarning: coroutine 'Messageable.send' was never awaited
我明白消息 - channel.send()方法是一种异步方法,但 on_status()事件处理程序是一种同步方法,我不能 await channel.send()on_status() - 但我不知道如何让它工作。我试图制作 on_status()方法一个异步方法:
    async def on_status(self, status):
<same code for checking the tweet and finding the channel>
await DChannel.send(TweetText, embed = TwitterEmbed)
但这总是导致类似的警告:
RuntimeWarning: coroutine 'TweetListener.on_status' was never awaited
if self.on_status(status) is False:
我找到了问题, How do I async on_status from tweepy? 并遵循那里的链接,但我没有看到任何让我知道我的编码错误的任何内容。
通过额外的研究,我还尝试使用来自 asyncio 的一些电话。库进行调用:
    #channel.send(message, embed = TwitterEmbed)
#---ASYNCIO TEST---
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(DChannel.send(embed=TwitterEmbed)))
loop.close()
不幸的是,当它尝试执行 loop=asyncio.get_event_loop() 时,这会导致未处理的异常。指示 There is no current event loop in thread 'Thread-6'. (所以它甚至不会使用 run_until_complete() 方法来查看它是否有效,尽管我在这一点上并不完全乐观)。
我意识到像 MEE6 这样的现有 Discord 机器人已经可以完成我在这里尝试做的事情,但我希望能够让这个机器人成为“我自己的”机器人,同时自学一些 Python 知识。我可能在这里忽略了一些简单的东西,但是我在 API 文档中找不到任何关于 tweepy 的内容。或 discord.py这似乎为我指明了正确的方向,而我的 Google-fu 显然没有那么强。到目前为止,我能找到的所有示例似乎都已过时,因为它们似乎指的是已弃用的方法和任一或两个库的旧版本。还有其他事情我仍然需要弄清楚如何做(例如,让 @TwitterHandle 正确填充嵌入),但我必须让它能够阅读和推送推文,然后我才能担心关于达到这一点。

环境信息
Visual Studio 2017 CE
python 3.6
不和谐.py 1.3.3
tweepy 3.8.0

更新:附加测试
所以,只是为了向自己证明我的 TweetListener类(class)实际上正在工作,我继续在 on_status 中注释掉了与 Discord 的所有交互。方法(从 for Guild in MyBot.guilds 到方法结束的所有内容),然后添加一个简单的 print(TweetText) .我再次运行代码,登录到我为该项目拥有的测试 Twitter 帐户,并发布了更新。检查控制台,它正确输出 status.text我的推文,正如我所料。正如我所想,我在这里遇到的唯一问题是试图 send将文本发送到 Discord。
我也尝试初始化 tweepy.Stream.filter同步模式而不是异步模式 - NewStream.filter(follow=['USER IDS']) .这只会导致我的应用程序在启动时基本上“挂起”。我意识到这是由于它在代码中的位置,所以我移动了 TweetListener 的所有三行初始化到 on_ready事件方法。我将 Discord 代码注释掉并进行了测试,它再次“有效”,因为它打印了 status.text另一个测试推文到控制台。但是,机器人不会响应其他任何事情(我认为仍在“等待”流中)。
即便如此,只是为了看看它是否会有任何不同,我继续取消注释 Discord 交互代码并再次尝试。结果和我最初的一样,只是这次 Discord bot 不会响应 channel 中的事件(代码中的其他地方有几个 super 简单的 @bot.command 声明),这又一次基本上把我带回来了到我有同样问题的原始代码。
我确信有更好的方法来对整个事情进行编码。正如我上面所说的,我现在才开始玩 Python 并且仍在学习语法规则等。即便如此,我仍然不确定我做错了什么和/或忽略了什么阻止我实现我认为是一个相当简单的任务。

更多测试
我回去又发现了一些 asyncio示例并在 on_status 中的 Discord 交互中尝试了另一个迭代:
    loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
result=loop.run_until_complete(DChannel.send(embed=TwitterEmbed))
这次我遇到了与以前不同的未处理异常。错误发生在 run_until_complete当它接收到一条新推文时:
Timeout context manager should be used inside a task
我考虑了这个进展,但我显然还没有完全到位,所以回到谷歌,我在 asgiref 上找到了信息。图书馆及其 sync_to_asyncasync_to_sync方法,所以我想我会尝试一下。
    asgiref.sync.async_to_sync(DChannel.send)(embed=TwitterEmbed)
不幸的是,我遇到了与 asyncio 相同的未处理异常。版本。我觉得我正处于解决这个问题的边缘,但它还没有“点击”。

再来一轮
好的,所以在查找有关 Timeout context manager 的信息之后异常(exception),我正在超越,我偶然发现了另一个 SO 问题,它给了我一丝希望。这个答案在 RuntimeError: Timeout context manager should be used inside a task再次让我回到使用 asyncio并在使用 asyncio.run_coroutine_threadsafe 提供有用的建议之前,简要但描述性地解释 OP 问题背后的原因。方法。查看推荐的代码,这可以帮助我有效地启动同步-> 异步方法通信是有道理的。我实现了建议的更改(为运行机器人的 Thread 对象创建了一个全局变量,添加了一个在该循环中生成机器人的“启动”方法,然后更改了 on_status 中的 Discord 交互以实现所有功能一起。
“好消息”是我在发布推文时不再收到任何错误。此外,测试 bot 命令似乎也能正常工作。坏消息是它仍然没有将消息发送到 channel 。由于它没有产生任何错误,因此无法确定消息的结束位置。

最佳答案

我遇到了和你一样的问题,并从谷歌获得了确切的链接并尝试了所有链接,但正如你所提到的,没有任何效果。

因此,经过大量的尝试和修补后我意识到,我可以将主循环传递给 tweepy 监听器并使用 run_coroutine_threadsafe 执行异步函数。

这是我的代码的要点:

听众:

class EpicListener(tweepy.StreamListener):
def __init__(self, discord, loop, *args, **kwargs):
super().__init__(*args, **kwargs)
self.discord = discord # this is just a function which sends a message to a channel
self.loop = loop # this is the loop of discord client

def on_status(self, status):
self.send_message(status._json)

def send_message(self, msg):
# Submit the coroutine to a given loop
future = asyncio.run_coroutine_threadsafe(self.discord(msg), self.loop)
# Wait for the result with an optional timeout argument
future.result()

不和谐客户端:
class MyClient(discord.Client):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

async def on_ready(self):
myStream = tweepy.Stream(
auth=api.auth, listener=EpicListener(discord=self.sendtwitter, loop=asyncio.get_event_loop())
)
myStream.filter(follow=['mohitwr'], is_async=True)
print(myStream)

希望这可以帮助。

关于python - 使用带有 discord.py 的 tweepy 将推文发布到特定 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61535485/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com