Discord.py 重写 Modmail 系统
Discord.py rewrite Modmail System
几乎我正在尝试为服务器制作一个 modmail 机器人。这是代码。
@client.event
async def on_message(message):
modmail_channel = discord.utils.get(client.get_all_channels(), name="bot-log")
if message.author == client.user:
return
if str(message.channel.type) == "private":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='Report a member:', value=f"React with 1️⃣ if you want to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with 2️⃣ if you want to report a Staff Member.")
embed.add_field(name='Warn Appeal:', value=f"React with 3️⃣ if you would like to appeal a warning.")
embed.add_field(name='Question:', value=f"React with 4️⃣ if you have a question about our moderation system or the server rules.")
embed.set_footer(text="Olympia Gaming | Modmail")
msg = await message.author.send(embed=embed)
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["1️⃣", "2️⃣", "3️⃣", "4️⃣"]
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "1️⃣":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='How to Report:', value="Send the ID of the person you are reporting and attach add a screen shot of them breaking a rule (can be ToS or a server rule).")
embed.set_footer(text="Olympia Gaming | Report a member ")
await message.author.send(embed=embed)
message, user = await client.wait_for("on_message", timeout=60, check=check)
embed = discord.Embed(title=f"{message.content}", color=0x00FFFF)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.delete()
break
此代码的唯一问题是它不会将邮件发送到 modmail 频道,并且会不断重复原始邮件。谁能解释一下我该如何解决这个问题?
我有几个建议给你。
首先,我强烈建议将以下内容作为您 on_message
中的第一条语句:
if message.guild:
return
这将取代您的 if str(message.channel.type) == "private":
,并确保立即丢弃任何未在 DM 中发送的消息。
其次,我建议使用 get_channel 而不是您的 discord.utils.get(client.get_all_channels(), name="bot-log")
,它将搜索您的机器人所在的每个频道,直到找到名称为 bot-log
的频道。这是低效的。
现在,您的机器人每次都会发送初始消息的原因是因为每次向机器人发送消息时都会调用主on_message
。您将需要跟踪哪些用户已经发送了初始消息,这样您就不会再次发送它。最简单的实现就是将用户 ID 添加到一个列表,然后在主 on_message
.
中检查该列表
此外,你的第二个 wait_for
将不起作用,它应该只是“消息”,你正在使用你的第一个检查功能,它正在寻找反应。
一下子说了很多,所以这里是我的完整 on_message
所有更改,希望你不要只是复制粘贴它而不学任何东西:
sent_users = []
@client.event
async def on_message(message):
if message.guild: # ensure the channel is a DM
return
if message.author == client.user:
return
if message.author.id in sent_users: # Ensure the intial message hasn't been sent before
return
modmail_channel = client.get_channel(CHANNEL_ID)
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='Report a member:', value=f"React with 1️⃣ if you want to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with 2️⃣ if you want to report a Staff Member.")
embed.add_field(name='Warn Appeal:', value=f"React with 3️⃣ if you would like to appeal a warning.")
embed.add_field(name='Question:', value=f"React with 4️⃣ if you have a question about our moderation system or the server rules.")
embed.set_footer(text="Olympia Gaming | Modmail")
msg = await message.author.send(embed=embed)
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
sent_users.append(message.author.id) # add this user to the list of sent users
try:
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["1️⃣", "2️⃣", "3️⃣", "4️⃣"]
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "1️⃣":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='How to Report:', value="Send the ID of the person you are reporting and attach add a screen shot of them breaking a rule (can be ToS or a server rule).")
embed.set_footer(text="Olympia Gaming | Report a member ")
await message.author.send(embed=embed)
message = await client.wait_for("message", timeout=60, check=lambda m: m.channel == message.channel and m.author == message.author)
embed = discord.Embed(title=f"{message.content}", color=0x00FFFF)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.delete()
几乎我正在尝试为服务器制作一个 modmail 机器人。这是代码。
@client.event
async def on_message(message):
modmail_channel = discord.utils.get(client.get_all_channels(), name="bot-log")
if message.author == client.user:
return
if str(message.channel.type) == "private":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='Report a member:', value=f"React with 1️⃣ if you want to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with 2️⃣ if you want to report a Staff Member.")
embed.add_field(name='Warn Appeal:', value=f"React with 3️⃣ if you would like to appeal a warning.")
embed.add_field(name='Question:', value=f"React with 4️⃣ if you have a question about our moderation system or the server rules.")
embed.set_footer(text="Olympia Gaming | Modmail")
msg = await message.author.send(embed=embed)
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["1️⃣", "2️⃣", "3️⃣", "4️⃣"]
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "1️⃣":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='How to Report:', value="Send the ID of the person you are reporting and attach add a screen shot of them breaking a rule (can be ToS or a server rule).")
embed.set_footer(text="Olympia Gaming | Report a member ")
await message.author.send(embed=embed)
message, user = await client.wait_for("on_message", timeout=60, check=check)
embed = discord.Embed(title=f"{message.content}", color=0x00FFFF)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.delete()
break
此代码的唯一问题是它不会将邮件发送到 modmail 频道,并且会不断重复原始邮件。谁能解释一下我该如何解决这个问题?
我有几个建议给你。
首先,我强烈建议将以下内容作为您 on_message
中的第一条语句:
if message.guild:
return
这将取代您的 if str(message.channel.type) == "private":
,并确保立即丢弃任何未在 DM 中发送的消息。
其次,我建议使用 get_channel 而不是您的 discord.utils.get(client.get_all_channels(), name="bot-log")
,它将搜索您的机器人所在的每个频道,直到找到名称为 bot-log
的频道。这是低效的。
现在,您的机器人每次都会发送初始消息的原因是因为每次向机器人发送消息时都会调用主on_message
。您将需要跟踪哪些用户已经发送了初始消息,这样您就不会再次发送它。最简单的实现就是将用户 ID 添加到一个列表,然后在主 on_message
.
此外,你的第二个 wait_for
将不起作用,它应该只是“消息”,你正在使用你的第一个检查功能,它正在寻找反应。
一下子说了很多,所以这里是我的完整 on_message
所有更改,希望你不要只是复制粘贴它而不学任何东西:
sent_users = []
@client.event
async def on_message(message):
if message.guild: # ensure the channel is a DM
return
if message.author == client.user:
return
if message.author.id in sent_users: # Ensure the intial message hasn't been sent before
return
modmail_channel = client.get_channel(CHANNEL_ID)
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='Report a member:', value=f"React with 1️⃣ if you want to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with 2️⃣ if you want to report a Staff Member.")
embed.add_field(name='Warn Appeal:', value=f"React with 3️⃣ if you would like to appeal a warning.")
embed.add_field(name='Question:', value=f"React with 4️⃣ if you have a question about our moderation system or the server rules.")
embed.set_footer(text="Olympia Gaming | Modmail")
msg = await message.author.send(embed=embed)
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
sent_users.append(message.author.id) # add this user to the list of sent users
try:
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["1️⃣", "2️⃣", "3️⃣", "4️⃣"]
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "1️⃣":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Olympia Gaming Modmail System", icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='How to Report:', value="Send the ID of the person you are reporting and attach add a screen shot of them breaking a rule (can be ToS or a server rule).")
embed.set_footer(text="Olympia Gaming | Report a member ")
await message.author.send(embed=embed)
message = await client.wait_for("message", timeout=60, check=lambda m: m.channel == message.channel and m.author == message.author)
embed = discord.Embed(title=f"{message.content}", color=0x00FFFF)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.delete()