【问题标题】:How can I make my discord bot respond to the correct answer?如何让我的不和谐机器人响应正确答案?
【发布时间】:2020-01-03 07:30:43
【问题描述】:

我正在编写一个机器人,它会在我的不和谐频道中提出一个琐事问题。我已经重写了几次,但无法让它接受答案。 我可能错过了一些可怕的东西。

我的代码:

# bot.py
import os
import json
import discord
from discord.ext import commands
import requests

token=('*removed*')
bot = commands.Bot(command_prefix ='??')
os.chdir(r'C:\Users\thund\OneDrive\Documenten\Python programmeren\Discord - bot')
correct_answer = ''

@bot.event
async def on_ready():
    print(f'{bot.user} has connected to Discord!')

@bot.event
async def on_member_join(member):

    with open('users.json', 'r') as f:
            users = json.load(f)
    await update_data(users, member)

    with open('users.json', 'w') as f:
            json.dump(users, f)

    await member.create_dm()
    await member.dm_channel.send(
        f'Hello {member.name}, You have joined a Discord server where the Mr. Questionnaire is active!\n')
    await member.dm_channel.send(
        f'By default you will get questions which you can answer by preceding your answer by ??')
    await member.dm_channel.send(
        f'There are different prices you can win, try answering some questions and find out!')

@bot.command()       
async def start(ctx):
    global correct_answer
    explanation = (
            'So you want to play a game? We will ask questions, the first one to answer wins one point\n'
            'I will keep firing questions, untill someone types ??stopplease'
            )
    await ctx.send(explanation)
    r = requests.get (url = 'https://opentdb.com/api.php?amount=1')
    data = r.json()
    category = data['results'][0]['category']
    difficulty = data['results'][0]['difficulty']
    question = data['results'][0]['question']
    answer = data['results'][0]['correct_answer']
    correct_answer = answer.replace(' ','_')
    await ctx.send('Category: %s\nDifficulty: %s\nQuestion: %s\n'
                    % (category, difficulty, question))

@bot.command()
async def correct(ctx):
    global correct_answer
    with open('users.json', 'r') as f:
        users = json.load(f)       
    await update_data(users, ctx.author)
    await add_experience(users, ctx.author, 10)
    await level_up(users, ctx.author, ctx.channel)
    with open('users.json', 'w') as f:
       json.dump(users, f)
    await ctx.send('{} has guessed correctly!'.format(ctx.author))
    bot.command('start')

async def update_data(users, user):
    if not user.id in users:
        users[user.id] = {}
        users[user.id]['experience'] = 0
        users[user.id]['level'] = 1

async def add_experience(users, user, exp):
    users[user.id]['experience'] += exp

async def level_up(users, user, channel):
    experience = users[user.id]['experience']
    lvl_start = users[user.id]['level']
    lvl_end = int(experience ** (1/4))

    if lvl_start < lvl_end:
        await ctx.send(channel, '{} has leveled up to level {}'.format(user.mention, lvl_end))
        users[user.id]['level'] = lvl_end

@bot.command(name='supersecret')
async def answer(ctx):
    global correct_answer
    await ctx.send('The Answer is: %s' % (correct_answer))

@bot.command(name='%s' % (correct_answer))
async def correct22(ctx):
        global correct_answer
        with open('users.json', 'r') as f:
            users = json.load(f)       
        await update_data(users, message.author)
        await add_experience(users, message.author, 10)
        await level_up(users, message.author, message.channel)
        with open('users.json', 'w') as f:
            json.dump(users, f)
        await ctx.send('{message.author} has guessed correctly!')

async def update_data(users, user):
    if not user.id in users:
        users[user.id] = {}
        users[user.id]['experience'] = 0
        users[user.id]['level'] = 1

async def add_experience(users, user, exp):
    users[user.id]['experience'] += exp

async def level_up(users, user, channel):
    experience = users[user.id]['experience']
    lvl_start = users[user.id]['level']
    lvl_end = int(experience ** (1/4))

    if lvl_start < lvl_end:
        await bot.send_message(channel, '{} has leveled up to level {}'.format(user.mention, lvl_end))
        users[user.id]['level'] = lvl_end

@bot.command(name='stopplease', help='Stop it right now!')
async def stop_quiz(ctx):
    await ctx.send('Thank you for playing our game!\n'
                   'If you like it, please consider a donation and/or using it on all the servers you know!')

@bot.event
async def on_error(event, *args, **kwargs):
    with open('err.log', 'a') as f:
        if event == 'on_message':
            f.write(f'Unhandled message: {args[0]}\n')
        elif event == 'command':
            f.write(f'Unhandled command: {args[0]}\n')
        else:
            raise
bot.run(token)

我尝试添加一些我希望它可以触发的命令,但我完全错过了一些东西。

感谢您的帮助!

【问题讨论】:

    标签: python discord.py


    【解决方案1】:

    你的问题是对装饰器的误解。它们是一个相当复杂的话题,所以这里有一个basic resource。对你来说最重要的是:装饰器只运行一次一次,这意味着只要你运行文件,其中的任何内容都是它唯一会听的东西。 现在你想在你的代码中做什么

    @bot.command(name='%s' % (correct_answer))
    

    是在装饰器中具有动态值,因此机器人会响应正确的答案。这不起作用!装饰器只运行一次。

    那么我们该如何解决这个问题呢? 我们需要稍微重写一下您的正确22 函数。您的机器人可以通过参数处理动态输入。幸运的是,这些在机器人扩展中很容易做到。 即使有参数,我们仍然需要一个命令名称,所以让我们选择“答案”。因此,在您尝试使用??2005 回答之前,您现在使用??answer 2005 回答。您可以尝试按照您最初的意图进行操作,但我认为这会使您的代码过于复杂,因为您必须处理消息处理程序。

    可能的解决方案:

    @bot.command(name='answer')
    async def correct22(ctx, answer):
            global correct_answer
            if correct_answer != answer:
                return
            with open('users.json', 'r') as f:
                users = json.load(f)       
            await update_data(users, message.author)
            await add_experience(users, message.author, 10)
            await level_up(users, message.author, message.channel)
            with open('users.json', 'w') as f:
                json.dump(users, f)
            await ctx.send('{message.author} has guessed correctly!')
    

    我还没有测试过像体验这样的用户功能,但至少消息回复应该是这样的。

    【讨论】:

    • 感谢您的回答!我已经实现了它,它完美无瑕。我现在正在调整体验命令,因为这不会增加 ATM。我会阅读您提供的链接,这看起来很有趣。好奇,你能给我一些关于消息处理的提示吗?
    • 考虑到您使用的是 discord.py 的 bot 扩展,只需查看其官方文档:discordpy.readthedocs.io/en/latest/ext/commands/commands.html。这很容易理解。如果您有任何问题,可以在 Discord 上添加我(我的个人资料上的用户名和标签)。
    • 如果我希望回复没有任何前缀,比如我必须输入 2005
    • @siprabhav 这可能是你要找的东西:stackoverflow.com/questions/57956326/… 另外,我敦促你为这样的问题打开一个单独的问题,因为它与原始问题或 cmets 无关.
    猜你喜欢
    • 2021-11-15
    • 2019-06-08
    • 2021-07-07
    • 2017-11-15
    • 2021-03-03
    • 2021-03-31
    • 2020-06-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多