我有一个 discord.py
机器人来访问 Politics & 的 API战争,我有一个线程每 20 分钟检查一次以检查新活动.我已经尝试将这部分放在 on_ready
中,但这似乎会停止执行任何命令,所以我不得不创建一个线程.但是,当我尝试运行此代码并且有新活动要发送消息时,它会引发 RuntimeError:
I have a discord.py
bot to access the API for Politics & War, and I have a thread to check every 20 minutes to check for new activity. I have tried putting this part in on_ready
, but this seems to stop the execution of any commands, so I had to create a thread. However, when I try to run this code, and there is new activity to send a message about, it raises a RuntimeError:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:Users
aturAppDataLocalProgramsPythonPython38lib hreading.py", line 932, in _bootstrap_inner
self.run()
File "C:Users
aturAppDataLocalProgramsPythonPython38lib hreading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/natur/Desktop/Trans-Atlantic-Bot/BOT/main.py", line 100, in update
asyncio.run(update_war())
File "C:Users
aturAppDataLocalProgramsPythonPython38libasyncio
unners.py", line 44, in run
return loop.run_until_complete(main)
File "C:Users
aturAppDataLocalProgramsPythonPython38libasyncioase_events.py", line 616, in run_until_complete
return future.result()
File "C:/Users/natur/Desktop/Trans-Atlantic-Bot/BOT/main.py", line 61, in update_war
defense_channel = await client.fetch_channel(CHANNEL_1)
File "C:Users
aturAppDataLocalProgramsPythonPython38libsite-packagesdiscordclient.py", line 1447, in fetch_channel
data = await self.http.get_channel(channel_id)
File "C:Users
aturAppDataLocalProgramsPythonPython38libsite-packagesdiscordhttp.py", line 185, in request
async with self.__session.request(method, url, **kwargs) as r:
File "C:Users
aturAppDataLocalProgramsPythonPython38libsite-packagesaiohttpclient.py", line 1012, in __aenter__
self._resp = await self._coro
File "C:Users
aturAppDataLocalProgramsPythonPython38libsite-packagesaiohttpclient.py", line 426, in _request
with timer:
File "C:Users
aturAppDataLocalProgramsPythonPython38libsite-packagesaiohttphelpers.py", line 579, in __enter__
raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task
import os
import time
import json
import difflib
import datetime
import asyncio
import threading
import requests
import discord
from discord.ext import commands
TOKEN = os.environ.get("TRANSATLANTICBOT")
KEY = os.environ.get("PNWKEY")
command_dict = {
"help": "Lists the commands and their descriptions",
"help_commands": "ALIAS: help",
"city": "Gets information about the specified city. URL and ID are both accepted.",
}
def req(loc, key_provider=None):
if key_provider is not None:
return requests.get(f"https://politicsandwar.com/api/{loc}{key_provider}key={KEY}").json()
if "=" in loc:
return requests.get(f"https://politicsandwar.com/api/{loc}&key={KEY}").json()
else:
return requests.get(f"https://politicsandwar.com/api/{loc}/?key={KEY}").json()
def dict_to_string(d):
newline = "
"
return f'```yml
{newline.join((f"{key}: {value}" for key, value in d.items()))}
```'
async def get_nation(ctx, n_id):
if not n_id.isdigit():
if n_id.startswith("http"):
n_id = n_id[n_id.find("=") + 1].rstrip("/")
else:
pass
return n_id
# update
async def update_war():
start_time = time.time()
print("
WAR")
print(f"Update Started - 0 secs")
new = req("wars?alliance_id=7536")
print(f"Recieved Data - {time.time() - start_time} secs")
if "success" in new.keys():
lastcheck = datetime.datetime.utcnow() - datetime.timedelta(hours=0, minutes=21)
wars = new["wars"]
war_time = datetime.datetime.strptime(wars[0]["date"][:19], "%Y-%m-%dT%X")
war = 0
while war_time >= lastcheck:
current_war = wars[war]
war_time = datetime.datetime.strptime(wars[war + 1]["date"][:19], "%Y-%m-%dT%X")
if current_war["attackerAA"] in ("Atlantian Council", "Atlantian Council Applicant"):
defense_channel = await client.fetch_channel(CHANNEL_1)
else:
defense_channel = await client.fetch_channel(CHANNEL_2)
spec_war = req(f"war/{current_war['warID']}", "/&")
emb = discord.Embed(
title="WAR REPORT",
description=dict_to_string(spec_war),
color=discord.Color(0x00ff00)
)
emb.set_footer(text=f"P&W bot for ANYONE, unlike SOME OTHER BOT - Requested by The Atlantian Council")
await defense_channel.send(embed=emb)
war += 1
print(f"Update Success - {time.time() - start_time} secs")
else:
print(f"Upate Failure - {time.time() - start_time} secs")
print(f"Waiting for next update - {time.time() - start_time} secs")
async def update_nations():
start_time = time.time()
print("
NATION")
print(f"Update Started - 0 secs")
with open("all_nations.json", "w") as nations:
new = req("nations")
print(f"Recieved Data - {time.time() - start_time} secs")
if "success" in new.keys():
json.dump(new, nations)
print(f"Update Success - {time.time() - start_time} secs")
else:
print(f"Upate Failure - {time.time() - start_time} secs")
print(f"Waiting for next update - {time.time() - start_time} secs")
def update():
while True:
try:
asyncio.run(update_war())
asyncio.run(update_nations())
except Exception as e:
print("
ERROR HAPPENED
")
print(e)
time.sleep(60 * 20)
updater = threading.Thread(target=update, daemon=True)
# run bot
client = commands.Bot(command_prefix=("^", "!", "also,
", "also, ", "tst!"))
client.remove_command("help")
@client.event
async def on_ready():
await client.change_presence(
status=discord.Status.online,
activity=discord.Game(name="P&W")
)
print("BOT READY")
updater.start()
async def start():
await bot.wait_until_ready()
# Whatever function you want
bot.loop.create_task(start())
这篇关于从线程内部发送消息时出现discord.py错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!