discord.py 如何在用户兑换密钥后存储其ID并实现权限控制
Discord机器人密钥兑换与权限控制实现方案
需求说明
- 用户通过
.redeem <密钥>命令兑换有效密钥后,记录其用户ID - 已兑换用户可使用专属命令,未兑换用户无法访问
- 解决数据存储工具选择问题
现有基础代码
import discord import rstr import random from discord.ext import commands intents = discord.Intents.all() bot = commands.Bot(command_prefix=".", intents=intents, help_command=None) list_keys = [rstr.xeger(r'[a-zA-Z\d]{25}') for x in range(10)] @bot.listen() async def on_ready(): print('ready') @bot.command() async def redeem(ctx, key): if key in list_keys: embed=discord.Embed(title="Demon V2", description=f"Claimed the key ! \n Happy Bloxfliping , If commands arent working dm scooby#0001 (no caps)") embed.set_thumbnail(url="https://media.discordapp.net/attachments/860177535010603028/1010881302678999140/PP4Y_756.gif") embed.set_footer(text="#8k.HITTAS | scooby#0001") await ctx.send(embed=embed) else: embed=discord.Embed(title="Demon V2", description="Invalid Key.", color=0x980de3) embed.set_thumbnail(url="https://media.discordapp.net/attachments/860177535010603028/1010881302678999140/PP4Y_756.gif") embed.set_footer(text="#8k.HITTAS | buy keys from scooby#0001") await ctx.send(embed=embed) @bot.command() async def printkeys(ctx): for key in list_keys: print(key) bot.run('my token')
数据存储工具选择
根据你的机器人规模,推荐两种方案:
- JSON文件:适合小型机器人,无需额外依赖,读写简单,直接用Python内置的
json模块操作 - SQLite:Python内置的轻量数据库,适合数据量稍大的场景,支持更灵活的查询和数据管理
下面以JSON文件为例,给出完整实现代码:
完整功能实现代码
import discord import rstr import random import json import os from discord.ext import commands intents = discord.Intents.all() bot = commands.Bot(command_prefix=".", intents=intents, help_command=None) # 数据文件路径 DATA_FILE = "bot_data.json" # 初始化数据结构 def init_data(): if not os.path.exists(DATA_FILE): with open(DATA_FILE, "w") as f: json.dump({ "used_keys": [], "premium_users": [] }, f) # 读取数据 def load_data(): with open(DATA_FILE, "r") as f: return json.load(f) # 保存数据 def save_data(data): with open(DATA_FILE, "w") as f: json.dump(data, f, indent=4) # 生成初始密钥(仅第一次运行需要,之后可以注释掉) # list_keys = [rstr.xeger(r'[a-zA-Z\d]{25}') for x in range(10)] # print("Generated keys:", list_keys) @bot.listen() async def on_ready(): init_data() print('Bot is ready!') # 自定义检查:验证用户是否为已兑换用户 def is_premium(): def predicate(ctx): data = load_data() return str(ctx.author.id) in data["premium_users"] return commands.check(predicate) @bot.command() async def redeem(ctx, key): data = load_data() # 这里替换成你实际的有效密钥列表,建议单独存储未使用的密钥 valid_unused_keys = [k for k in ["生成的密钥1", "生成的密钥2"] if k not in data["used_keys"]] if key in valid_unused_keys: # 标记密钥已使用 data["used_keys"].append(key) # 添加用户到付费列表 user_id = str(ctx.author.id) if user_id not in data["premium_users"]: data["premium_users"].append(user_id) save_data(data) embed=discord.Embed(title="Demon V2", description=f"Claimed the key ! \n Happy Bloxfliping , If commands arent working dm scooby#0001 (no caps)") embed.set_thumbnail(url="https://media.discordapp.net/attachments/860177535010603028/1010881302678999140/PP4Y_756.gif") embed.set_footer(text="#8k.HITTAS | scooby#0001") await ctx.send(embed=embed) else: embed=discord.Embed(title="Demon V2", description="Invalid or already used Key.", color=0x980de3) embed.set_thumbnail(url="https://media.discordapp.net/attachments/860177535010603028/1010881302678999140/PP4Y_756.gif") embed.set_footer(text="#8k.HITTAS | buy keys from scooby#0001") await ctx.send(embed=embed) # 专属命令示例:只有已兑换用户能使用 @bot.command() @is_premium() async def premium_cmd(ctx): await ctx.send(f"Hello {ctx.author.mention}! This is a premium-only command.") # 处理无权限的情况 @premium_cmd.error async def premium_cmd_error(ctx, error): if isinstance(error, commands.CheckFailure): await ctx.send("You need to redeem a valid key to use this command!") @bot.command() async def printkeys(ctx): # 示例生成密钥,实际建议读取未使用的密钥列表 list_keys = [rstr.xeger(r'[a-zA-Z\d]{25}') for x in range(10)] for key in list_keys: print(key) await ctx.send("Keys printed to console!") bot.run('your_bot_token_here')
关键功能说明
- 数据持久化:通过JSON文件存储已使用的密钥和付费用户ID,机器人重启后数据不会丢失
- 密钥防重复兑换:每次兑换后将密钥标记为已使用,避免同一密钥被多次兑换
- 权限控制:自定义
is_premium检查器,用装饰器给专属命令添加权限验证,未达标用户会触发错误提示 - 错误处理:针对专属命令的权限错误,给出明确提示
内容的提问来源于stack exchange,提问作者Scooby
相关产品推荐
相关产品推荐

