discord.py如何实现自定义欢迎消息变量自动转换为用户提及
问题描述
我正在开发discord.py的欢迎模块,希望让自定义欢迎消息中的{member_mention}自动转换为新加入服务器用户的提及(@用户)。目前发送消息时只会保留{member_mention}文本,无法转换为实际用户提及。我需要的是自定义变量替换功能,而非直接使用member.mention,参考Dyno等热门机器人的类似功能,询问具体实现方法。
当前代码
@bot.event async def on_member_join(member): try: with open("database\\database_main\\serverdb.json", encoding="utf-8") as f: data = json.load(f) if str(member.guild.id) in data: logera = data[str(member.guild.id)]['log_joinlogs'] if logera == 0: with open("database\\database_main\\serverdb.json", encoding="utf-8") as f: data = json.load(f) if str(member.guild.id) in data: isenabled = data[str(member.guild.id)]['logchlID'] if isenabled == 0: return else: creation = member.created_at.strftime("%a %#d %B %Y, %I:%M %p") channelrs = bot.get_channel(data[str(member.guild.id)]['logchlID']) embed = discord.Embed(title=f"Member Joined", color=discord.Colour.green()) embed.add_field(name="Account Creation Date", value=f"{creation}") embed.set_footer(text=f"User ID: {member.id}") embed.set_author(name=f"{member.display_name} (@{member.name})", icon_url=member.avatar) await channelrs.send(embed=embed) else: return except: return with open("database\\database_main\\serverdb.json", encoding="utf-8") as f: datar = json.load(f) welcomemodule = datar[str(member.guild.id)]['welcome_module'] if welcomemodule == 0: welcomemessage = datar[str(member.guild.id)]['welcome_message'] if welcomemessage == "": print("welcom message no?") return else: welcoa = datar[str(member.guild.id)]['welcome_chl_id'] if welcoa == 0: return else: member_mention = member.mention welcomechl = bot.get_channel(datar[str(member.guild.id)]['welcome_chl_id']) await welcomechl.send(f"{welcomemessage}")
JSON配置文件
{ "1141583283403116574": { "level_module": 0, "moderation_module": 0, "lvlupID": 1173294414303600771, "xpaddition": 0, "logchlID": 1161019161531662466, "log_joinlogs": 0, "log_leavelogs": 0, "log_banlogs": 1, "log_deletemsglogs": 0, "fun_module": 0, "log_editedmsglogs": 0, "welcome_module": 0, "welcome_message": "hi **{member_mention}!!!**", "svrid": "phmouGp", "welcome_chl_id": 1165505902841962588, "welcome_dm_message": "hi" } }
解决方案
核心思路是将配置中的占位符替换为对应用户/服务器的实际数据,以下是三种可行实现方式:
方法1:字符串替换(基础版)
直接用replace()方法逐个替换占位符,适合变量较少的场景:
# 定义占位符与实际值的映射 variable_map = { "{member_mention}": member.mention, "{member_name}": member.name, "{server_name}": member.guild.name } # 替换所有占位符 formatted_msg = welcomemessage for placeholder, value in variable_map.items(): formatted_msg = formatted_msg.replace(placeholder, value) await welcomechl.send(formatted_msg)
方法2:str.format()(简洁扩展版)
利用Python内置的字符串格式化功能,占位符需与format()参数名匹配,扩展性更强:
formatted_msg = welcomemessage.format( member_mention=member.mention, member_name=member.name, member_display_name=member.display_name, server_name=member.guild.name, member_id=member.id ) await welcomechl.send(formatted_msg)
方法3:正则表达式替换(灵活匹配版)
适合需要动态识别大量占位符的场景,通过正则匹配所有{xxx}格式的占位符:
import re # 匹配所有{xxx}格式的占位符 pattern = re.compile(r"\{(\w+)\}") def replace_match(match): key = match.group(1) # 根据占位符返回对应值 match_dict = { "member_mention": member.mention, "member_name": member.name, "server_name": member.guild.name } return match_dict.get(key, match.group(0)) # 找不到则保留原占位符 formatted_msg = pattern.sub(replace_match, welcomemessage) await welcomechl.send(formatted_msg)
完整修改后的代码片段
以方法2为例,修改后的欢迎消息发送逻辑:
with open("database\\database_main\\serverdb.json", encoding="utf-8") as f: datar = json.load(f) welcomemodule = datar[str(member.guild.id)]['welcome_module'] if welcomemodule == 0: welcomemessage = datar[str(member.guild.id)]['welcome_message'] if welcomemessage == "": print("welcom message no?") return else: welcoa = datar[str(member.guild.id)]['welcome_chl_id'] if welcoa == 0: return else: # 格式化欢迎消息 formatted_msg = welcomemessage.format( member_mention=member.mention, member_name=member.name, member_display_name=member.display_name, server_name=member.guild.name ) welcomechl = bot.get_channel(datar[str(member.guild.id)]['welcome_chl_id']) await welcomechl.send(formatted_msg)
注意事项
- 确保JSON配置中的占位符名称与代码中
format()的参数名完全一致 - 可根据需求扩展更多变量,比如用户ID、服务器成员总数等
- 建议添加异常捕获,避免因未知占位符导致的格式化错误
内容的提问来源于stack exchange,提问作者As2Bax
相关产品推荐
相关产品推荐

