跑步烧瓶&同一应用程序中的Discord bot

时间:2018-02-08 19:09:22

标签: python bots twitch discord.py

我正在使用Python构建Discord bot并希望从Twitch.tv的API接收HTTP请求(请参阅Webhooks Guide& Webhooks Reference)(订阅像X这样的事件; streamer已经上线了,并根据从Twitch收到的HTTP(POST或GET)请求的内容,在Discord bot上做了一些事情,例如:在文本频道上输出消息。

我正在使用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 !'

当我运行看起来像这样的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')

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

如果我要添加" app.run()"同样的问题仍然存在。我的代码中的某个地方(在调用" client.run()"启动Discord bot部分之前)启动Flask服务器;它只是运行烧瓶,卡住它直到我从Flask服务器中按Ctrl + C,然后它继续启动Discord机器人。 最终,我需要使用Discord API,我需要连接到Discord API网关和所有好的爵士乐,以实际将消息发送到机器人的频道,所以我真的不知道该怎么做。

因此。我想我已经尽力解释我最终想要在这里实现的目标,并希望有人可以帮助我找到一种方法来使这个与Flask一起工作,或者是否有更好的和更简单的方法,提供不同的解决方案。

4 个答案:

答案 0 :(得分:3)

这是discord.py中的齿轮示例

我为您可以实现的dbl(Discord Bot列表)制作了这个东西,

注意:使用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()

答案 1 :(得分:2)

另一种很酷的方法是,如果您不打算使用烧瓶扩展名,请使用夸脱代替烧瓶,这对您来说将非常容易。

注意:使用webprocess运行heroku应用

示例: 网址:python main.py

然后继续https://uptimerobot.com/并设置为每5分钟ping您的Web应用

# Code Example
from discord.ext import commands
from quart import Quart
import os
app = Quart(__name__)

bot = commands.Bot('!')

@bot.command()
async def something(ctx):
    ...

"""
Note: On Heroku you cant bind your webserver with 5000 port as they aren't static.

To fix above problem you will have to get dynamic port from the environment variable and you are good to go.

"""

PORT = os.environ.get('PORT')

bot.loop.create_task(app.run_task('0.0.0.0', PORT))

bot.run('Token')

答案 2 :(得分:1)

正如那些评论者告诉我的那样; threading似乎是要走的路。 谢谢你们!

答案 3 :(得分:0)

或者您可以使用终端多路复用器tmux独立运行它们! 如果您在Linux平台上运行,则tmux python3 flaskapp.py将运行flask应用程序,而您可以独立运行discord机器人。