Discord.NET Bot Development · Ranks & auto-roles · Episode 8 [OUTDATED]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys and welcome to the eighth episode of the discord.net bot development series in this episode we are going to talk about ranks and auto rules ranks are roles that people can add to themselves by using commands and auto rules are roles that will be added when someone joins the server automatically so these two subjects are things we're going to talk about now this episode is indeed about events because we want to trigger something when someone joins the server but later on we will also make something that sends a message when someone joins the server rather than just adding the raw but because doing both in one episode will take a lot of time and it will make one episode very long and thus i decided that we're just going to talk about ranks and art roles in this episode and then in the coming episode we are going to talk about customization of the welcoming module so how you can change the background of it how you can set a channel for where our messages will be sent to and that kind of stuff if you enjoyed this episode please leave a like if you have any suggestions or any feedback please leave a comment and if you really like this series please subscribe to my channel as there will come more episodes and probably even more series now let's get started now the very first thing that we want to do is head over to our infrastructure and open up the tutorial context file and this is the database structure that we started working on in episode six now the first thing we want to do here is we want to create classes that contain information about ranks and author rules so let's go here on the server and let's twice enter and create a new class and call this class a public class and let's say rank so each rank shall have an id to identify itself this is only for the database we won't use it but it's just so the database can identify a specific rank we want the role id so the id of the role that the rank contains and the server id so we know to which server direct belongs so let's go here to curly brackets to make a public int id and this value should be get set so we can get the value but also modify it so set it the second value we'd like is a public ulon rule id so in here we're going to store the id of the row of the rank again use curly brackets and get set and last but not least we want to add the server id so we say public ulang server id and in this property we can store the id of the server so we can for example search for all ranks of a server and again curly brackets get set now we also want to create a new property for auto rules so just copy the class paste it under the rank and rename rank to auto raw now replace the character within the class so the weird height lighting goes away and there we go we now have ranks and we have auto rules now to actually put these two classes inside of our database go all the way up enter and say public db set and we want a table of rank so let's say rank let's call the table ranks and again this value should also be get set so we can modify and set the values inside of the table now we also want the table for public db set also role because we also want a table for alter roles and we call this table auto rows again curly brackets get set now we want to push these changes to our database so we can actually put them to use now to do this the first thing we want to do is go to your windows icon right here type in xampp open up exam and start up mysql and apache now click on admin next to mysql and let's minimize the window for now let's also minimize apache and now we want to push our changes onto our database so we can actually use the ranks table and the auto rules table go to tools nuget package manager and package manager console now before doing anything you want to make sure that the default project is set to infrastructure and that the starter project is set to infrastructure 2 when you've done that go to the console and type in add migration and here we can type in a name as you can see the previous migration that we made so the first time we made a migration which was in episode 6 we called it the initial version now we're going to call it the second version so add migration second version let it build and when it's done building we want to push our changes to the database so we say update database now if everything goes well it will say applying migration and then it will say done now if we go to our browser refresh the page go inside of our tutorial database you'll see a table called auto rolls ranks and servers each containing an id a role id and a server id perfect now the next thing we want to do is we want to create functions that are able to communicate with our database for example in the service class we made functions to modify the guild prefix and get the good prefix but now we also want to make functions that allow us to create new ranks new altar roles but also modify them so what we want to do is head over to the infrastructure project right click it click on add and click on class now as a name we call the first class ranks press enter now the first thing we want to do here is we want to make the class public so public class ranks and inside of here we want to create around four functions the first one we also create is a function that is able to grab all the ranks of a server and then return it to us as a list in order to do this we first want to inject our database context into the file just like we did at servers right over here copy these lines go back to ranks and paste them in there now replace servers with ranks so we can actually access our database right here now in here type public async task and the return type should be a list of rank so it's going to return a list of ranks then we say get ranks async and then as a argument we want to pass in the id of a server so we say you long id hover over task click on the light bulb in using system threading tasks now in here the first thing we want to do is create a new variable that we call ranks so var ranks equals await underscore context and we want to use the ranks table so we say dot ranks which equals the table that we created all the way here so we can now use this table and search based upon these properties and here what we want to do is we want to search for all ranks that have the server id of the server id that was passed here so we say where then brackets and x and lambda expression and then we say it's not server id equals the id that we pass in a bit more now here what we do is we say to list async so we actually have a list of all the ranks within the server then the final thing we want to do is say return await task.fromresult and then the ranks so now we have a list of all the ranks based upon the server id the next thing we want to create is a function that's able to add a new rank to the server now to do this we create a new function we say public async task add rank async now here as arguments we again want a server id so your long id but we also want the id of a row so let's say you long roll id press enter curly brackets and inside of here what we want to do first is search for the server so we say file server equals await underscore context dot servers and enter and then we want to search all the servers and find the server that has the id that we passed in earlier now if the server is null meaning that there is no server in the database we want to add a server to the database so we say underscore context dot add a new server and the id of the server should be the id that was passed a bit more up now we also want to add a new rank to our database so we say context add new rank curly brackets the role id should be the role id that was passed in earlier and his server id exactly the same should be the id that was passed in earlier now finally we say await underscore context dot save changes async and we end with a semicolon now we also want a function that's able to remove a rank from a guild so we can delete ranks so they no longer can be used in order to give to a user and in order to do this we say public async task remove rank async again we want to pass in the id of the server and we want to pass in the id of the role so ulon roll id curly brackets and inside what we first say is we say var rank equals await underscore context dot ranks because we want to use the ranks table now in this table we want to search for all ranks and have the role id which equals the role id that was passed into the method so where x and then the wall id equals the role id that was passed in then we want to select the first or default result asynchronously from the database now we want to remove the rank from our database so we say underscore context dot remove and then the rank last but not least we want to save the changes so we say wait underscore context dot save changes async now last but not least we want to create a function that's able to remove multiple ranks by using a list now why do we want a function that does that now later on we want to create a function that is able to actually give the roles to us so you can access the name of the raw and we can automatically give the role to a user but what if the bot is no longer able to give the role to the user because the server only decided that the bot does not longer have permissions to add a role or that the role simply doesn't exist anymore in that case if the rule doesn't exist anymore or if the bot cannot even give the role to the user anymore we want to remove the rank from the server so we don't cause any issues and that we can do easily by using a function that's able to remove multiple ranks at the same time so that if we have multiple ranks that no longer work we can just delete them at once instead of using every time removing and removing and removing so in order to do this we say public async task and we say clear ranks async and then we want to pass in a list containing rank and we want to call this ranks so we have a list of ranks and curly brackets and inside here a very simple thing we can do is say underscore context dot remove range and then the list that we just passed in then we want to save the changes so we say wait undersaw context dot save changes async and that's basically all the functions that we're going to need from the database now we also have auto rules and for those auto rules we want to use exactly the same functions so go to the infrastructure project right click it click on add click on class and i create a new class that's called also rules in this class we want to paste everything that we just did in ranks because everything works exactly the same so go back to ranks select everything copy it paste it in auto rolls replace ranks with also rules and replace it again here ranks with auto rules now in the names we want to change it from get ranks async to get auto rules async then here we want to change range to alter rule we want to go a bit more down change context.ranks to context.also rules and here we want to replace the name of the variable with auto rules and then pass in the ultra rules variable right here next add rank async should be add auto raw async go a bit more down you want to say contacts.add new auto rule rather than rank and that's it go even more down remove rank async should be remove auto raw async replace contacts.ranks with context of auto rolls replace the variable name of rank with also raw copy the name paste it in right here save the changes and last but not least clear ranks async should be clear also rules async and instead of using the ranks variable we say auto rules instead of using rank we say auto rule copy the name paste it in there and that's it now we have two classes that are able to create modify etc auto rolls and ranks now because we're finished with doing all the database required things we can get started with some methods that we need to make inside of our template or whatever the project is called for your discord bot so get inside of this project get inside of the utilities folder and here we want to create again two new classes one is a class for the answer rules and one is going to be a class for the ranks right click the folder and say add and say class and the first one we want to work with is a ranks helper so called the class of ranks help now inside of here we want to create the function that's able to give us the raws as actual discord rules so we can just apply them to the user and we can instead of doing difficult things we can just simply check if all of the roles exist in the server and if our bot is able to access them now first things first let's make this class public second we again want to inject something but in this case not the database context but we want to inject the method that we made earlier the ranks and server class so in a ranks helper we want to inject the ranks class so what we say here is we say private read only ranks and then we want to do it like this so we automatically add the using infrastructure right there then we say underscore ranks semicolon then we create a public constructor so it's a public ranks helper ranks ranks just like that and then we say underscore ranks equals ranks just like that now we can put them to use now before continuing it's important that we go to our program and here at singleton both ranks and alter rules so we say dot add singleton then the ranks just like that and the auto rules so auto rules just like that now we can actually use the ranks and ultra rules classes inside of our ranks helper now go a bit more down and the first thing we want to create is a function that's able to get all the ranks within the server but then as actual discord rules so we say public async task and as a return type instead of using ranks we actually return roles so we say list and then i roll and then his name we call it get ranks asic and as parameter we want to pass in i i gold gold so we can actually use the gold to check things and that kind of stuff hover over task click on the light bulb and say using system threading tasks now first things first we want to create a new variable which is called rules now this one is going to be the list that we will be returning all the way at the end so let's say var rules equals a new list with the type of i roll just like this and they use brackets and a semicolon and you want to create a list of invalid ranks so a list of ranks that are incorrect or have a higher position than the bot or deleted that kind of stuff so we call this var invalid ranks equals a new list and the type should be rank records and a semicolon now we also want to fetch all the ranks that we currently have so let's make a new line and say var ranks equals the await underscore ranks dot get ranks async gold dot id so now we fetch all the ranks based upon the database and then store them into a variable called ranks then we want to loop over all ranks of our server and then check if they are valid that kind of stuff so here we say for each var rank in ranks so we can loop over them we want to make sure that they are valid don't have a higher position that kind of stuff so what we say here var raw equals guild dot roles dot first or default so it picks the first or default rule that it can find and that should be based upon a condition so we say x and then a lambda expression and then we say x dot id equals the rank dot draw lighting so we can make sure that the row actually exists now if the brawl is null meaning that they could not find the role meaning that the row was deleted we add the raw or the rank to the list of invalid ranks so we say envelope ranks dot add and then the rank so we can later on delete it now let's actually add some curly brackets because we're also going to have an else statement which is when the row is not null and in that case if it's not null just like this we want to do something different also add another curly bracket right there so it's nicely done and add another curly bracket right there so if the raw is not null in that case what we want to do is we want to execute something different the first thing we want is to fetch the current user so we want to fetch the bot from the guild and to do this we say var current user equals await gold dot get current user async so we now have our bot stored into a variable and this allows us to check for example the hierarchy of our bot inside of the server now here we create a new variable to store the hierarchy of our bot so we can check if the position is high enough in order to add the role to a user so it's a var hierarchy equals and then here what we say is the current user that we fetched earlier as a socket build user and then we put brackets around it and then we say dot hierarchy so we have it stored into a nice variable next we want to check if the roll dot position so the position of the row based upon if the bot is higher than the raw or not so raw dot position is higher than the hierarchy of the bot in that case we also wanted to add it to the invalid ranks so we see valid ranks and then the rank if that's not the case then we can add the raw to our valid rules so we say rows add and then the raw now that's the loop that we need let's go outside of the loop and here what we want to do is if the invalid ranks dot count so the total amount of envelope ranks is higher than zero in that case what we do is we say await underscore ranks dot clear ranks async based upon the invalid ranks list that we made earlier just like that then finally we want to return all the roles and that's the first function that we need now we also need a class for our auto roles so go to the utilities folder click on add click on class and let's make a new class and call this auto rolls helper press enter now go back to your ranks helper copy everything inside of this paste it into the auto rules helper now replace ranks helper auto rules helper copy it paste it right there replace ranks with auto rules let's call this auto rules again do the same here so auto rules also rules underscore auto rules and then last but not least we say underscore auto roles equals the author rules now instead of the name get ranks async we say get auto rolls async now we go a bit more down we say instead of invalid ranks we say invalid also rules and we want this to be a list of auto rules just like that and here we say var answer rules equals await underscore also rules dot get art rules async just like this and then instead of looping over the ranks we want a loop over the outer rule so we say var also roll in also rules so a loop of the auto rules then we want to check if everything matches right there and if not we want to add it to the other row and we want to add the outer row itself and here we say rolled up position is higher than the hierarchy should be adding it to the invalid auto rules it should add the outer rule if the invalid altera is the count is higher than zero it will use the arterials and then the clear arterials acing function to clear and remove all the invalid auto rules and that might have sounded a bit complicated but now we have two functions that are capable of fetching all the rules inside of our discord servers to get the alter rolls but also the ranks and if they are not correct or something is wrong they're able to delete them now we can go and close up the utilities folder and we can also close the entire infrastructure project we can go inside of our modules and for these commands let's make a new folder so click on the modules folder click on add and click on class now let's call this class configuration so in this class we can make the commands to configure the author roles and the ranks now go back to your example module and let's copy this go back to the configuration class first thing says let's make the class public and then just paste it right there so we now use the module base and then the socket command context hover over it click on the light bulb let's see using discord dot commands and now let's make some commands that are able to change all of the stuff that we just made so there are a few commands that we want to make we want to make commands that are able to add and remove auto rolls and ranked and we want to make commands that are able to give a rank to a user and we also want to use an event so when a user joins the server we want to use that event in order to give the auto roles to the user so the first thing we want to create is the functions related to the ranks so first things first let's make a new command and let's give it the name ranks this command can be executed in order to list all the ranks within the server so we say command ranks and we want to make this a public async task ranks should be no arguments that's all fine curly brackets and inside here the first thing we do is we want to fetch the ranks of a server but in order to do so we want to inject the ranks helper inside of this class so we say private read only ranks helper underscore ranks helper semicolon then use a constructor public configuration ranks helper ranks helper and then curly brackets inject it into the ranks helper so we can actually use it now just like we did before we want to go to our program.cs and add both the ranks helper and the alter rules helper to our services so we say dot at singleton pointy brackets ranks helper goes first brackets and last but not least we say add single tan and then pointy brackets and we say auto raws helper again pointy brackets and brackets that's it we no longer need to add any services here now we can actually make use of everything that we just made now hover over task wait for the icon to appear and say using system threading tasks and now we can use tasks now in here the first thing we want to fetch like i said earlier are all the ranks within the guild so we save our ranks equals the weight underscore ranks helper does get ranks async and we want to pass in the context.guild so we can just simply use that then if the ranks dot account equals null so if the server doesn't have any ranks we just want to say await reply async this server does not yet have any ranks now this is a very basic message you could add a nice embed around it you could give it embed a nice title and that kind of stuff but that's not what we do in these tutorials not yet at least for now we just send simple messages back and you can customize them in any way you like now again we use the early return statement so if this happens it just stops right there and that's it now next because the process can take a while there's a very nice thing we can do in order to let our user know like hey we're working on it we don't yet have a response but just hold on two three seconds and will have a nice response for you and that is trigger typing async trigger typing async basically means that in a channel it shows that the bot is typing which is an indication to the user like hey it received the command it's working on it but it can take a while although it just takes two or three seconds it's still nice to indicate like hey we're working on it so we say wait context channel trigger typing async just like that now what we want to do is let our user know what ranks are available so let's create a string and we call this showing a description and the first thing that the description should say is this message lists all available ranks just like that then we use a semicolon at the end and now what we can do is loop over the ranks and add each rank to the description so what we say here is we say for each var rank in ranks we say description plus equals which means it grabs the description and adds something on the end so plus equals then here we use a backslash and then an n and a backslash m means that we create a new line and we want to create a new line so we can nicely separate every single rank then what we can do here is we add a dollar sign at the start and we say two curly brackets and then in here what we can do is we can say rank dot mention and then we use two normal brackets and here we pass in the rank dot id so this allows people to add the rank to them by using the id or for example the name and to make that instruction a bit more clearer what you can do here is in the description make a new line and say in order to add a rank you can use the name or id of the rank so you could use for example the name of the rule or you could use the id of the raw if multiple ranks have exactly the same name so we can do here now is we can return our message with the description to the user so we say away apply async and then the description just like that and that's already it now we already have a working function and when we run our discord bot right now we first want to of course change the starter project to our template and also go to the package manager and say that the default project should be the template then save it and run it now if you go to discord and try to execute the ranks command it will tell you that this server does not yet have any ranks and that's correct we didn't make the command set to add any ranks but we don't have any yet so that's perfectly correct and the next command that we want to make is a command that allows us to add ranks so we say command and then between a string we save add rank and now an important thing comes permissions we don't want to allow everyone in the server to create new ranks we only want to let administrators create new rings so we say require user permission and then the permission build permission dot administrator so we only want to let users that have the administrative permissions to be able to execute this command now we also want to let the bot have enough permissions in order to add the rank to users so we say require bot permission and then google permission manage rules so the bot is actually able to give rules to members otherwise it's useless now we say public async task and now a nice thing we can do is we can let the user pass in multiple arguments this is the thing you can choose you can for example choose whether or not the user should be able to mention the role and that kind of stuff but in this case and for this tutorial we're just gonna work with the name of the rule so for example if you have a role called tutorial you just have to type in name tutorial and then it will be the rank so we say public async task add rank and as arguments we want a string name now what if the name of a rule contains an answer that means that there will be two arguments right and that's correct we don't want that to be we want to allow all names that have spaces anything and in order to do this instead of just using a regular string you go all the way to the start and you use square brackets you say remainder and then it becomes a remainder string called name and remainder means that the string can contain spaces it doesn't matter it will take everything as one argument it's also impossible to just use another argument after this because everything will be used as domain the string you can only use arguments before the remainder string so we say remain the string name then we open the function and in here we can start processing the creation of ranks but before doing so we again need to think about something important because ranks at rank and allows commands will be database related commands and like i said in a previous episode when things can take long or when they are database related it's important to use these tasks on a separate process that way it won't stop any other command for working so an important thing to do here go to line 20 add a comma after the string and say run mode equals run mode dot async now copy this go to line 41 and do the exact same so that both commands will work asynchronously on a separate process and we will keep doing this for every single command that we will be making that is database related that kind of stuff now also before continuing let's go to our example module let's grab the prefix command that we had right here and let's say ctrl x backspace let's get rid of these two lines go back to the configuration class and paste in the command above the ranks command and also because the prefix command is a database related command it's useful to just use run mode equals run mode dot async now we want to go back to our example module go all the way up and we can get rid of the injection of these servers let's get rid of it right there go back to the configuration class paste it in right there go back to the example module get rid of the injection right there paste it in right here go back to the example module get rid of it right here go to the configuration class paste it right there and now we can use the servers class within our configuration class and of course don't forget to use the infrastructure now if we go all the way down it's time to actually do some processing to add the roll to the ranks so the first thing i want to do is again indicate that the bot is doing something that we receive the command and that we're working on it so what we do here is we say wait context.channel dot trigger typing async now we want to fetch all the ranks of the server so var ranks equals await underscore ranks helper dot get ranks async and then pass in the context.good so we fetch all the ranks as roles that we can use the next thing we want to do is we want to search in our server for a role that contains the name that was passed in right here so we say vowel role equals context dot gold dot rules and then we want to pick the first or default role which has the same name as that one that was provided earlier so you say first or default and here we can decide whether or not we want to use case sensitivity in my case i'm not going to use case sensitivity so even if you type in the wrong name in regards of case sensitivity it will still work you can get rid of this but in my case i'm just going to work with it so we say x create a lambda expression string dot equals and then x dot name and then we compare it with the name that was sent earlier and then we use string comparison dot current culture ignore case now that might sound complicated but it basically means that it will compare and let us know if this is true so if the string equals the name but it will ignore case sensitivity so it's a nice way of comparing both now if the raw equals null so if there if the rule doesn't exist if the name is invalid we say await reply async and then we say that role does not exist and of course a semicolon at the end again we use a return an early return statement and we can move on to check if the raw has a higher position than our bot which means we cannot add it because it just won't work so you see if the roller position is higher than context dot guild current user dot hierarchy then we say weight reply async that role has a higher position than the bot and a semicolon and again use an early return statement now the last thing we want to check is if the role is already a rank because you don't want to let people at the same rank over and over again so you say if ranks dot any and use a lambda expression just like that and then if any rank dot id x dot id equals the rollout id so if any of the ranks that we have equal the role id that's in there that we just fetched then we also want to send an error and say wait reply async that role is already a rank semicolon at the end here's an early return statement and finally what we can do is add the rank to our server so we want to use the ranks functions that we made into our infrastructure project and so we want to go all the way back up and we say here private read on the ranks underscore ranks here we say ranks ranks and finally we say underscore ranks equals ranks now we go a bit more down and now we can add the rank to our server so we say wait underscore ranks dot add rank async and in here we want to pass in the id of the server and the role id so we say first things first we add the server id so we say context guild id and then we say roll.id so we pass in that the next thing we can do is say hey it worked out the rank has been added so we say wait reply async the raw and now let's mention the raw so it looks a bit nice so the roll roll.mention has been added to the ranks and nice semicolon at the end let's check if it works run the template go to discord and as you can see in this server i have a test and verified rule which we made earlier let's remove the test rule from me so we can actually test it on later and say exclamation mark ranks as you can see the server right now does not have any ranks yet now we say add rank and then a test raw the raw has a higher position than the bot so our error messages also work let's go to the server settings go to roles and let's put the tutorial role above testing save the changes close the window and say add rank test the raw test has been added to the ranks now the funny thing is if we go back here and go to our browser and refresh this take a look at the ranks table you'll see that we now also have it implemented into our database so it works good so if we go here now and say exclamation mark ranks we'll say this message lists all available ranks in order to add a rank you can use the name or id of the rank so as you can see it works perfectly fine now let's test what happens when i go to roles and delete the test role because that means there will be a big issue it cannot find the raw so let's go here back and as you can see it already updates it but that's because of discord now if we execute the command again it will say the server doesn't yet have any ranks that was fast it replied really quickly and if we go back here and refresh the page you can see that it automatically removed it from our database so all of our code works let's minimize the browser let's close our discord bot and now we can also apply this to the author ranks so in order to do that we can copy both the ranks command and the add ranks command and then paste them right here but instead of allowing everyone to execute the outer rules command let's first rename it ultra rules we want only to let administrators be able to view alter rules because members shouldn't really be able to see what things have been configured this is more private thing for administrators so we say require user permission good permission dot administrator and of course rename this to auto rules and rename this to add auto raw now here we want to of course first add the author rules helper to the class so we say private read-only auto rules helper underscore auto rules helper let's put it underscore before a little bit just like that semicolon at the end and let's edit right here also rules helper also rules helper just like that add it to the injection so auto rolls helper equals auto rules helper and we also want to inject our auto rules class that we made in the infrastructure project so we say private read only auto roles underscore auto rules and again edit right here so we say auto roles also rules and we say here underscore auto rules equals auto rules so we can actually use everything that we need let's go back all the way down and replace here underscore ranks help with underscore auto rules helper let's replace get ranks async with dot get auto rules async and let's rename this to auto rules just like that paste it right here this server doesn't have any auto rules instead of ranks string description this message lists all auto rules in order and then here we can say in order to remove an also use the name or id just like that and then of course here we say auto roll for each outer row and auto rolls we want to mention the auto roll and we want to pass in the id of the auto rule this command will not work and we can also say add auto roll which has the same required permissions that's correct and then instead of here using the ranks helper we say underscore auto rules helper and we say instead of get ranked async we say get auto rolls async then here while roll we check if the row actually exists then we say that rule doesn't exist here we check the hierarchy and finally here what we can say if the auto and any item within the author roles has the same id as the role id it should error so let's replace the name of the list right here from ranks with auto rules so now it can actually work and then we can say here that role is already alterable then finally of course we want to say underscore also roles dot add auto raw async just like that and last but not least we say the raw and then dimension the raw has been added to the auto rules now let's run this and see if that also works so let's go back to discord go to the server settings go to the roles let's create two new roles let's create one it's called arterial and make it yellow and let's create one that we call rank and let's make this cyan ish now go back and let's say here ranks which are none we don't have any ranks and alter walls which are also none we don't have any alter rules now let's add a rank and we set rank at rank rank and we say add auto rule also rule just like that now if we say exclamation mark ranks we will have only the rank raw and if we say auto rolls we will only have the auto rule rule so everything works perfect now let's close our discord bot so now we have commands in order to fetch all the autorules within a server and we are able to use commands in order to add autorules or add rings the next commands that we want to make is to remove autorules and to remove ranks and how we can let people add ranks to themselves let's go a bit more up to make the delete rank command so in here what we do is we say command and then we pass in bell rank as in a short version of rank so dial rank and again we want this command to run as run mode equals run mode dot async so it runs asynchronously on a separate project now again we want to use the same permissions the bot should have the go permissions.manage rules permission and the user should have administrative permissions now we make the function we say public async task and this task should be called dell rank again you should be able to pass in a name so we're going to use a remainder string name of the raw that you want to delete as rank now here again we let the user know that we are working on his command so we say wait context.channel not trigger typing asynchronous then we want to fetch all the ranks within the server so we say var ranks equals weight underscore ranks helper dot get ranks async by using the context.guild and now we have all the ranks now again we can copy the process of searching for the rule right here so we say if the rule does not exist we give it an error and if it does exist we now have it stored into a variable next thing that we want to do is this doesn't matter the position the hierarchy because we're just removing it meaning that it doesn't really matter where the rank is positioned so that's fine now the thing that we do want to check is if the raw is even a rank so what we can do here is say if ranks not any and then a lambda expression just like this and then the id equals the roll.id but instead of using equals we say does not equal so if none of the ranks have the same id as our rule id then we want to give an error hey this row isn't even a rank so we say wait apply async we say that ball is not a rank yet and then we use a semicolon and again we use the early return statement now we can here assume that the rank exists and it's still in the list and it's actually raw and in that case what we want to do is say wait underscore ranks dot remove rank async and we pass in the id of a server so context.google id and then we pass in the id of the row just raw dot id next we let the user know hey we're done the raw is no longer a rank so you say reply async and then we say the raw and then raw.mention has been removed from the ranks just like that and now it's no longer a rank now we can copy all of this then go a bit more down let's say go under the add auto rules and instead of saying del rank we now sell dell auto roll replace the function name with dell auto raw just like that and then here instead of using the ranks helper get rank async we use underscore auto rolls helper dot get auto rolls async by using the context guild then let's rename the ranks variable to auto rules and here what we can do is we can search again this process is exactly the same it's fine we don't need to change anything about that but then here we go and then check if in the auto rolls there's any raw matching the world that was passed then we say that raw is not a auto raw and we use and so that's not an auto rule yet finally instead of using rank stop when we rank async we use underscore auto rolls remove auto raw async and then finally last but not least we say the raw dimension has been removed from the also rolls just like that so now we are able to delete and add outer roles and ranks now the final command that we want to make is a command that's able to assign or remove the rank from someone in order to do this we go to the example module right here and now all the way down we can create a new command which is called rank so the rank command can be used in order to give someone rank or let it remove it from someone so we say command rank again we want to run this command on a separate task so we say run mode equals run mode dot async just like that now we make a new task and we say public async task rank and again here we want to pass in a remainder and then a string that should be the name of the rank now earlier we said in the configuration here that you can also use the id order name so in this case we need to search for both name or id and thus we're not going to call this name but we're going to call this identify so we can check if this is an id or if this is something else just like that so the first things first what we always want to do is we want to let the user know that we're working on it so we say await context.channel trigger typing async just like that now we want to store all the ranks into one variable but before doing so we need to inject our helper of the ranks into our class so we go all the way back here we say private read only ranks helper and an underscore thanks helper then we go here we say ranks helper ranks helper finally we say underscore ranks helper equals the ranks helper just like that and now we can actually put it to use so now if we go the way back down here we can save bar ranks equals the weight underscore ranks helper dot get ranks async and we pass in the context.good the next thing that we can do is we can check whether or not the provided identifier is an id of a rule or if it's just a name now the way that we can do this is by creating an empty variable and then later filling it based upon if it's an id or if it's a name and a simple way of doing this is to create a new variable which is an eye roll role and just put it like this so it's an empty rule it's really nothing actually but we can do this in order to later check if the raw is still nothing and that means that it's not an id not a string something went wrong so we could return an error now what we can do is we can say if the ulong dot try pass and then we pass in the identifier and we want to get the result of that by using out you long and then we say roll id now this if statement means that if the identifier was possible to a new long so if we could pass the id to you long which means that it's a u-long it's a number then we can check with the you long if it's an actual role that exists so in here what we can do is we can say var raw by id let's just call it like that equals context dot guild dot raws but first or default so you're going to pick the first or default row and then a lambda expression just like this and we say the first role that has the id of the role id that we just passed right here so we can check by this if there exists a role by using the id that we have right here and if that's the case then we can pass that role to this variable right here but we first want to check if the role by id equals null we say await apply async we say that ball does not exist and then we say early return statement now if that's not the case the simple thing that we now can do is we can say raw equals raw by id and now we have an actual raw that's right there now if it failed to pass then we want to check if the identifier is a name of a rule and if there actually exists a rule with their name so what we do here is we go back to configuration now here we're looking for a line for example where we said varroal equals context.girl.rules so we can filter based upon name but ignore decay sensitivity like we did earlier search for a line like that and then just copy everything after the equals now go back to the example module and here we want to create a new variable let's call this var raw by name equals and then just like that now what you want to do is replace the name here with identifier and hover over string comparison click on the light bulb and say using system so now we're able to use that now if the raw by name equals null so if there's nothing we say the weight reply async that role does not exist again use an early return statement and if it does exist so if it passes early return statement we say raw equals raw by name so now we can filter based upon the id or based upon the name so now the rule will always be something and if it's not something and it would have already errored for example right here or for example right here now the nice thing that we now can do is just check if the person has the rank and if not we can add it to them but if he does he or she does we can just remove it from them and why is because we don't need to do any further checks because if we go back to the auto rules helper or the ranks helper you can see that we always check if the hierarchy is still valid if it's not it's getting removed just to remind you this function we always call it when we for example fetch all the ranks or the also rules so we automatically already filter out all the things that we can't use so the only thing that's left to do is make sure that the bot is also able to manage rules and in order to do that we just go here create a new line and say require spot permission and then guild permission dot manage rules so now we are 100 sure that the command is executable there will be no errors whatsoever now the only thing we need to check is whether or not the role that we now have is actually part of the ranks and in order to do this the only thing we need to do is if and then ranks dot any x so a lambda expression and an x dot id doesn't equal the raw dot id so if none of the ranks equal the rule id that we just received then we say await reply async and we say that rank does not exist so now in that case the raw is not part of a rank and so we do nothing with it we again use the early return statement now we need to check if the user has the raw or if he or she does not have the role so what we do here is we say if the context dot user as socket guild user and then again use two brackets around it just like this and it's a dot raws dot any and then x so we use lambda expression x dot id equals the raw dot id so if any of the roles that the person has equals the id that was just passed it means that the user already has the ring and in that case we're going to remove it from them so again use a bracket so it nicely fits use curly brackets and so what we do here is we say await then the context dot user as socket good user and between brackets and we say dot remove raw async and we pass in the raw that we have all the way up there so now if it's a rank if the rank was found we can remove it from them when they have it and then we say await reply async successfully removed the rank and now we can pass in the name of the rule so we get a bit more back here add a dollar sign and we can save successfully remove the rank raw dot mention from you and then a semicolon at the end and then finally we say return now the final thing that we can do is we can add the raw to them so copy these two lines go all the way here and we say await context.user socket guild user dot add raw async and then the raw and here we say successfully edit the rank raw dimension to you now let's check this out let's save all of our code let's run the bot let's go to discord so as you know we earlier set the rank raw as one of our ranks so if we now use rank it won't work because we did not pass enough arguments but if we use exclamation mark rank and then rank then it will say successfully added the rank ranked to you but i made a typo but if you look at the account we now also have the rank roll it works perfectly fine now let's say we execute the command again so we say rank rank successfully remove the rank rank from you and we no longer have the rank so that works perfectly fine now if we look at the ranks here it's just listed perfectly fine for example if we use the id we say rank and then the id of the rank it will also work and it will give us the rank again and if we use it again with the id but now remove it it works perfectly fine let's go back those are discord bot fix the typo i made earlier and that means that everything works in the ranks command the only thing that's left for us to do now is to implement the alter rules so let's go to the command handler and we want to create a new function for when someone joins the server from this episode forward i'm getting rid of the on reaction edit event we no longer really use it so we're getting rid of it we're also getting rid of the unjoint task and we're getting rid on the on channel created event so we're just getting rid of all of those because we're not really going to use them anymore they were just an example for episode 5 but for now it's fine and the next thing we want to do is create a new event which is called when a user joins so we say underscore client dot user joins plus equals on user joint just like this and it will give us the light bulb when we say generate method command enter dot on user joint now as you know we need to use the auto rules helper in order to fetch for example all the auto rules so we go here we say private read only auto rules helper and then the underscore auto rolls helper just like that then we go all the way at the end here and we say auto rules helper also rules helper copy the name go here say underscore auto rules helper equals the auto rules helper just like that now we can go into here and the first thing we would like to fetch are all of the roles that we can add to the user so we say var rules equals await underscore also rules helper dot get auto rules async and we pass in the arc dot gold now we also want to make this test async so it's a private async task on user joint just like that now again we want to check if there are even any rules that we can add to the user so what we can do here is say if the role of account is lower than one then we just say return so we use an early return statement if there are no rules to be added but if there are in that case what we want to do is we want to say await arg dot add roles async and then all of the author rules that have been set by the server and that's basically it now it works automatically and when we now try to join our server it will automatically give all the alterations of the server to the user so let's run our discord bot let's go to discord and before actually adding a user to my server i will first execute the auto rules command so as you can see we now have one auto roll right here but we also want to add let's just add one more so we can see if everything really works so let's add the verified role to the author roles here we can say add auto raw and verify just like that so now if we execute the articles command again you see that we have both auto raw and verified rules to be our auto rules now i just added my own aka account as we call it to the server and if we now go to the account you can see that it has both the verifies and the auto raw rules now if you go to the server go to server settings and an audit log you also see that the tutorial bot has updated the roles for my alt account and we now have the raw auto rule and verified so everything works perfectly fine now if i open up my browser and go to the ask account so now i am on my different account this account doesn't have any permissions as you can see another administrator so now if i try to execute the ranks command it will show me all the ranks and if i try to join them so if i say examination mark rank rank it will work it will give me the rank raw and everything works perfectly fine if i execute the command again it will remove the rank from me and i no longer have the rank now for example if i try to execute the command auto rules just like this then it will fill it will tell me hey you don't have the required permissions and that's exactly how we want it to be so everything works and we have created amazing systems for both auto rolls and ranks so that was it for this episode it was a lot of stuff at once we did a lot of coding we did a lot of database operations but we did also make amazing stuff in the next episode like i said at the beginning of the episode we will work on customizing our welcoming service so how we can send an image to the welcoming channel how we can set the welcoming channel how we can change the background of our image generator so we can all set those values in a database now if you have any issues whatsoever please comment them in this video or go to the description down below take a look at the link to our discord support server and we will be happy to help you also as a quick reminder the entire code that we write will always be on the github repository online which you can also find in the description down below now if you've enjoyed this episode don't forget to leave a like and please subscribe to the channel if you like to see more episodes or even more series have an amazing day and i hope to see in the next one you
Info
Channel: Coding with Efehan
Views: 3,491
Rating: undefined out of 5
Keywords: discord, discord.net, discord bot, tutorial
Id: 9s7rApKNPC4
Channel Id: undefined
Length: 64min 30sec (3870 seconds)
Published: Sun Oct 18 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.