Discord Botでエラーが発生したときにコンソールをわざわざ見に行くの、めんどくさいですよね?
エラーが発生したときにユーザーにその旨を通知したいですよね?
IDを振って管理したいですよね?
それならコーデディングだ!
しくみ
エラー発生時
- on_command_errorでエラーを拾う
- そのエラーに関する情報を専用のチャンネルに送信する
- そのメッセージのIDを36進数に変換
- 変換したIDをつけてエラー情報を実行者に返す
エラー情報取得時
- 36進数のIDを10進数に直す
- 直したIDを用いてエラー情報を取得し、そのメッセージのembedをそのまま送信する
こんな感じで。
れっつこーでぃんぐ!
numpyとtracebackをインポートしておいてください。
@bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
await ctx.send(discord.Embed(title="エラーが発生しました", description="そのコマンドは見つかりませんでした。ごめんなさい。"))
elif isinstance(error, commands.NotOwner):
await ctx.send(discord.Embed(title="エラーが発生しました", description="そのコマンドは見つかりませんでした。ごめんなさい。")) # 私は隠したいから..
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(discord.Embed(title="エラーが発生しました", description="パラメータが不足しています。ヘルプコマンドなどで確認してください。"))
elif isinstance(error, commands.CommandOnCooldown):
await ctx.send(discord.Embed(title="エラーが発生しました", description=f"現在クールダウン中です...\nあと{error.retry_after}秒後に再試行してください。"))
else:
ch = 123456789 # エラー情報を送信するチャンネル
embed = discord.Embed(title="エラー情報", description="")
embed.add_field(name="エラー発生サーバー名", value=ctx.guild.name, inline=False)
embed.add_field(name="エラー発生サーバーID", value=ctx.guild.id, inline=False)
embed.add_field(name="エラー発生ユーザー名", value=ctx.author.name, inline=False)
embed.add_field(name="エラー発生ユーザーID", value=ctx.author.id, inline=False)
embed.add_field(name="エラー発生コマンド", value=ctx.message.content, inline=False)
t = f"```py\n{''.join(traceback.TracebackException.from_exception(error))}```"
embed.add_field(name="発生エラー", value=t if len(t < 2048) else f"```py\n{error}\n```", inline=False)
m = await bot.get_channel(ch).send(embed=embed)
await ctx.send(discord.Embed(title="エラーが発生しました", description="何らかのエラーが発生しました。ごめんなさい。\nこのエラーについて問い合わせるときは下記のエラーIDも一緒にお知らせください").set_footer(text=numpy.base_repr(m.id), 36))
@bot.command()
@commands.is_owner()
async def get_error(ctx, error_id):
await ctx.send(embed=(await bot.get_channel(123456789).fetch_message(int(error_id, 36))).embeds[0])
もし、以前書いた記事と共存させたい場合、
await ctx.send(discord.Embed(title="エラーが発生しました", description="何らかのエラーが発生しました。ごめんなさい。\nこのエラーについて問い合わせるときは下記のエラーIDも一緒にお知らせください").set_footer(text="A" + numpy.base_repr(m.id), 36))
例えばこのようにIDの前にAをつけて区別します。
await ctx.send(embed=(await bot.get_channel(123456789).fetch_message(int(error_id[1:], 36) if error_id.startswith("A") else int(error_id))).embeds[0])
情報を取得するときはIDがAから始まっていればAを削除したIDを10進数に変換し、Aから始まっていなければ単純にint型に変換してメッセージを取得します。
p.s.
以前書いた記事が今見るとちょっと初心者の方などに申し訳ないなという記事だったのでこの記事を書きました。
だけど、ちょっと難易度上がってしまった...かも?