diff --git a/jams/batches/java-discord-bot/part-1/en-US.md b/jams/batches/java-discord-bot/part-1/en-US.md new file mode 100644 index 00000000..8293665e --- /dev/null +++ b/jams/batches/java-discord-bot/part-1/en-US.md @@ -0,0 +1,159 @@ +--- +part: "part-1" +batch: 'java-discord-bot' +totalParts: '4' +title: 'Basics' +description: 'First we are going to register the bot at Discord and making the bot run.' +contributor: 'Kipp-ie' +contributorSlackID: 'U07HBU94Q1E' +thumbnail: 'https://github.com/user-attachments/assets/ef4418ba-c9c2-4648-92d5-8df8a198a713' +timeEstimate: '1 Hour' +difficulty: 'Beginner' +keywords: 'java, discord-bot' +presentation: 'https://www.figma.com/slides/XYXBH3tG4jlvZJMyFQCXsT/Untitled?node-id=5-297&t=OpU8bpu74eR06IRE-1' +presentationPlay: 'https://www.figma.com/deck/XYXBH3tG4jlvZJMyFQCXsT/Untitled?node-id=5-117&t=wFGI7lZsBox5fgGX-1&scaling=min-zoom&content-scaling=fixed&page-id=0%3A1' +presentationPDF: 'https://github.com/Kipp-ie/jamassets/blob/main/part-1.pdf' +--- + +# Hi 👋 + +You might have heard of Discord Bots before, if you don't i will give a short description for you. A Discord bot is a bot designed with multiple features for a Discord Server, think of a message when you join or sending random funny memes. Let's make one today! + +First go to [Discord Developer Applications](https://discord.com/developers/applications). You'll probably need to sign in. + +Click on **New Application** + +![Discord Developer Home Page](https://cloud-6p1pvbaeh-hack-club-bot.vercel.app/0image.png) + +You can choose any name wou want here. Proceed by clicking the **check box** to accepts Discord's TOS (You should read them!). + +![Application Creation](https://cloud-cqn2d1ojp-hack-club-bot.vercel.app/0image.png) + +Click on the page **Bot**. On this page you can customize the bot anyway you want! + +![Bot page](https://cloud-ief8tg9tb-hack-club-bot.vercel.app/0image.png) + +A bot token is how you can communicate with a Discord Bot, think of it like an account password. You need to keep this code safe, otherwise if someone else gets the code they can hijack your bot. Save this token for now in a notepad/word file. + +![Resetting bot token](https://cloud-69uxismjr-hack-club-bot.vercel.app/0image.png) + +You need to enable all these Privileged Gateway Intents, otherwise your bot won't function! + +![Permissions](https://cloud-j9k09iazm-hack-club-bot.vercel.app/0image.png) + +You have now changed all the settings needed, let's invite this bot to our server! + +Click on the tab **OAuth2** + +![OAuth](https://cloud-4upqdgtaj-hack-club-bot.vercel.app/0image.png) + +Check **bot** + +![Bot](https://cloud-1y24aht1v-hack-club-bot.vercel.app/0image.png) + +Check **Administrator** + +![Check administrator](https://cloud-fitsonnil-hack-club-bot.vercel.app/0image.png) + +On the bottom click on **Copy** + +![Copy LINK](https://cloud-5ze8tu4h1-hack-club-bot.vercel.app/0image.png) + +Paste this link in a new tab and proceed by following the instructions. + +# You now invited your own Discord Bot to your server, good job! + +Let's now proceed by actually writing the code. + +We will be using **JDA** (Java Discord API). + +The recommended IDE for Java is **Intellij** but you can use any IDE you want (However i will be using Intellij so it may be harder to follow if you use another IDE). + +Now, let's create a new project. + +You can give the bot/project any name you want. When you chose a name make sure the project is set on Maven instead of Gradle. Click on **Create**. + +At the left your files should look something like this. + +![IntellIJ](https://cloud-f4tqhukr8-hack-club-bot.vercel.app/0image.png) + +Open pom.xml. + +And add this to the file: + +``` xml + + + net.dv8tion + JDA + 5.0.2 + + +``` + +Press Ctrl + Shift + Q + +It should like like this. + +![Example pom](https://cloud-8k7a2wspb-hack-club-bot.vercel.app/0image.png) + +In main.java delete everything except package (your name). + +Paste this in your main.java, make sure to replace BOT_TOKEN with the bot token we got earlier. + +``` java +public class Main { + + + + private ShardManager shardManager; + + public Main() throws LoginException, InterruptedException { + DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.createDefault(BOT_TOKEN); + builder.setStatus(OnlineStatus.DO_NOT_DISTURB); + builder.setActivity(Activity.watching("Hi hackclub!")); + builder.enableIntents(GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_MESSAGES, GatewayIntent.DIRECT_MESSAGES, GatewayIntent.MESSAGE_CONTENT); + shardManager = builder.build(); + shardManager.addEventListener( + ); + + + } + + public static void main(String[] args) { + try { + Main bot = new Main(); + } catch (LoginException e) { + System.out.println("Bot token invalid!"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} +``` +Click on the things that are red, then Alt + Enter and Import Class. + +Also make sure that the bot token is between "" example: "dwah8esfsehfhsnvcb" + +Now you can try running the main.java file and seeing if the bot boots. + +If it boots, then the hardest part is behind you! If it doesn't try to retrace the steps to see if you maybe went somewhere wrong. Feel fry to dm me on Discord @kippenboutske or tag me/dm me on the Hack Club Slack: @Kipp-ie. + +Ready for the next step? If so you can follow part 2! + + + + + + + + + + + + + + + + + diff --git a/jams/batches/java-discord-bot/part-2/en-US.md b/jams/batches/java-discord-bot/part-2/en-US.md new file mode 100644 index 00000000..5deeccab --- /dev/null +++ b/jams/batches/java-discord-bot/part-2/en-US.md @@ -0,0 +1,190 @@ +--- +part: "part-2" +batch: 'java-discord-bot' +totalParts: '4' +title: 'Commands' +description: 'Creating some simple commands.' +contributor: 'Kipp-ie' +contributorSlackID: 'U07HBU94Q1E' +thumbnail: 'https://github.com/user-attachments/assets/01c63e14-014b-4dce-9b90-b3468deca8fd' +timeEstimate: '1 Hour' +difficulty: 'Beginner' +keywords: 'java, discord-bot' +presentation: 'https://www.figma.com/slides/OPzkpUPcVzR78sXNefuGLk/Untitled?node-id=1-238&t=E11NlCiFb5enyqGi-1' +presentationPlay: 'https://www.figma.com/deck/OPzkpUPcVzR78sXNefuGLk/Untitled?node-id=1-32&t=E11NlCiFb5enyqGi-0&scaling=min-zoom&content-scaling=fixed&page-id=0%3A1' +presentationPDF: 'https://github.com/Kipp-ie/jamassets/blob/main/part-2.pdf' +--- + +# 👋 Welcome back! + +So our bot is kinda lifeless right now, let's give it some spark ;). So the way you communicate with Discord Bots are slash commands. Let's make some! + +So first, we need to make a system that will register slash commands with the Discord Servers. + +So, create a **package**, it's like a folder for Java. + +Right click on the folder where main.java is located. + +Click on New, then package. + +Name it whatever you want but for simplicity you could call it Managers. + +It should now look like this. + +![Package Creation](https://cloud-36n8smf7u-hack-club-bot.vercel.app/0image.png) + +Click create again, then **class**, name it SlashCommandManager (Or something else! Be creative ;). + +So the point of the SlashCommandManager is communicating to the Discord Servers like "Hey Discord Servers, look at this cool command, okay now make sure this bot can use it". + +You know how it works now, let's make it B). + +Open SlashCommandManager, it should like like this: + +``` java +public class SlashCommandManager { + +} +``` + +add extends ListenerAdapter behind SlashCommandManager, like this! + +``` java +public class SlashCommandManager extends ListenerAdapter { +} +``` +Make sure your textcursor is between the brackets. + +Click Ctrl + O + +Search for OnGuildReady and click enter. + +What CTRL + O does is it shows you what events your bot can pick up. For example onSlashCommand If someone does a slashcommand it sends a signal to the class that uses onSlashCommand, you can use that for example sending a message when someone does /message. + +Remove super.onGuildReady(event); + +It should now look like this: + +``` java +public class SlashCommandManager extends ListenerAdapter { + @Override + public void onGuildReady(GuildReadyEvent event) { + } +} +``` + +So you can now register your commands in public void onGuildReady(GuildReadyEvent event) {} + +Add this to onGuildReady: +List commands = new ArrayList<>(); + +and + +event.getGuild().updateCommands().addCommands(commands).queue(); + +If anything becomes red click on it then Alt + Enter, please remember this, you will need it more in the future. + +Now it should look like this: + +``` java +public class SlashCommandManager extends ListenerAdapter { + @Override + public void onGuildReady(GuildReadyEvent event) { + List commands = new ArrayList<>(); + # Place your slashcommands here! + event.getGuild().updateCommands().addCommands(commands).queue(); + } +} +``` + +So now we can make some commands! + +Place the command in between onGuildReady and event.getGuild().updateCommands().addCommands(commands).queue(); + +For making a command you do: + +commands.add(Commands.slash("name of your command", "description of your command")); + +The name should be all lowercase, description can be with anything. + +Lets make the name "ping", the description can be anything you want (Let your imagination choose something ;)) + +Any class we make in Java we have to add to Main.java. + +Like this: + +![Main.java](https://cloud-rey8pf8mq-hack-club-bot.vercel.app/0image.png) + +If you add more classes to the main make sure to sepperate them with , + +Like this + +``` java +new pongcommand(), +new xcommand +``` + +# Let's try it out! + +Run the bot, go to your Discord Server, and type /ping. Does it show up? If it doesn't please retrace your steps. + +It should look like this. + +![/ping test](https://cloud-o35vh3hmp-hack-club-bot.vercel.app/0image.png) + +You have maybe noticed but if you send /ping it doesn't really do anything, that's because we need to create a Ping class. So i talked about events, we need to create a class that picks up SlashCommands with the name "ping" or whatever you chose. + +You will get this error if you don't make a onSlashCommand. + +![/ping error](https://cloud-udjw1d4l7-hack-club-bot.vercel.app/0image.png) + +Let's do that! + +So first create a Package called commands (Or whatever you want.). + +Then create a class in the package with the name whatever you want, nameing the classes with what command it is will help. + +Like this: + +![Ping Class](https://cloud-q5vhpib42-hack-club-bot.vercel.app/0image.png) + +In the class add extends ListenerAdapter\ + +Press CTRL + O and type onSlashCommand and click enter. + +Remove super.onSlashCommandInteraction(event); + +Okay this will get pretty complicated so read very good. + +In onSlashCommand add: +``` java +if (event.getName().equals("ping")) { + +} +``` +So what this does is check is the slash command has the name **ping** +If it does we can reply! + +With: + +``` java +event.reply("Message what you want to reply with!").queue; +``` + +It should look like this now! + +![ping command class](https://cloud-84sly80bm-hack-club-bot.vercel.app/0image.png) + +Okay this class is pretty good look now, let's add it to our main class! (You should probably know how! If not scroll a bit up!) + +Try /ping now! If you followed the instructions it should reply now instead of that error. If not retrace steps. Feel fry to dm me if you are stuck on Discord @kippenboutske or tag me/dm me on the Hack Club Slack: @Kipp-ie. + +# Good job, you can create slashCommands now! Pretty epic, right? + + + + + + + + diff --git a/jams/batches/java-discord-bot/part-3/en-US.md b/jams/batches/java-discord-bot/part-3/en-US.md new file mode 100644 index 00000000..71a0fa4b --- /dev/null +++ b/jams/batches/java-discord-bot/part-3/en-US.md @@ -0,0 +1,155 @@ +--- +part: "part-3" +batch: 'java-discord-bot' +totalParts: '4' +title: 'Fancy Messages (Embeds)' +description: 'Making ✨*fancy*✨ messages (Embeds)' +contributor: 'Kipp-ie' +contributorSlackID: 'U07HBU94Q1E' +thumbnail: 'https://github.com/user-attachments/assets/23ed59d0-4399-4058-a38d-c6d1da922c0b' +timeEstimate: '1 Hour' +difficulty: 'Beginner' +keywords: 'java, discord-bot' +presentation: 'https://www.figma.com/slides/NEKjZ1qZwYBTTCSc5DUVdC/Untitled?node-id=1-32&t=E11NlCiFb5enyqGi-1' +presentationPlay: 'https://www.figma.com/deck/NEKjZ1qZwYBTTCSc5DUVdC/Untitled?node-id=1-32&t=E11NlCiFb5enyqGi-0&scaling=min-zoom&content-scaling=fixed&page-id=0%3A1' +presentationPDF: 'https://github.com/Kipp-ie/jamassets/blob/main/part-3.pdf' +--- + +# Welcome back! 👋 + +You know what my view is on learning new stuff? Experimentation. Let's do that! + +Let's make some ✨*fancy*✨ messages. + +In *programmer language* we call that **Embeds**. + +Here's an example of an embed. + +![image](https://github.com/user-attachments/assets/94f3d9b6-daa0-4c66-9fda-efa4d3bd57f2) + + +To create an embed we use this: + +``` java +EmbedBuilder embed = new EmbedBuilder(); +``` + +Using embed you can make ✨*fancy*✨ messages. + +Here's a list of things you can do with embeds! + +``` +embed.setTitle("Title"); +embed.setDescription("Description"); +embed.setColor("Hexcode color"); +embed.addField("Field title", "Field description", false); +embed.setFooter("Footer"); +embed.setAuthor("Author"); +embed.setImage("Imageurl"); +``` + +There are a couple more but these are the most important. + +Remember our Ping command? Let's make it ✨*fancy*✨! + +This was where we left of: + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + event.reply("Pong").queue(); + } + } + } +``` + +First lets add the Embed Builder. + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + EmbedBuilder embed = new EmbedBuilder(); + event.reply("Pong").queue(); + } + } + } +``` + +Now let's give the embed a title! + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + EmbedBuilder embed = new EmbedBuilder(); + embed.setTitle("Pong!"); + event.reply("Pong").queue(); + } + } + } +``` + +If you look at our code you see event.reply, this does not send out embed, let's fix that! + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + EmbedBuilder embed = new EmbedBuilder(); + embed.setTitle("Pong!"); + event.replyEmbeds(embed.build()).queue(); + } + } + } +``` + +You need to build an embed before sending it, that's why it's embed.build(). + +Let's add some color! I was thinking of orange #ff7308. But you should choose the color you like! For color you need to add Color.decode(hexcode). + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + EmbedBuilder embed = new EmbedBuilder(); + embed.setTitle("Pong!"); + embed.setColor(Color.decode("#ff7308")); + event.replyEmbeds(embed.build()).queue(); + } + } + } +``` + +Maybe add a text field? + +```java + public class Ping extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("ping")) { + EmbedBuilder embed = new EmbedBuilder(); + embed.setTitle("Pong!"); + embed.setColor(Color.decode("#ff7308")); + embed.addField("Ping", "Pong", false); + event.replyEmbeds(embed.build()).queue(); + } + } + } +``` + +You can add anything you want to the embed! Experiment please! You will learn! + +Let's try it now :) + +![image](https://github.com/user-attachments/assets/ad9132cb-cfce-40c1-828a-2d5f8cade7fd) + +This was pretty cool, right? In Part 4 we will explore examples and you will learn more advanced ways to use embeds and events. But you can also use your creativity, you will learn more if you figure it out yourself. The choice is yours :). + +# Nice job ;) Maybe i will see you in the last part, maybe not! Hope i could help ;). diff --git a/jams/batches/java-discord-bot/part-4/en-US.md b/jams/batches/java-discord-bot/part-4/en-US.md new file mode 100644 index 00000000..80028f8c --- /dev/null +++ b/jams/batches/java-discord-bot/part-4/en-US.md @@ -0,0 +1,218 @@ +--- +part: "part-4" +batch: 'java-discord-bot' +totalParts: '4' +title: 'Examples.' +description: 'In this final (Optional) step we will make some example commands :)' +contributor: 'Kipp-ie' +contributorSlackID: 'U07HBU94Q1E' +thumbnail: 'https://github.com/user-attachments/assets/1678411f-a278-4883-a053-155c5e8bed70' +timeEstimate: '1 hour' +difficulty: 'Beginner' +keywords: 'java, discord-bot' +presentation: 'https://www.figma.com/slides/zmb4kWADcE6d8rKWsG0GIe/Untitled?node-id=1-32&t=E11NlCiFb5enyqGi-1' +presentationPlay: 'https://www.figma.com/deck/zmb4kWADcE6d8rKWsG0GIe/Untitled?node-id=1-32&t=E11NlCiFb5enyqGi-0&scaling=min-zoom&content-scaling=fixed&page-id=0%3A1' +presentationPDF: 'https://github.com/Kipp-ie/jamassets/blob/main/part-4.pdf' +--- + +# Welcome! (for the last time :() + +This adventure is coming to an end, welcome to the last step, the example step. I will guide you to make examples and explain every single part of the code. This will be a steep learning curve, but i believe in you :). + +# /avatar commands +Goal: Create an /avatar command where you can select an user. + +First, let's make the command. + +You already know how to make a command, but let's add some advanced features. + +``` java +commands.add(Commands.slash( "avatar", "Get someone's avatar")); +``` + +This is something new: + +``` java +commands.add(Commands.slash( "avatar", "Get someone's avatar") + .addOption(OptionType.USER, "user", "Select an user to grab a avatar from", true)); +``` +Now you can select an user with the slash command, the **true** means that the option is **required**. + +Like this: + +![image](https://github.com/user-attachments/assets/344b6c9a-8a9f-41be-84e2-ed2523f16f51) + +Let's move onto the command. + +Like we did in Step 2 create a class with the name of your choice. If you don't know this anymore go back to step 2! + +You should have something like this: + +``` java + public class Avatar extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("slashname")) { + + } + } +} +``` + +First let's begin by getting the avatar url, that's pretty straightforward + +1. Create a string with the name url +2. Get the user someone chose with the slashcommand +3. Get their avatar. + +``` java + public class Avatar extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("slashname")) { + String url = event.getOption("user").getAsUser().getAvatarUrl(); + + } + } +} +``` +We now have a String (**url**) that contains the avatar url. + +Let's make it into an embed! + +``` java + public class Avatar extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("slashname")) { + String url = event.getOption("user").getAsUser().getAvatarUrl(); + EmbedBuilder embed = new EmbedBuilder(); + embed.setImage(url); + + } + } +} +``` + +You now have a embed with the avatar url, now let's send it. + +``` java + public class Avatar extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("slashname")) { + String url = event.getOption("user").getAsUser().getAvatarUrl(); + EmbedBuilder embed = new EmbedBuilder(); + embed.setImage(url); + event.replyEmbeds(embed.build()).queue(); + } + } +} +``` + +Last step, add this class to the Main class. + +If you did that you should be done! Let's test it out! + +![image](https://github.com/user-attachments/assets/c2327be7-af0f-4b0e-a011-4788a6eacada) + +As you see it works! + +Let's move on to our second and last example. + +# Let's create a kick command. + +Sometimes when someone is so annoying you litteraly want to kick them, well, you can. Let's fix that ;) + +First let's create a slash command. + +``` java +commands.add(Commands.slash( "kick", "Kick someone") + .addOption(OptionType.USER, "user", "Choose the user to kick", true) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.KICK_MEMBERS))); +``` + +It creates a slash command with: +- An option to select the user. +- That only people with the **KICK_MEMBERS** permission can kick people. + +Now create a main class. + +Add the same base as the example above (Including if (event.getName.equals)) + +You should now have this: + +``` java +public class Kick extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("kick")) { + Member member = event.getOption("user").getAsMember(); + } + } +} +``` + +We want: +- Getting the user from the option +- Kicking the user +- Replying to the event. + +First: + +``` java +public class Kick extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("kick")) { + Member member = event.getOption("user").getAsMember(); + } + } +} +``` + +We want to get the user as a member because otherwise it gets someone as a user and now it gets someone as a member, so part of the server otherwise you can't kick them! + +Now let's do the kicking part! + +``` java +public class Kick extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("kick")) { + Member member = event.getOption("user").getAsMember(); + member.kick().queue; + } + } +} +``` + +Done! Now let's do the replying part + +``` java +public class Kick extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("kick")) { + Member member = event.getOption("user").getAsMember(); + member.kick().queue; + event.reply("Member has been kicked!").queue(); + } + } +} +``` + +Add this class to your main class. + +Let's test your bot! Now it's up to you. No screenshot this time, why? Because i don't want that your bot ends up as mine! You should use your creativity! See coding as a form of art! + +But the most important thing is, having fun. I hoped i learned you something new. + +Now use this talent! + +Good luck ;) + + + + + diff --git a/jams/batches/java-discord-bot/readMe/en-US.md b/jams/batches/java-discord-bot/readMe/en-US.md new file mode 100644 index 00000000..447f561e --- /dev/null +++ b/jams/batches/java-discord-bot/readMe/en-US.md @@ -0,0 +1,12 @@ +--- +title: 'Java Discord Bot' +contributor: 'Kipp-ie' +description: 'In this jam you are going to create a Discord Bot in Java.' +video: 'https://youtube.com/shorts/PwOjnXNr_CM' +thumbnail: 'https://github.com/user-attachments/assets/ef4418ba-c9c2-4648-92d5-8df8a198a713' +keywords: 'java, discord-bot' +timeEstimate: '4 Hours' +difficulty: 'Beginner' +slug: 'Java Discord Bot' +isBatch: True +---