I am looking for a way to integrate a REST API inside my Discord.py
, using the rewrite branch. I want to use aiohttp
to handle requests but I am unsure of which approach I should take. The objective is to make for example a GET request to the API that would return a list of guilds the bot is in. Or as another example, a POST request that would ask the bot to write a given message into a specific channel. Overall it's about giving instruction to the bot from a webpage.
I tried putting the aiohttp app router and runner inside my Discord.py client class. The web server is indeed running, I made an async function to return guilds the bot is in, but it looks like the function won't take the request argument I pass to it when going to http://127.0.0.1/guilds
. Thus leading to a missing 1 required positional argument
error.
import discord
import asyncio
from aiohttp import web
class MyClient(discord.Client):
async def on_ready(self):
print('Logged on as {0}!'.format(self.user))
async def get_guilds(self, request):
response_obj = self.guilds
return web.json_response(response_obj,status=200,content_type='application/json')
app = web.Application()
app.router.add_get('/guilds', get_guilds)
web.run_app(app, port=80)
client = MyClient()
client.run(TOKEN)
Besides, the aiohttp server does not run asynchronously. I expect the on_ready(self)
to run, but it never does. What am I doing wrong ?
Well I found a way.
from asyncio import gather, get_event_loop
from logging import basicConfig, INFO
from discord.ext.commands import Bot
from aiohttp.web import AppRunner, Application, TCPSite
from sys import argv
from api import routes
basicConfig(level=INFO)
async def run_bot():
app = Application()
app.add_routes(routes)
runner = AppRunner(app)
await runner.setup()
site = TCPSite(runner, '0.0.0.0', 8080)
await site.start()
bot = Bot(command_prefix="$")
app['bot'] = bot
try:
await bot.start(TOKEN)
except:
bot.close(),
raise
finally:
await runner.cleanup()
if __name__ == '__main__':
loop = get_event_loop()
loop.run_until_complete(run_bot())
routes = RouteTableDef()
@routes.get('/guilds')
async def get_guilds(request):
client = request.app['bot']
guilds = []
for guild in client.guilds:
guilds.append(guild.id)
response = Handler.success(guilds)
return json_response(response, status=200, content_type='application/json')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With