`public class VerificationSystem extends ListenerAdapter {
#Override
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
System.out.println("WORKS!");
String memberName = event.getMember().getEffectiveName();
Member member = event.getMember();
event.getGuild().addRoleToMember(member,event.getGuild().getRoleById("1034143551568752682")).queue(); //Grants the new member "Unverified" role
TextChannel textChannel = event.getGuild().createTextChannel("Verification for: " + memberName).complete(); // Creates new verification channel
textChannel.getManager().getChannel().upsertPermissionOverride(event.getMember()).setAllowed(Permission.VIEW_CHANNEL).queue(); // Grants the new member view permissions to the channel
textChannel.getManager().getChannel().upsertPermissionOverride(event.getGuild().getRoleById("1034143551568752682")).setDenied(Permission.VIEW_CHANNEL).queue(); // Revokes the view permission for #everyone
}`
The event register:
JDA jda = JDABuilder.createDefault(token)
.setActivity(Activity.playing("Football Manager"))
.addEventListeners(new VerificationSystem())
.build().awaitReady();
For some reason this method does not work. It is correctly registered, and it does not work whenever someone joins the server. Please help, this is killing me!!
Since one of updates Discord added such thing as "Intents". Now all developers have to specify what kind of data their bots need.
To accept events of members' joining you need to use intent "GUILD_MEMBERS". Note that this intent is priveleged, what means you can use it easily until your bot reaches 100 servers, then you must get verification from Discord.
To enable intents in bot visit Developers portal
To enable intents in JDA use enableIntents method in builder.
JDA jda = JDABuilder.createDefault(token)
.setActivity(Activity.playing("Football Manager"))
.addEventListeners(new VerificationSystem())
// Enables GUILD_MEMBERS intent
.enableIntents(GatewayIntent.GUILD_MEMBERS)
.build().awaitReady();
Related
NOTE: I'm aware that this question somehow can be a duplicate. Still I'm asking this as I found no tutorial or any proper answer for the above question.
I'm making an app which has a feature that user can block the notifications. The user can select either to block all the notifications or block only selected apps. To select apps for blocking notifications I have created a RecyclerView where user can choose which app to be blocked, and to block all notifications there is a master switch. The android Rooms are used to save data even after the activity is destroyed.
Following is a screenshot of the app.
All I need to know is how can I implement the NotificationListenerService in order to block notifications. As I mentioned before I want only to block notifications when the app is selected in the RecyclerView or the Block all notifications, master switch is turned on. Anyone who can give me a proper guide is appreciated.
PS: There are 8 files in the project and I have no idea how to post them here, any solutions for that also?
I found a way! Obviously I created a NotificationListener class which extends the NotificationListenerService class and then override the onNotificationPosted(StatusBarNotification sbn) function.
To block all the notifications I created a variable in MainActivity.java named public static boolean BLOCK_ALL = false;. This variable would change as the Block All Notification switch in the screenshot changed.
SwitchMaterial blockAllNotifications = findViewById(R.id.blockAllNotifications);
blockAllNotifications.setChecked(BLOCK_ALL);
blockAllNotifications.setOnCheckedChangeListener((buttonView, isChecked) -> {
BLOCK_ALL = isChecked;
});
And in the onNotificationPosted(StatusBarNotification sbn) function in the NotificationListener I added following condition;
if(MainAcitivity.BLOCK_ALL)cancelAllNotifications();
Whenever the Block All Notifiction switch is turned on it's going to call cancelAllNotification() function and block all the notifications.
At last in order to block notifications of each package I did something as follow. As I mentioned in the question, I have all the apps whose switch is turned on in a Room named BlockedList. Therefore I added a logic; if the package which has posted the notification is in the BlockedList I blocked that app's notifications with cancelNotification(String key).
appNameList = appsDB.dbDAO().getAllAppNames();
if(appNameList.contains(getApplicationName(sbn.getPackageName()))){ // if the blocked list has the app name of the notification
cancelNotification(sbn.getKey());
}
/***
* getApplicationName: get the application name of the notification belongs to
* #param pack: the package name; a StatusBarNotification.getPackageName()
* #return
*/
private String getApplicationName(String pack){
final PackageManager pm = context.getPackageManager();
ApplicationInfo appInfo;
try{
appInfo = pm.getApplicationInfo(pack, 0); // getting the application info
}catch(PackageManager.NameNotFoundException e){
appInfo = null;
}
final String appName = (String) (appInfo != null? pm.getApplicationLabel(appInfo) : "(unknown)"); // if the appInfo is not null get the label of the Application
return appName;
}
Every notification(StatusBarNotification) has its own packagename,
public String getPackageName() {
return pkg;
}
I think you can block it through StatusBarNotification attribute
I am coding a feedback feature in my Discord Bot, when someone leaves, they should be DMed a message asking why they left.
event.getUser().openPrivateChannel()
.flatMap(channel -> channel.sendMessage("Hello, we are sorry you're leaving "+event.getGuild().getName()+", if you don't mind, please tell us why you left or leave any other feedback here, it'll help us improve the server and improve experience for you if you re-join again in the future.\n\nThank you ❤."))
.queue();
The code above is responsible for sending it, I tried to create a state machine in a private channel but it didn't work:
import bot.Main;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class Feedback extends ListenerAdapter {
private final long channelId, authorId;
public Feedback(MessageChannel channel, User author) {
this.channelId = channel.getIdLong();
this.authorId = author.getIdLong();
}
#Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getAuthor().isBot()) return;
if (event.getAuthor().getIdLong() != authorId) return;
if (event.getChannel().getIdLong() != channelId) return;
MessageChannel channel = event.getChannel();
String content = event.getMessage().getContentRaw();
event.getChannel().sendMessage("Thanks for your feedback!").queue();
EmbedBuilder feedback = new EmbedBuilder();
feedback.setTitle("Automated System Operations - Leaving Feedback");
feedback.addField("Feedback", content, false);
feedback.setColor(0xC90004);
feedback.setAuthor(event.getAuthor().getAsTag()+" - "+event.getAuthor().getId(), "https://support.discord.com/hc/en-us/articles/209572128-How-do-I-log-out-", event.getAuthor().getAvatarUrl());
feedback.setImage("https://media.discordapp.net/attachments/894913784823566428/896323821336948736/unknown.png?width=384&height=192");
Main.jda.getGuildById("894913620868202506").getTextChannelById("896322509874540545").sendMessage(feedback.build()).queue();
}
}
I got this event state-machine channel but I don't know how to addListener to it in DMs.
Any help is accepted <3
You can add the state machine event listener with JDA#addEventListener:
event.getUser().openPrivateChannel().flatMap(channel -> {
event.getJDA().addEventListener(new Feedback(channel, event.getUser()));
return channel.sendMessage("hello");
}).queue();
I would recommend to remove your event listener after you received that response with event.getJDA().removeEventListener(this);
You never have to guess how to use a library - that's what documentation is for. Any library worth its salt has documentation listing every single class, method, and the property you need to worry about.
A quick google search for "discord-jda docs" takes us to the JavaDoc: https://ci.dv8tion.net/job/JDA/javadoc/index.html
You want to send a message to a user, right? So let's use the search bar and find User. First result under Types is net.dv8tion.jda.API.entities.User. We're now at https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/entities/User.html
If you want to know how to do something with a user, we look at the Methods every User has. Two catch my eye right away: User.hasPrivateChannel() and User.openPrivateChannel(). We'll click the second one since it looks relevant.
Lo and behold, the docs have example usage! I'll quote it below:
// Send message without response handling
public void sendMessage(User user, String content) {
user.openPrivateChannel()
.flatMap(channel -> channel.sendMessage(content))
.queue();
}
This seems pretty straightforward. So the basic usage you're looking for (assuming event is a MessageReceivedEvent) is this:
event.getAuthor().openPrivateChannel().flatMap(channel -> channel.sendMessage("hello")).queue();
I tried tracking if people on the bots guild change activities (like starting to play a game)
After reading the javadoc I found out:
GatewayIntent.GUILD_PRESENCES
CacheFlag.ACTIVITY
MemberCachePolicy.ONLINE (therefore GatewayIntent.GUILD_MEMBERS)
must be active.
so thats my Main:
JDABuilder builder = JDABuilder.createDefault(token);
builder.enableIntents(GatewayIntent.GUILD_PRESENCES);
builder.enableIntents(GatewayIntent.GUILD_MEMBERS);
builder.enableCache(CacheFlag.ACTIVITY);
builder.setMemberCachePolicy(MemberCachePolicy.ONLINE);
builder.setChunkingFilter(ChunkingFilter.ALL);
this.jda = builder.build();
jda.addEventListener( new ActivityListener(jda));
And this my Listener:
public class ActivityListener extends ListenerAdapter {
private final JDA jda;
public ActivityListener(JDA jda) {
this.jda = jda;
}
#Override
public void onUserUpdateActivities(#NotNull UserUpdateActivitiesEvent event) {
super.onUserUpdateActivities(event);
System.out.println(event.getUser().getAsTag() + " " + event.getUser().getIdLong());
}
}
Sadly when I or someone else starts a game or smt else it never triggers.
Edit:
I used jda.getUserCache(); to check if the caching worked and I am i the cache, but it still doesn't work.
The members for the associated users have to be cached before the event fires. Since you use lazy loading this might take a while to happen since members are added to cache through messages or voice states.
You can use setChunkingFilter(ChunkingFilter.ALL) to eagerly load all members on startup.
There was a bug which caused these events to not fire which has been fixed in 4.2.1_264.
the UserUpdateActivitiesEvent requires the GuildPresence intent to be enabled. You enabled it in your code, but it has to also be enabled on the discord api website at https://discord.com/developers/applications -> Your Application -> Bot -> Enable Presence Intent
I'm making a JDA (Java Discord API) program that needs to check if a message was sent by the bot itself. How can I achieve this? I thought about checking if the user ID of the message sender equals the bot's user ID, but how can I get the user ID of the bot itself in the program?
If you use the MessageReceivedEvent, you can just check if the sender is a bot by using:
event.getAuthor.isBot().
You can access the user of the bot itself by accessing JDA and calling getSelfUser() as follows with the MessageReceivedEvent in mind:
event.getJDA().getSelfUser()
On the SelfUser you can call SelfUser#getId() or SelfUser#getIdLong() to access the ID.
Example Code
public class Listener extends ListenerAdapter {
#Override
public void onMessageReceived(MessageReceivedEvent event) {
boolean isBot = event.getAuthor().isBot() //Check if the Message Sender is a bot
long id = event.getJDA().getSelfUser().getIdLong() //the bot ID
}
}
I have written the following methods and they both are not working. Anyone know why and how to fix it?
PS: The bot has admin perms.
public class GuildMemberJoin extends ListenerAdapter {
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
EmbedBuilder join = new EmbedBuilder();
join.setColor(Color.getHSBColor(227, 74, 64));
join.setTitle("SERVER UPDATE");
join.setDescription(event.getMember().getAsMention() + " has now joined The server!");
event.getGuild().getDefaultChannel().sendMessage(join.build()).queue();
}
public class GuildMemberLeave extends ListenerAdapter {
public void onGuildMemberLeave(GuildMemberLeaveEvent event) {
EmbedBuilder join = new EmbedBuilder();
TextChannel spamChannel = event.getGuild().getTextChannelById("713429117546135572");
join.setColor(Color.getHSBColor(227, 74, 64));
join.setTitle("SERVER UPDATE");
join.setDescription(event.getMember().getAsMention() + " has now left the server!");
spamChannel.sendMessage(join.build()).queue();
}
Default channel settings
To quote the JDA Wiki:
There are many reasons why your event listener might not be executed but here are the most common issues:
You are using the wrong login token?
If the token is for another bot which doesn't have access to the desired guilds then the event listener code cannot run.
Your bot is not actually in the guild?
Make sure your bot is online and has access to the resource you are trying to interact with.
You never registered your listener?
Use jda.addEventListener(new MyListener()) on either the JDABuilder or JDA instance
You did not override the correct method?
Use #Override and see if it fails. Your method has to use the correct name and parameter list defined in ListenerAdapter.
You don't actually extend EventListener or ListenerAdapter.
Your class should either use extends ListenerAdapter or implements EventListener.
You are missing a required GatewayIntent for this event.
Make sure that you enableIntents(...) on the JDABuilder to allow the events to be received.
The event has other requirements that might not be satisfied such as the cache not being enabled.
Please check the requirements on the event documentation.
If none of the above apply to you then you might have an issue in your listener's code, at that point you should use a debugger.
For clarification:
You can enable the GUILD_MEMBERS intent by doing builder.enableIntents(GatewayIntent.GUILD_MEMBERS) on JDABuilder.
For example:
JDABuilder builder = JDABuilder.createDefault(token);
builder.enableIntents(GatewayIntent.GUILD_MEMBERS);
builder.addEventListeners(myListener);
JDA jda = builder.build();
See also: Gateway Intents and Member Cache Policy