在同一个应用程序中运行 Flask 和 Discord 机器人

Hax*_*201 10 python bots twitch discord.py

我正在用 Python 构建一个 Discord 机器人,并希望从 Twitch.tv 的 API(请参阅Webhooks 指南Webhooks 参考)接收 HTTP 请求(订阅事件,例如 X 流媒体已经上线)并基于 HTTP 的内容( POST 或 GET)从 Twitch 收到的请求,在 Discord 机器人上做一些事情,例如:在文本频道上输出一条消息。

我正在使用discord.py Python Discord API/Library。

我调查了这个问题,发现Flask似乎是一个很好的极简主义选择,让网络服务器接收这些请求。

我应该先说我对 Python 非常陌生,而且我以前从未使用过 Flask。

现在。问题是我似乎无法找到在我的不和谐机器人内部运行 Flask 服务器的方法。

我尝试将这个简单的代码添加到我的 discord.py 脚本中:

from flask import Flask, request
app = Flask(__name__)
@app.route('/posts', methods=['POST'])
def result():
    print(request.form['sched'])
    # Send a message to a discord text channel etc...
    return 'Received !'
Run Code Online (Sandbox Code Playgroud)

当我运行我的 discord.py 脚本时,它看起来像这样:( 为了保持简短,去掉了一些命令和功能)

import discord
import asyncio

from flask import Flask, request
app = Flask(__name__)
@app.route('/posts', methods=['POST'])
def result():
    print(request.form['sched'])
    # Send a message to a discord text channel etc...
    return 'Received !'

client = discord.Client()

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

@client.event
async def on_message(message):

    if message.author == client.user:
        return

    content = message.content
    fullUser = message.author.name+'#'+message.author.discriminator
    print(str(message.timestamp)+" #"+message.channel.name+" "+fullUser+": "+str(content.encode('ascii', 'ignore').decode('ascii')))
    if content.startswith('!'):

        content = content[1:]
        if content.startswith('test'):
            counter = 0
            tmp = await client.send_message(message.channel, 'Calculating messages...')
            async for log in client.logs_from(message.channel, limit=100):
                if log.author == message.author:
                    counter += 1

            await client.edit_message(tmp, 'You have {} messages.'.format(counter))

client.run('MyTokenHere')
Run Code Online (Sandbox Code Playgroud)

似乎如果我将flask指向discord.py(上面的)并运行它,它将启动代码,进入discord的“client.run('MyTokenHere')”部分,然后停止并运行不和谐机器人。直到我通过执行 Ctrl+C 退出机器人,实际的 Flask 服务器才启动,但现在不和谐机器人已断开连接,不再进行任何处理。

例如,如果我要在代码中的某处添加“app.run()”(在调用启动 Discord bot 部分的“client.run()”之前)以启动 Flask 服务器,同样的问题仍然存在;它只会运行 Flask,在我按 Ctrl+C 离开 Flask 服务器之前卡住它,然后它会继续启动 Discord 机器人。最终,我需要使用 Discord API,我需要连接到 Discord API 网关和所有优秀的爵士乐才能使用机器人将消息实际发送到通道,所以我真的不知道在这里做什么。

所以。我想我已经尽力解释了我最终要在这里实现的目标,希望有人能帮助我找到一种方法来使用 Flask 进行这项工作,或者如果有更好更简单的方法,请提供不同的解决方案.

Wip*_*erR 6

这是 discord.py 中的 cog 示例

我为 dbl(Discord Bot Lists)制作了这个东西,你可以实现,你需要的东西。

注意:使用 webprocess 运行你的 heroku 应用程序

示例:
网络:python main.py

然后访问https://uptimerobot.com/ 并设置为每 5 分钟 ping 您的 Web 应用程序

from aiohttp import web
from discord.ext import commands, tasks
import discord
import os
import aiohttp

app = web.Application()
routes = web.RouteTableDef()


def setup(bot):
    bot.add_cog(Webserver(bot))


class Webserver(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.web_server.start()

        @routes.get('/')
        async def welcome(request):
            return web.Response(text="Hello, world")

        @routes.post('/dbl')
        async def dblwebhook(request):
            if request.headers.get('authorization') == '3mErTJMYFt':
                data = await request.json()
                user = self.bot.get_user(data['user']) or await self.bot.fetch_user(data['user'])
                if user is None:
                    return
                _type = f'Tested!' if data['type'] == 'test' else f'Voted!'
                upvoted_bot = f'<@{data["bot"]}>'
                embed = discord.Embed(title=_type, colour=discord.Color.blurple())
                embed.description = f'**Upvoter :** {user.mention} Just {_type}' + f'\n**Upvoted Bot :** {upvoted_bot}'
                embed.set_thumbnail(url=user.avatar_url)
                channel = self.bot.get_channel(5645646545142312312)
                await channel.send(embed=embed)
            return 200

        self.webserver_port = os.environ.get('PORT', 5000)
        app.add_routes(routes)

    @tasks.loop()
    async def web_server(self):
        runner = web.AppRunner(app)
        await runner.setup()
        site = web.TCPSite(runner, host='0.0.0.0', port=self.webserver_port)
        await site.start()

    @web_server.before_loop
    async def web_server_before_loop(self):
        await self.bot.wait_until_ready()
Run Code Online (Sandbox Code Playgroud)


Hax*_*201 5

正如好心的评论者告诉我的那样;线程似乎是要走的路。谢谢你们!

  • 你在烧瓶或机器人上做了线程吗? (3认同)