0
votes

I am working on a custom discord bot, mostly for fun. I found another discord bot from another server, named Kurisu, which is completely custom and open source. here is the github: https://github.com/nh-server/Kurisu. In mod.py (https://github.com/nh-server/Kurisu/blob/port/cogs/mod.py), on line 432, there is a function that basically gives a user the No-Help role (in the server this restricts access to specific channels). I am trying to make something similar, where having the No-Voice role restricts your acess to voice channels. I am using some of their code, namely in the parameters of the function. I am doing async def takevoice(ctx, member: FetchMember): as the function. the full function is here:

@bot.command(name="takevoice", pass_context=True, description="Removes access to voice channels. Admin only.")
@commands.has_role("Admin") # This must be exactly the name of the appropriate role
async def takevoice(ctx, member: FetchMember):
   role = get(member.guild.roles, name="No-Voice")
   await member.add_roles(role)

other functions in my program work perfectly, but whenever I try and run this function with another user as the target, it doesn't work and gives me a traceback error. the end of it is: AttributeError: "user" object has no attribute "guild". I have looked everywhere for an answer, but can't find one. any help would be much appreciated.

thanks!

the full code for my bot is here: (I am using a couple other files, all of which can be found in the utils folder of the Kurisu github. namely, I am using checks.py, converters.py, database.py, manager.py, and utils.py. I am also using a file called keep_alive.py because i am running this on repl.it.)

import asyncio
import aiohttp
import json
import keep_alive
from discord import Game
from discord.ext.commands import Bot
import datetime
import re
import time
from subprocess import call
import discord
from discord.ext import commands
from checks import is_staff, check_staff_id, check_bot_or_staff
from database import DatabaseCog
from converters import SafeMember, FetchMember
import utils
from discord.ext import commands
from discord.utils import get
TOKEN = ""  # Get at discordapp.com/developers/applications/me
bot=commands.Bot(command_prefix=".")
client=discord.Client()

@bot.command(name="hi")
async def hi(ctx):
    await ctx.channel.send("hello")

@bot.command (name="elsewhere", description="Gives acess to the #elsewhere channel")
async def elsewhere(ctx):
    role = discord.utils.get(ctx.guild.roles, name="Elsewhere")
    user = ctx.message.author
    if role in user.roles:
        await user.remove_roles(role)
    if role not in user.roles:
        await user.add_roles(role)

2
I've read the source for Kurisu/utils/converters.py and I can't really wrap my head around it. It appears FetchMember is eager to fallback to a User rather than a Member. Regardless, if you want to use a member method (to get the guild. Users are Members of guilds), try setting your function argument as member: Member, Discord.py will try to convert automatically. - Allister
@Allister when i do that, i get a Member is not defined error. - 2tmb
Try member: discord.Member then. I have just tested, as I should have in the first place, and this absolutely works. - Allister
@Allister it worked! thanks! I don't exactly get why, but it did. one more question, do you know how to make it so having a specific role means you can not acess specific channels? instead of making it so having a specific role means you can acess specific channels. - 2tmb
I don't know. I would suggest you research, give it your best shot, then make another question when you've hit a wall. - Allister

2 Answers

2
votes

That's because a User object cannot have a specific guild - a user means someone that is no longer in the guild. Change async def takevoice(ctx, member: FetchMember): to async def takevoice(ctx, member: discordMember): and the issue will be fixed. That way, you will get a Member instead of a User object, and there would be a specific guild. However (I don't know whether this matters) you can no longer perform this action on someone who is not in the guild.

0
votes

Changing member: FetchMember to member: discord.Member solved it. the .Member needs to be capitalized.