Add reaction in jda to Message by messageid - java

My problem is, that my code, especially tc.addReactionById(messageID, emote);, dont adds a reaction. The whole code is following!
if(args[0].equalsIgnoreCase(prefix + "system") && args[1].equalsIgnoreCase("radd")){
if(args.length == 6){
Message message = event.getMessage();
List<TextChannel> channels = event.getMessage().getMentionedChannels();
List<Role> roles = message.getMentionedRoles();
if(!channels.isEmpty() && !roles.isEmpty()){
TextChannel tc = event.getMessage().getMentionedChannels().get(0);
Role role = roles.get(0);
String messageIDString = args[2];
try{
long messageID = Long.parseLong(messageIDString);
String emote = args[5];
tc.addReactionById(messageID, emote);
eb.setAuthor("Oni System");
eb.setColor(Color.MAGENTA);
eb.setDescription(emote);
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
LiteSQL.onUpdate("INSERT INTO reactionroles(guildid, channelid, messageid, emoji, roleid) VALUES(" + event.getGuild().getIdLong() + ", " + tc.getIdLong() + ", " + messageID + ", '" + emote +"', " + role.getIdLong() + ")");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
else{
eb.setAuthor("Oni System");
eb.setColor(Color.RED);
eb.setDescription(userMent + " bitte benutze !system radd <messageid> <#role> <channel> <emoji>");
eb.setFooter("Oni System | ©ONI", "https://media.discordapp.net/attachments/810910771557957672/810927512892604416/Bot.png?width=676&height=676");
channel.sendMessage(eb.build()).queue();
}
}

addReactionById is a RestAction in the JDA library, so you will need to queue the operation.
Replace
tc.addReactionById(messageID, emote);
with
tc.addReactionById(messageID, emote).queue();
Assuming the messageID and emote arguments are valid, the call to .queue() should process the reaction. In particular, emote needs to be one of either:
An Emote object created by JDA (usually these are custom server emotes), or
A Unicode string of the emoji you want to add
See the MessageChannel documentation for more info.

Related

Seperating ArrayList items to a regular keyword group

I started Java for plugin codding in minecraft. now I'm trying to add role names as prefix and show it in chat.
ArrayList<String> userRoles = new ArrayList<String>();
if(player.hasPermission("chat.rank.admin")){
userRoles.add("[Admin]");
} if(player.hasPermission("chat.rank.vip")) {
userRoles.add("[VIP]");
}
event.setFormat(userRoles<>(1) + " " + player.getDisplayName() + "§7: " + msg);
// In this line, the expected output is "[Admin] user: msg" or both [Admin] [VIP] user: msg"
// But it gives "([Admin],[VIP]) user: msg"
// I'm sure it has a simple solution but as I said, I'm new here. thanks from now
It seems like you are trying to create a list which only stores one value.
You might want to try creating a function that get the rank name of the player outside of your PlayerChatEvent listener.
Here's a demo code:
public String getPlayerRankName(Player p){
if (p.hasPermission("chat.rank.admin"))
return "[Admin]";
else if (p.hasPermission("chat.rank.vip"))
return "[VIP]";
else
return "";
}
And in your PlayerChatEvent event listener, call this function in your chat line:
event.setFormat(getPlayerRankName(event.getPlayer()) + " " + player.getDisplayName() + "§7: " + msg);

Youtube Search Command for JDA Discord Music Bot

I've been working on a Discord bot for a few days now.
Initially only with simpler commands etc. But slowly I also devoted myself to the topic of music bot.
I also use the YouTube Data API for this and everything works so far. However, I would now like to incorporate a Youtube Search Command or build it into another (Play Command). I already have half a search command.
So far you can do $play (song title)
and the first track found will be selected.
However, I want to be able to see the first 10 search results and then choose between them.
I have already figured out how to display the search results, but now I need a little help with how to enter a command, after you have already entered another.
So you enter: $play Faded
Then a normal EmbedBuilder comes up and shows you the search results, and then you can select the desired track by entering 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10.
This is the code:
public class PlayCommand implements ServerCommand {
private final YouTube youTube;
public PlayCommand() {
YouTube temp = null;
try {
temp = new YouTube.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
null
)
.setApplicationName("JDA Discord Bot")
.build();
} catch (Exception e) {
e.printStackTrace();
}
youTube = temp;
}
#Override
public void performCommand(List<String> args, Member m, TextChannel channel, Message message) throws RiotApiException {
String input = String.join(" ", args.subList(1, args.size() - 1));
if (!isUrl(input)) {
String ytSearched = searchYoutube(channel, input);
if (ytSearched == null) {
channel.sendMessage("Keine Ergebnisse!").queue();
return;
}
input = ytSearched;
}
PlayerManager manager = PlayerManager.getInstance();
manager.loadAndPlay(channel, input);
manager.getGuildMusicManager(channel.getGuild()).player.setVolume(100);
}
private boolean isUrl(String input) {
try {
new URL(input);
return true;
} catch (MalformedURLException ignored) {
return false;
}
}
#Nullable
private String searchYoutube(TextChannel channel, String input) {
String youtubeKey = "AIzaSyDoQ4OInMTYth7hdlWwQSIaHuxpxxv7eJs";
try {
List<SearchResult> results = youTube.search()
.list("id,snippet")
.setQ(input)
.setMaxResults(10L)
.setType("video")
.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)")
.setKey(youtubeKey)
.execute()
.getItems();
if (!results.isEmpty()) {
String videoId = results.get(0).getId().getVideoId();
/*EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("Suchergebnisse");
builder.setColor(Color.RED);
builder.setDescription( "1. " + results.get(0).getSnippet().getTitle() + "\n" +
"2. " + results.get(1).getSnippet().getTitle() + "\n" +
"3. " + results.get(2).getSnippet().getTitle() + "\n" +
"4. " + results.get(3).getSnippet().getTitle() + "\n" +
"5. " + results.get(4).getSnippet().getTitle() + "\n" +
"6. " + results.get(5).getSnippet().getTitle() + "\n" +
"7. " + results.get(6).getSnippet().getTitle() + "\n" +
"8. " + results.get(7).getSnippet().getTitle() + "\n" +
"9. " + results.get(8).getSnippet().getTitle() + "\n" +
"10. " + results.get(9).getSnippet().getTitle());
channel.sendMessage(builder.build()).queue();
*/
return "https://www.youtube.com/watch?v=" + videoId;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
I think you are looking for an EventWaiter.
With JDA-Utilities you can achieve what you want.
You just basically wait for an event, check if it's suitable for the use case of yours (eg: is a specific event, or contains a specific text)
Check out this stackoverflow answer about EventWaiter and adding it as an EventListener.
You would want to check if the received text for example is part of the youtube search result. Also don't forget about having a time limit for accepting answers.

Discord JDA getOnlineStatus() is not checking for online members on the server

I am trying to make a bot that will list all online members on the discord server using JDA. I have used if(m.getOnlineStatus == OnlineStatus.ONLINE) and this did not work - it didn't include a single username. I have tried using .equals() instead of == but that did not work either. I am using an embed builder and adding the names to the description.
However, it is not .getMembers() that is broken as, if I remove the onlineStatus condition from the if statement, it returns all members of the server as it should do.
Here is my code for this command:
if(event.getMessage().getContentRaw().equalsIgnoreCase("!memberList")) {
Guild guild = event.getGuild();
List<Member> users = guild.getMembers();
int playerCount = guild.getMemberCount();
EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("There " + ((playerCount == 1) ? "is " : "are ") + playerCount + " player" + (playerCount == 1 ? "" : "s") + " online!");
for (Member m : users) {
if(!m.getUser().isBot() && m.getOnlineStatus() == OnlineStatus.ONLINE) {
builder.appendDescription(m.getEffectiveName() + "\n");
}
}
builder.setColor(Color.MAGENTA);
builder.setFooter("Requested by " + event.getAuthor().getName());
event.getChannel().sendMessage(builder.build()).complete();
}
My JDABuilder code, JDA 4.2.0:
JDA bot;
try {
bot = JDABuilder.createDefault(DISCORD_TOKEN)
.setChunkingFilter(ChunkingFilter.ALL)
.addEventListeners(new MessageHandler())
.setMemberCachePolicy(MemberCachePolicy.ALL)
.enableIntents(GatewayIntent.GUILD_MEMBERS)
.build();
} catch(LoginException e) {
System.out.println("Oopsie! Someone did a poopsie!");
e.printStackTrace();
}
You need to enable the GUILD_PRESENCES intent to keep track of the online status. Add this to your builder: enableIntents(GatewayIntent.GUILD_PRESENCES) and enable it in your application dashboard.

How to avoid repeating try block

I'm coding a webservice in Java using aws and in many method i need to have a try catch block that can actually log any errors that can occur in the execution of each exposed methods.
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
#WebMethod(operationName = "addObjectToBucket")
public String addObjectToBucket(String bucketName, String objectName, File file) throws IOException{
if ( file == null ){
file = createSampleFile();
}
String message = "";
try {
message += "Uploading a new object to S3 from a file\n";
s3.putObject(new PutObjectRequest(bucketName, objectName, file));
} catch (AmazonServiceException ase) {
message += "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
} catch (AmazonClientException ace) {
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
}
return message;
}
How Can i avoid to repeat this try catch block throw all methods that use this kind of stuff ?
Thanks for your help !
Edit : Actually I modified the code :
private String parseError(AmazonServiceException ase) {
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
private String parseError(AmazonClientException ace) {
String message;
message += "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
#WebMethod(operationName = "listingBucket")
public String listingBucket() {
String message = "";
try {
message = "Listing buckets";
for (Bucket bucket : s3.listBuckets()) {
message += " - " + bucket.getName();
}
} catch (AmazonServiceException exc) {
message += parseError(exc);
} catch (AmazonClientException exc) {
message += parseError(exc);
}
return message;
}
Clearer indeed ! :)
I'll just take a look about the command pattern to see if I can use it for this kind of application.
There are two aspects in here.
One thing is about the code repetition in the catch block; which can be easily turned into something like
public class ExceptionHandler {
public String buildMessageFor(AmazonServiceException ase) {
... }
public String buildMessageFor(AmazonClientException ase) {
... }
...
You can even unit test that thing very easily (where "naming" could be improved; but I guess the example should be good enough to get you going).
That would also make it easier in the future to turn from "pure string" messages into something else. You know, hardcoding user messages in source code is not the smartest thing to do.
The other part, the try/catch itself; somehow depends. You see, the try/catch is an essential part of your operations; so many people would argue that you simply keep that structure in your code. The only alternative would be to define some kind of interface like
public interface RunAmazonOperation {
public void run() throws Amazon...
}
Then you can write down all your operations as little classes implementing that interface; to be called by some framework that does the try/catch for you. If that is worth the price ... depends on your application.
In other words: if you turn to the "command" pattern; you might find it useful to define a variety of "commands"; implementing that interface; thus reducing the number of places with try/catch dramatically.
Just do it with methods. One possibility would look like:
String parseError(AmazonServiceException ase){
String message;
message = "Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.";
message += "Error Message: " + ase.getMessage();
message += "HTTP Status Code: " + ase.getStatusCode();
message += "AWS Error Code: " + ase.getErrorCode();
message += "Error Type: " + ase.getErrorType();
message += "Request ID: " + ase.getRequestId();
return message;
}
String parseError(AmazonClientException ace){
String message;
message = "Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with S3, "
+ "such as not being able to access the network.";
message += "Error Message: " + ace.getMessage();
return message;
}
Now you can just write:
catch(AmazonServiceException exc){
message=parseError(exc);
}
catch(AmazonClientException exc){
message=parseError(exc);
}

Bukkit Coding - Kick message with color codes set in config.yml

So I have a plugin im making where they get kicked with a message. I want that message to be in color that is set in the config.yml. heres my code:
}
if (l == 2) {
settings.getData().set("" + target.getName() + "", null);
settings.saveData();
target.kickPlayer(this.getConfig().getString("BanMessage"));
target.setBanned(true);
Bukkit.getServer().broadcastMessage(ChatColor.RED + target.getName() + " " + "Has been tempbanned for 25 Minutes by " + sender.getName() + "" + "(3/3)");
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
public void run() {
target.setBanned(false);
}
}, 1500 * 20);
return true;
}
Heres my config.yml:
BanMessage: You have been temp banned for 25 Minutes
You could use ChatColor.translateAlternateColorCodes():
String kickMessage = plugin.getConfig().getString("BanMessage");
kickMessage = ChatColor.translateAlternateColorCodes('&', kickMessage);
target.kickPlayer(kickMessage);
target.setBanned(true);
You can use these color codes in your configuration file.
So, putting in &6You have been banned for &4Spamming Will give you ChatColor.GOLD + "You have been banned for " + ChatColor.DARK_RED + " Spamming"
and if you would like to make it so they get that same message whenever they join if they're banned, you can use:
#EventHandler
public void playerJoin(PlayerJoinEvent e){
if(myMethodToCheckIfAPlayerIsTempBanned(e.getPlayer()){
String msg = myMethodToGetPlayersBanMessage(e.getPlayer());
e.getPlayer().kickPlayer(msg);
}
}
This should work:
String kickMessage = this.getConfig().getString("BanMessage");
kickMessage.replaceAll("(?i)&([a-f0-9])", "\u00A7$1");
target.kickPlayer(kickMessage);
target.setBanned(true);
Then, you should be able to use these color codes in your config.
ex.
BanMessage: &3You &0have been banned &1for &425 &3minutes
will display as
You have been temp banned for 25 Minutes

Categories