You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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')

关键功能说明

  1. 数据持久化:通过JSON文件存储已使用的密钥和付费用户ID,机器人重启后数据不会丢失
  2. 密钥防重复兑换:每次兑换后将密钥标记为已使用,避免同一密钥被多次兑换
  3. 权限控制:自定义is_premium检查器,用装饰器给专属命令添加权限验证,未达标用户会触发错误提示
  4. 错误处理:针对专属命令的权限错误,给出明确提示

内容的提问来源于stack exchange,提问作者Scooby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:35:22