message.guild.createRole({
name: message.member.user.tag,
color: 'RANDOM',
deny: ['CHANGE_NICKNAME'],
})
It seems the deny parameter for createRole() is not working & will not deny the change nickname permission, I tried multiple variations but it seems to want to enable it by default. I've even included the value of CHANGE_NICKNAME which is: 0x04000000 but this does not want to seem to take effect, any ideas?
That's because deny is not a parameter in RoleData, you need to use the permissions parameter and then pass the denied permissions:
message.guild.createRole({
name: message.member.user.tag,
color: 'RANDOM',
permissions: [{
deny: ['CHANGE_NICKNAME']
}]
})
Related
I have been having trouble figuring out how to update a User with graphQL. The functionality I'm currently aiming for is for the user to be able to update their account/profile information. I have some things set up for the user like a bio field for their profile, and a profile picture field that's set up to take a URL and display that as their profile picture.
I have no problems when it comes to creating using graphQL. A user can sign up, log in, make posts, etc without issue. I can also update the User in regards to other models, for example, a new post pushes to the users Post data just fine.
I have not been able to figure out how to update a user directly though. Essentially I can get around this by creating a new model for "profile pic" and pushing that to the User, but that seems like it's just extra steps that might slow things down, as well as shortchanging myself being able to learn something new.
This is the User model. I have omitted a few fields due to the exact block of code being large, but this includes the "image" and "bio" fields (the fields I would like to update) as well as the reference to the Post model which I mentioned above that functions appropriately.
User.js
const userSchema = new Schema(
{
username: {
type: String,
required: true,
unique: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
match: [/.+#.+\..+/, 'Must match an email address!']
},
password: {
type: String,
required: true,
minlength: 8
},
image: {
type: String
},
bio: {
type: String,
maxLength: 500
},
posts: [
{
type: Schema.Types.ObjectId,
ref: 'Post'
}
],
},
Below is the mutation in Explorer, including the variables and the result.
Profile Pic Resolver
addProfilePic: async (parent, { image }, context) => {
if (context.user) {
const updatedUser = await User.findOneAndUpdate(
{ _id: context.user._id },
{ image: image },
{ new: true, runValidators: true }
);
return updatedUser;
}
throw new AuthenticationError('You need to be logged in!');
},
typeDefs.js (relevant only)
type Mutation {
addProfilePic(_id: ID!, image: String!): Auth
}
I notice that in the Explorer page it returns "null" for user with a 200 status. I am led to believe that means that it's not able to even access the "image" field on the user to be able to update it. When compared to my other mutations in regards to users, this is set up very similarly and I'm not sure what the difference is.
I feel like I am missing something very basic here in regards to being able to update. I haven't been able to find an update mutation example that works. Could anyone assist? My main questions would be:
Why does the mutation return "null" for user?
How can I set up my resolver to appropriately update information on an already-created object?
Thank you to anyone who is able to take a look and assist, I will be closely watching this post for replies and will update any other code someone may need to be able to assist. I've been stuck in regards to updating information for a long time, but my site is getting to the point where it's nearly ready and I need to tackle this updating issue in order to progress. Thank you!
Quick Edit: I want to add that "Auth" is referenced. The appropriate authorization headers are in place to retrieve the data. Just wanted to add that in as I highly doubt authorization has anything to do with this!
I have solved this issue and would like to leave the answer here for anyone who may find it useful.
In the mutation typeDefs, I changed the "Auth" to "User",
type Mutation {
addProfilePic(_id: ID!, image: String!): User
}
and then in the mutation itself, took away the user field like such:
mutation addProfilePic($_id: ID!, $image: String!) {
addProfilePic(_id: $_id, image: $image) {
_id
username
image
}
}
This has allowed the user to update their profile photo information. Hope this helps!
So, I have made this code
const { Guild } = require("discord.js");
Guild.roles.create({
name: 'Kırmızı',
color: '#ff0000',
reason: 'Before giving color roles, you need to add the roles to server'
})
I know that I should be writing the guild name but I want it to run this code in the server its command is used. How can I do that?
You're pretty close. You get the guild from the message:
message.guild.roles.create({
name: 'Super Cool Blue People',
color: 'BLUE',
reason: 'we needed a role for Super Cool People',
});
It does depend on how you are triggering this interaction, e.g. message, interaction, reaction, etc.
If you are doing it from a reaction, for example:
client.on('messageReactionAdd', async (reaction, user) => {
if (reaction.emoji.name === '👍') {
reaction.message.guild.roles.create({
name: 'Super Cool Red People',
color: 'RED',
reason: 'we needed a role for Super Cool People',
});
}
});
Roles
Reactions
There really isn't enough documentation on this either in the AWS docs or in the Github, so hopefully someone here has tackled a similar issue.
I have a react app with backend api hosted on AWS, using appsync, dynamoDB, and cognito-user-pools. My IAM policies are set up to allow unauth users read-only permission to some public tables. I tried the public api key but that didn't do anything. I'm trying to get the IAM unauth role permissions set up but even when I experimentally added literally every service and every action to the unauth role, I still get "no current user" when attempting to make the API call without logging in.
Use case is for public author pages, where information about an author along with their currently available books is listed. Users should not have to sign in to see this page, an author should be able to drop a link to the page to anyone, whether they have a login for the app or not.
This is my graphql schema for the relevant types, it gets no errors:
type PublicBook #model #auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
#key(name:"byPublicWorld", fields: ["publicWorldId", "indexOrder"])
#key(name:"byPublicSeries", fields: ["publicSeriesId", "indexOrder"]){
id: ID!
publicWorldId: ID
publicSeriesId: ID
indexOrder: Int!
cover: FileObject #connection
description: String
amazon: String
ibooks: String
smashwords: String
kobo: String
goodreads: String
audible: String
barnesnoble: String
sample: String
}
type PublicSeries #model #auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
#key(name:"byPublicWorld", fields: ["publicWorldId", "indexOrder"]){
id: ID!
publicWorldId: ID!
indexOrder: Int!
logo: FileObject #connection
description: String
genre: String
books: [PublicBook]#connection(keyName:"byPublicSeries", fields: ["id"])
}
type PublicWorld #model #auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
#key(name:"byAuthorPage", fields: ["authorPageId", "indexOrder"]){
id: ID!
authorPageId: ID!
logo: FileObject #connection
description: String
genre: String
indexOrder: Int!
series: [PublicSeries]#connection(keyName:"byPublicWorld", fields: ["id"])
books: [PublicBook]#connection(keyName:"byPublicWorld", fields: ["id"])
}
type AuthorPage #model #auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
#key(name:"byPenName", fields: ["penId"])
#key(name:"byPenDisplayName", fields: ["penDisplayName"], queryField: "authorPageByPen"){
id: ID!
authorName: String
penDisplayName: String
penId: ID!
bio: String
photo: FileObject #connection
logo: FileObject #connection
penFBProfile: String
penFBGroup: String
penFBPage: String
penTwitter: String
penInstagram: String
penAmazon: String
penWebsite: String
penNewsletter: String
penGoodreads: String
penPatreon: String
posts: [AuthorPost]#connection(keyName:"byAuthorPage", fields: ["id"])
worlds: [PublicWorld]#connection(keyName:"byAuthorPage", fields: ["id"])
}
type AuthorPost #model #auth(rules: [{ allow: owner, operations: [create, update, delete], provider: userPools },
{allow: public, operations: [read], provider: iam}])
#key(name:"byAuthorPage", fields: ["authorPageId", "timeCreated"]){
id: ID!
authorPageId: ID!
timeCreated: AWSTimestamp!
content: String!
title: String!
subtitle: String
type: PostType!
}
Each of these types is set to owner/cognito permissions for creating, updating, and deleting, and then there is a public auth using iam to read. Seems straight forward enough.
The main type here is Author page, and I have the query set up to pull all the connected relevant cascading information. When logged in, this works fine and shows an author page with all the bits and bobs:
export const authorPageByPen = /* GraphQL */ `
query AuthorPageByPen(
$penDisplayName: String
$sortDirection: ModelSortDirection
$filter: ModelAuthorPageFilterInput
$limit: Int
$nextToken: String
) {
authorPageByPen(
penDisplayName: $penDisplayName
sortDirection: $sortDirection
filter: $filter
limit: $limit
nextToken: $nextToken
) {
items {
id
authorName
penDisplayName
penId
bio
photo {
location
}
logo {
location
}
penFBProfile
penFBGroup
penFBPage
penTwitter
penInstagram
penAmazon
penWebsite
penNewsletter
penGoodreads
penPatreon
posts {
nextToken
startedAt
}
worlds {
nextToken
startedAt
}
_version
_deleted
_lastChangedAt
createdAt
updatedAt
owner
}
nextToken
startedAt
}
}
`;
On the page itself (although in production this just happens at app.js and persists throughout the app), I'm pulling current credentials and logging them to make sure that some kind of IAM identity is being created, and it appears to be:
accessKeyId: "BUNCHANUMBERSKEY"
authenticated: false
expiration: Thu Mar 04 2021 13:18:04 GMT-0700 (Mountain Standard Time) {}
identityId: "us-west-2:48cd766c-4854-4cc6-811a-f82127670041"
secretAccessKey: "SecretKeyBunchanumbers"
sessionToken:"xxxxxbunchanumbers"
That identityId on line 4 is present in my identity pool as an unauth identity, so it is getting back to the pool, which seems to be what's supposed to happen.
So, this identity pool has two roles associated with it, which is standard: auth and unauth, and my Unauthenticated Identities Setting has the box for Enable Access to Unauthenticated Identities checked.
In my unauth role, I've got the following as the inline policy json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppsyncApiId/types/Mutation/fields/authorPageByPen"
]
}
]
}
I wasn't sure if this needed to be mutation, or query, or what, so I've tried them all. I tried them in combination with 'fields' and with 'index', I've tried writing the JSON, and adding the policies from the inline editor, which gives me the following which also does not work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "appsync:GraphQL",
"Resource": [
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppSyncAPIId/types/AuthorPage/fields/authorPageByPen",
"arn:aws:appsync:us-west-2:MyAccountID:apis/MyAppSyncAPIID"
]
}
]
}
What bit am I missing here? I could understand getting some error about not being allowed to access a resource, but the only error that logs is No Current User, and that happens immediately after the log showing the user.
Update:
Running the query from the Appsync console works fine with IAM and no logged in user. In the page itself, I'm using the following function to call the author page (I'm using routes):
const pullAuthorPage = async () => {
try{
const authorPageData = await API.graphql(graphqlOperation(authorPageByPen, { penDisplayName: props.match.params.id.toLowerCase() }))
console.log(JSON.stringify(authorPageData, null, 2));
setState({...authorPageData.data.authorPageByPen.items[0]})
} catch (error) {
console.log(error);
}
}
What I thought would happen with this is that if there is no authenticated user logged in, this will run using the unauth user credentials. Is that not the case? And if so, how should I change it?
In Discord.js v11 you could use guild.setRolePosition({ role: '123456789012345678', position: 1 }); to set the position of a specific role. How can you specify a role (like i.e. 'Muted') with the new role.setPosition() method? It seems to only accept a position number and a few options like options.relative. What I want is to assign a role position to the roles Admin, Friends, Muted in the roleCreate() event. I know that the roleCreate event only runs when a role is created, but somehow the 'position' parameter doesn't work well with guild.roles.create.
GuildRoleManager.create() actually works fine with the position parameter, you just have to add it ass a property to the data object.
guild.roles.create({
data: {
name: 'Role Name',
// any other options...
position: 1
},
});
If you still want to use role.setPosition(), you'll have to fetch the role object before-hand, then call the method on that object.
// <guild> is a placeholder for the guild object
// get the role by id
const role = <guild>.roles.cache.get('Role ID');
// get role by name (or other property)
const role = <guild>.roles.cache.find((role) => role.name === 'Role Name');
role.setPosition(1);
I'm actually doing a command to start a "conversation" with a player and take responses he give me. For doing that, I've the plan to use a temporary channel. I don't find a complet way to create a channel. I saw, that we have to create the channel, and after modifie it to adjust as we want. So I have this code :
m.guild.createChannel(`Candidature-${m.author.username}`, 'text', [{
type: 'role',
id: '605021521467146279',
permission: 0x400
}])
with this error :
(node:1904) DeprecationWarning: Guild#createChannel: Create channels with an options object instead of separate parameters
and I don't find real documentation about options object. Can I have some information about how it's work, and some link to learn more ?
Thanks for your help.
I can see the confusion here as the way channels are now created have been altered and here is how to create them: (var name = "blah" isn't needed but cleans it up a bit)
var name = `ticket-${numbers}`;
message.guild.createChannel(name, { type: "text" })
And to do the channel permissions you want to use .then like this:
message.guild.createChannel(name, { type: "text" }).then(
(chan) => {
chan.overwritePermissions(message.guild.roles.find('name', '#everyone'), {
'VIEW_CHANNEL': false
})
You can change the role or change it to other things such as message.author.id or mentioned users etc.
Hope this helps!
Thanks for your answers. I have do this :
m.guild.createChannel(
`Candidature-${m.author.username}`, {
type: 'text',
topic: `Salon de candidature créé par ${m.author.username} | Id du joueur : ${m.author.id}`,
parent: idCategorie,
permissionOverwrites: [{
id: m.guild.id,
deny: ['VIEW_CHANNEL'],
},
{
id: m.author.id,
allow: ['VIEW_CHANNEL'],
}
]
})
.then((chan) => {
console.log("Channel create");
});
With those links :
https://discord.js.org/#/docs/main/stable/typedef/ChannelData
https://discordjs.guide/popular-topics/permissions.html#roles-as-bot-permissions
It's creating a channel with a name, a topic, and a categorie as parent. Only the plyaer itself and administrator can see the channel.