diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..f74c661
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+TOKEN=
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index dc7de8d..9c2f1dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,12 @@
JDA
5.0.0-alpha.12
+
+
+ io.github.cdimascio
+ dotenv-java
+ 2.2.4
+
\ No newline at end of file
diff --git a/src/main/java/com/technovision/tutorialbot/TutorialBot.java b/src/main/java/com/technovision/tutorialbot/TutorialBot.java
index af07e18..d3259b6 100644
--- a/src/main/java/com/technovision/tutorialbot/TutorialBot.java
+++ b/src/main/java/com/technovision/tutorialbot/TutorialBot.java
@@ -1,9 +1,16 @@
package com.technovision.tutorialbot;
+import com.technovision.tutorialbot.commands.CommandManager;
+import com.technovision.tutorialbot.listeners.EventListener;
+import io.github.cdimascio.dotenv.Dotenv;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
+import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder;
import net.dv8tion.jda.api.sharding.ShardManager;
+import net.dv8tion.jda.api.utils.ChunkingFilter;
+import net.dv8tion.jda.api.utils.MemberCachePolicy;
+import net.dv8tion.jda.api.utils.cache.CacheFlag;
import javax.security.auth.login.LoginException;
@@ -15,6 +22,7 @@
*/
public class TutorialBot {
+ private final Dotenv config;
private final ShardManager shardManager;
/**
@@ -22,13 +30,30 @@ public class TutorialBot {
* @throws LoginException occurs when bot token is invalid.
*/
public TutorialBot() throws LoginException {
- String token = "YOUR_BOT_TOKEN";
+ // Load environment variables
+ config = Dotenv.configure().load();
+ String token = config.get("TOKEN");
+
+ // Build shard manager
DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.createDefault(token);
builder.setStatus(OnlineStatus.ONLINE);
builder.setActivity(Activity.watching("TechnoVisionTV"));
+ builder.enableIntents(GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_PRESENCES);
+ builder.setMemberCachePolicy(MemberCachePolicy.ALL);
+ builder.setChunkingFilter(ChunkingFilter.ALL);
+ builder.enableCache(CacheFlag.ONLINE_STATUS);
shardManager = builder.build();
+
+ // Register listeners
+ shardManager.addEventListener(new EventListener(), new CommandManager());
}
+ /**
+ * Retrieves the bot environment variables.
+ * @return the DotEnv instance for the bot.
+ */
+ public Dotenv getConfig() { return config; }
+
/**
* Retrieves the bot shard manager.
* @return the ShardManager instance for the bot.
diff --git a/src/main/java/com/technovision/tutorialbot/commands/CommandManager.java b/src/main/java/com/technovision/tutorialbot/commands/CommandManager.java
new file mode 100644
index 0000000..7a0c8cd
--- /dev/null
+++ b/src/main/java/com/technovision/tutorialbot/commands/CommandManager.java
@@ -0,0 +1,67 @@
+package com.technovision.tutorialbot.commands;
+
+import net.dv8tion.jda.api.entities.Role;
+import net.dv8tion.jda.api.events.ReadyEvent;
+import net.dv8tion.jda.api.events.guild.GuildReadyEvent;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.commands.build.CommandData;
+import net.dv8tion.jda.api.interactions.commands.build.Commands;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Registers and manages slash commands.
+ *
+ * @author TechnoVision
+ */
+public class CommandManager extends ListenerAdapter {
+
+ /**
+ * Listens for slash commands and responds accordingly
+ */
+ @Override
+ public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
+ String command = event.getName();
+ if (command.equals("welcome")) {
+ // Run the 'ping' command
+ String userTag = event.getUser().getAsTag();
+ event.reply("Welcome to the server, **" + userTag + "**!").queue();
+ }
+ else if (command.equals("roles")) {
+ // run the 'roles' command
+ event.deferReply().queue();
+ String response = "";
+ for (Role role : event.getGuild().getRoles()) {
+ response += role.getAsMention() + "\n";
+ }
+ event.getHook().sendMessage(response).queue();
+ }
+ }
+
+ /**
+ * Registers slash commands as GUILD commands (max 100).
+ * These commands will update instantly and are great for testing.
+ */
+ @Override
+ public void onGuildReady(@NotNull GuildReadyEvent event) {
+ List commandData = new ArrayList<>();
+ commandData.add(Commands.slash("welcome", "Get welcomed by the bot"));
+ commandData.add(Commands.slash("roles", "Display all roles on the server"));
+ event.getGuild().updateCommands().addCommands(commandData).queue();
+ }
+
+ /**
+ * Registers slash commands as GLOBAL commands (unlimited).
+ * These commands may take up to an hour to update.
+ */
+ @Override
+ public void onReady(@NotNull ReadyEvent event) {
+ List commandData = new ArrayList<>();
+ commandData.add(Commands.slash("welcome", "Get welcomed by the bot"));
+ commandData.add(Commands.slash("roles", "Display all roles on the server"));
+ event.getJDA().updateCommands().addCommands(commandData).queue();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/technovision/tutorialbot/listeners/EventListener.java b/src/main/java/com/technovision/tutorialbot/listeners/EventListener.java
new file mode 100644
index 0000000..e3838d8
--- /dev/null
+++ b/src/main/java/com/technovision/tutorialbot/listeners/EventListener.java
@@ -0,0 +1,74 @@
+package com.technovision.tutorialbot.listeners;
+
+import net.dv8tion.jda.api.OnlineStatus;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Role;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
+import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
+import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
+import net.dv8tion.jda.api.events.user.update.UserUpdateOnlineStatusEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Listens for events and responds with our custom code.
+ *
+ * @author TechnoVision
+ */
+public class EventListener extends ListenerAdapter {
+
+ /**
+ * Event fires when an emoji reaction is added to a message.
+ */
+ @Override
+ public void onMessageReactionAdd(@NotNull MessageReactionAddEvent event) {
+ User user = event.getUser();
+ String jumpLink = event.getJumpUrl();
+ String emoji = event.getReaction().getReactionEmote().getAsReactionCode();
+ String channel = event.getChannel().getAsMention();
+
+ String message = user.getAsTag() + " reacted to a [message]("+jumpLink+") with " + emoji + " in the " + channel + " channel!";
+ event.getGuild().getDefaultChannel().sendMessage(message).queue();
+ }
+
+ /**
+ * Event fires when a message is sent in discord.
+ * Will require "Guild Messages" gateway intent after August 2022!
+ */
+ @Override
+ public void onMessageReceived(@NotNull MessageReceivedEvent event) {
+ String message = event.getMessage().getContentRaw();
+ if (message.contains("ping")) {
+ event.getChannel().sendMessage("pong").queue();
+ }
+ }
+
+ /**
+ * Event fires when a new member joins a guild
+ * Requires "Guild Members" gateway intent!
+ */
+ @Override
+ public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
+ Role role = event.getGuild().getRoleById(988342442430443540L);
+ if (role != null) {
+ event.getGuild().addRoleToMember(event.getMember(), role).queue();
+ }
+ }
+
+ /**
+ * Event fires when a user updates their online status
+ * Requires "Guild Presences" gateway intent AND cache enabled!
+ */
+ @Override
+ public void onUserUpdateOnlineStatus(@NotNull UserUpdateOnlineStatusEvent event) {
+ int onlineMembers = 0;
+ for (Member member : event.getGuild().getMembers()) {
+ if (member.getOnlineStatus() == OnlineStatus.ONLINE) {
+ onlineMembers++;
+ }
+ }
+ String message = event.getUser().getAsTag()+"updated their online status! There are "+onlineMembers+" members online now!";
+ event.getGuild().getDefaultChannel().sendMessage(message).queue();
+ }
+}