Adding a single role to all server members - discord.py

So I am trying to make the bot give all the server members a single role. Code:
#commands.command(pass_context = True)
async def test(self, ctx, role: discord.Role):
for user in ctx.guild.members:
await user.add_roles(role)
print(f'{user.name} {role.name}')
However, it only printsOdysea(the name of my bot) test role And only gives the role to itself.
Any ideas how to fix this?

By the comment section you can do like this.
Ps. Im using client variable instead bot, that's up to you
In main file
client = commands.Bot(command_prefix=[your_prefix], intents=discord.Intents().all())
In cogs
#commands.command()
async def test(self, ctx, role:discord.Role):
for member in ctx.guild.members:
try:
await member.add_role(role)
except:
pass
print(f"{member.name}, {role.name}")

Related

Discord.py: Guild object has no attribute create_scheduled_event

Discord.py is handy to automate things and I am trying to create a scheduled discord event by command. But it seems that I cannot call the function create_scheduled_event of the Guild object while other functions work fine.
For example, the function fetch_roles() works fine and returns the roles of my guild.
But calling the function create_scheduled_event raises the error 'Guild' object has no attribute 'create_scheduled_event'.
Does anybody have an idea what I am missing, here?
Thanks in advance!
Here's the code
import discord
client = discord.Client()
#client.event
async def on_message(message):
# ...
if message.content.startswith('!newevent'):
myguild = client.guilds[0]
roles = await myguild.fetch_roles()
print(roles)
newevt = await myguild.create_scheduled_event(...)
client.run(TOKEN)

User's avatar discord.py 2.0

How to get member's avatar in discord.py v2?
Before, it was like this:
#client.command(aliases=["av"])
async def avatar(ctx, *, avamember : discord.Member=None):
userAvatarUrl = avamember.avatar_url
embed2 = discord.Embed(title=f"{avamember}")
embed2.set_image(url=userAvatarUrl)
await ctx.send(embed=embed2)
Error I got:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Member' object has no attribute 'avatar_url'
Thanks!
You need to replace avamember.avatar_url with avamember.avatar.url.
Here's the link to the 2.0 docs if you're interested:
https://discordpy.readthedocs.io/en/master/api.html#discord.Asset

How to make this remove role command work properely?

#client.command()
async def number_4(ctx, role):
role = discord.utils.get(ctx.guild.roles, name = role)
await ctx.author.remove_roles(role)
I'm not really sure how to make this work properly...
I've made a few changes. When calling the command you want to mention the role: #role
Keep in mind this will only work if the bot has a role higher up than the role you are trying to remove.
#client.command()
async def number_4(ctx, role: discord.Role):
await ctx.message.author.remove_roles(role)

login by one user and accesstoken of another user

I have implemented simpleJWT for token based authentication. I created a simple hello world test API.
While testing, I am logging with /rest-auth/login/ and for generating use /api/token/ - both working fine.
Now for testing, I am logging in with say user XYZ (having access rights for helloworld api) and generating token using another user ABC (not having access rights for helloworld api).
So now user XYZ is authenticated (ok) but I am having token of user ABC (ok).
Now, when I call the API with token generated for use ABC, I am able to access the helloworld api even if user ABC has no rights for the API !! Because user XYZ who has rights already logged in.
Problem is this will always be case when multiple users will be using the site. How to resolve ? Few code snippets also presented below :
My settings.py snipped
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
code basically a decorator which authenticate for users is as below
def user_is_ADM(fun_c):
#wraps(fun_c)
def wrapped(request, *args, **kwargs):
# 1 = ADM
if(request.user and request.user.is_authenticated) : <--- here is the issue
user_data = UserProfile.objects.get(user_id = request.user.id)
# user profile as as a user type
u = user_data.user_type
if u == 1:
return fun_c(request, *args, **kwargs)
else:
raise PermissionDenied
return wrapped
what should be my strategy in this case ?
EDIT
Modified my decorator as follows and it is working. Someone please comment if I am doing something wrong
def user_is_ADM(fun_c):
#wraps(fun_c)
def wrapped(request, *args, **kwargs):
juser = get_user(request)
if juser.is_authenticated:
user_jwt = JWTAuthentication().authenticate(Request(request))
if user_jwt is not None:
if request.user == user_jwt[0]:
k = user_jwt[0].userprofile.get_user_type_display()
if k == 'ADM':
return fun_c(request,*args,**kwargs)
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
else:
raise PermissionDenied
return wrapped
check out this documentation https://www.django-rest-framework.org/api-guide/permissions/ (Custom permissions)
when setting a general permission setting (IsAuthenticated).
It is really authenticating users but not verifying their permissions at any time
class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
"""
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
if basic administrator and user authentication is not enough. you can implement a custom permission
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
"""
extracted from the documentation
"""
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
"""
add authentication logic and return a boolean value
"""
# ...
# return bool()
in the views
from rest_framework.views import APIView
from modulename.permissions import CustomerAccessPermission
class ExampleView(APIView):
"""
...
"""
permission_classes = (CustomerAccessPermission,)
def get(self, request, format=None):
"""
...
"""
Here is an example with django authentication permissions
from typing import Tuple
from rest_framework.permissions import BasePermission
class CustomPermission(BasePermission):
"""
...
"""
list_permissions: Tuple[str] = (
'modelname.view_modelname',
'modelname.add_modelname',
'modelname.change_modelname',
'modelname.delete_modelname',
)
def has_permission(self, request, view) -> bool:
return bool(
request.user.has_perms(self.list_permissions)
or
request.user and request.user.is_staff
or
request.user and request.user.is_superuser
)
summary
With regard to the syntax in general, you will not see any changes, you must import your permission or decorator in the view, the difference lies in the runtime and the way django will evaluate the permissions
Remembering that a decorator is nothing more than a summary way of saying func(func()).
so you should always evaluate the view and call your method modified by the decorator
instead, permissions in this framework are always defined as a list of permission classes. Before executing the main body of the view, each permission in the list is verified. If any permission verification fails, exceptions will be generated. Permission denied or exceptions. An unauthenticated exception will be generated and the main body of the view will not be executed. (Consult the documentation for a complete explanation)
You should evaluate which method is most appropriate for your case (performance, syntax, etc.).
# you can set your permission in the general settings to avoid importing into each file
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'modulename.permissions.CustomPermission',
),
# ...
}

check OTP before registration in Django Rest Auth

I am using Django Rest Auth plugin for registration and login in Django Rest Framework. I want to check OTP (unique key) while user registration.
We are sending OTP based on Mobile number to users. Django checks OTP after registration. I want to set those condition before registration.
If conditions are true then registration should be done.
class SignupForm(forms.Form):
otp_no = forms.CharField(label='OptNo', required=True)
def signup(self, request, user):
try:
otpobj = Otp.objects.get(pk=self.cleaned_data['otp_no'])
if otpobj.phone_number == self.cleaned_data['phone_number']:
user_number = UserNumber(user=user, phone_number=self.cleaned_data['phone_number'])
user_number.save()
else:
raise forms.ValidationError('Number is not valid')
except ObjectDoesNotExist:
raise forms.ValidationError('OTP is not valid')
I have added def create() and def update() method in UserSerializer but still it doesn't work. Please guide me for this solution and thanks in advance.

Resources