How to edit an Embed in JDA - java

So I was wondering if I send an Embed for something with my Bot, can I edit it with the Bot afterwards?
If that's possible, then show me how to do it please.
This is my Code that I`ve got so far, but idk how to edit that EmbedBuilder afterwards:
public class Giveaway extends ListenerAdapter {
#Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getMessage().getContentDisplay().startsWith("+giveaway")) {
if (event.getMessage().getContentDisplay().substring(10, 11) != null) {
long msgid = event.getMessageIdLong();
String count = event.getMessage().getContentDisplay().substring(10, 11);
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("It's GIVEAWAY-TIME!");
eb.setDescription("Prize: " + "\n Winners: " + count);
eb.setColor(Color.BLUE);
event.getTextChannel().sendMessage(eb.build()).queue();
}
}
}
}
So to be clear, what I want to do is add a footer to the message afterwards and change the description in some cases.
I have tried some things but I've not come up with a solution yet.
Would be nice if you answer.
Kind regards,
lxxrxtz

You can keep the embed builder and create a new embed:
eb.setFooter(...);
MessageEmbed embed = eb.build();
Then all you have to do is call message.editMessage(embed).queue() with the message you want to edit. You can access the message from the callback in your sendMessage:
channel.sendMessage(embed).queue(message -> {
eb.setFooter(...);
message.editMessage(eb.build()).queue();
});

Related

JDA - Event if new user joined to Guild

I have a problem, I am trying to code a bot using Java Discord API (JDA).
When a new user joins a server, the bot shall send a message, but my code is not working.
Code:
public class UserJoinModule extends ListenerAdapter {
public void onGuildMemberJoined(GuildMemberJoinEvent event) throws LoginException {
String user = event.getMember().getAsMention();
JDA client = new JDABuilder("awesome token").build();
final List<TextChannel> channels = client.getTextChannelsByName("awesome channel name", true);
for (final TextChannel ch : channels) {
ch.sendMessage("New member joined: " + user).queue();
}
}
}
Can someone tell me what is wrong?
For me the issue was not from the listener and method I override.
I believe you have to add GatewayIntent.GUILD_MEMBERS to your JDABuilder.
builder.enableIntents(GatewayIntent.GUILD_MEMBERS);
This fixed the same issue for me.
In your Main.java or whatever the file is, there is a variable of type JDABuilder, on it's same line of code, there is your token, a .build() at the end etc...
Insert this code into that line:
.enableIntents(GatewayIntent.GUILD_MEMBERS)
So it looks like this:
jda = JDABuilder.createDefault("TOKEN").enableIntents(GatewayIntent.GUILD_MEMBERS).build();
For it to work, go to your Discord Developer Portal, click your bot, from the menu on the left, click Bot, then scroll down and enable:
Server Members Intent
There are still noticeable errors like registering a new client on every message and other issues, fix them, then start your bot and it shall work.
Your code should look like this:
public class UserJoinModule extends ListenerAdapter {
#Override // USE THIS WHEN YOU WANT TO OVERRIDE A METHOD
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
String user = event.getMember().getAsMention();
JDA client = event.getJDA(); // DO NOT CREATE A NEW JDA INSTANCE EVERY TIME
List<TextChannel> channels = client.getTextChannelsByName("awesome channel name", true);
for (TextChannel ch : channels) {
ch.sendMessage("New member joined: " + user).queue();
}
}
}
And you must register this listeners in your JDABuilder instance, preferably you only have one of these in your entire codebase. See addEventListeners.
You have 2 problems in your code.
You are creating a new JDA client every time a member joins.
You are sending messages to every channel with that name, in every guild. Not just the guild that the user joined.
Here is what you want to do:
public class UserJoinModule extends ListenerAdapter {
#Override
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
Guild guild = event.getGuild(); // Get the guild that the user joined.
User user = event.getUser(); // Get the user that joined.
JDA client = event.getJDA(); // Get the already existing JDA instance.
List<TextChannel> channels = guild.getTextChannelsByName("awesome channel name", true); // Get the list of channels in the guild that matches that name.
for (TextChannel channel : channels) { // Loops through the channels and sends a message to each one.
channel.sendMessage("New member joined: " + user).queue();
}
}
}

Getting LiveData inside the Repository class and update the Data inside the Database without an endless loop

I'm trying to create an app that only adds an entry to the database if there is no entry already at a specific time intervals and modifies the existing entry if there is already one in the database. I'm using Room.
It works, but only with a workaroud, because I have to call the add function twice before the value gets added (make the input two times before it works). And I also don't like my adding the Observer and immediately removing it afterwards. I also had to implement the workaround when instatiating the DB, with a value when it was first created.
How can I get the data from my LiveData List inside the Repository class and change it without ending up in an endless loop or how do I have to redesign my code to avoid that?
The complete code can be found on my Github account: Github repository
I would really appreciate any suggestion fix my problem and learn to design and plan my code better.
MainActivity
public void ok_clicked(View view) {
Intent intent = new Intent(this, DataActivity.class);
...
Diary addDiary = new Diary(new Date(), diaryCh.isChecked(), readingCh.isChecked(),writingCh.isChecked(),pianoCh.isChecked(),youtubeCh.isChecked());
mDiaryViewModel.insert(addDiary);
startActivity(intent);
}
DiaryViewModel
public void insert(Diary diary) {mRepositroy.add(diary);}
DiaryRepository
public class DiaryRepository {
private DiaryDao mDiaryDao;
private LiveData<List<Diary>> mEntriesToday;
DiaryRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mDiaryDao = db.diaryDao();
mEntriesToday = mDiaryDao.findEntriesByDate(Dates.getYesterdayMidnight(), Dates.getTomdayMidnight());
}
LiveData<List<Diary>> getmEntriesToday() { return mEntriesToday;}
void add(Diary diary) {
Observer<List<Diary>> observerEntriesToday = new Observer<List<Diary>>() {
#Override
public void onChanged(List<Diary> diaries) {
if (diaries != null) {
Log.e(TAG, "add: with matching entries"+ diaries.get(0) + " add: " + diary );
diaries.get(0).addAttributes(diary);
new updateDiaryAsyncTask(mDiaryDao).execute(diaries.get(0));
} else {
Log.e(TAG, "add: without matching entries"+" add: " + diary );
new insertDiaryAsyncTask(mDiaryDao).execute(diary);
}
}
};
getmEntriesToday().observeForever(observerEntriesToday);
getmEntriesToday().removeObserver(observerEntriesToday);
}
You shouldn't be using LiveData in this scenario at all. It is only a wrapper for data that will be observed from Activity/Fragment.
First you need to modify mEntriesToday to be MutableLiveData so you can update it.
In your case, you can omit using Observer for updating DB, and so something simple like:
void add(Diary diary){
if (mEntriesToday.getValue() != null) {
Log.e(TAG, "add: with matching entries"+ mEntriesToday.getValue().get(0) + " add: " + diary );
mEntriesToday.getValue().get(0).addAttributes(diary);
new updateDiaryAsyncTask(mDiaryDao).execute(mEntriesToday.getValue().get(0));
} else {
Log.e(TAG, "add: without matching entries"+" add: " + diary );
new insertDiaryAsyncTask(mDiaryDao).execute(diary);
}
}
If you need this data, outside this class, then you can use getmEntriesToday() and observe it.
You can get the value of the LiveData using the getValue() method
void add(Diary diary) {
List<Diary> diaries = mEntriesToday.getValue();
if(diaries!=null){
diaries.get(0).addAttributes(diary);
//update
}else{
//insert
}

Discord java bot verify user by name

in my current Discord (java) bot im trying to apply a command to a user name. how can i make sure this is an actual existing user ?
in psuedo code:
if User "A" exists {
User "A" types something at all
send message "hello"+ user "A"
}
else
{
this is no valid user;
}
i can't figure out how to write the 'check if exist code'.
This is from JDA-Utilities which is a really useful tool when building discord bots.
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandEvent;
public class Example extends Command {
public Example() {
this.name = "'isBot";
this.help = "Tells you if the user is a bot!";
}
#Override
protected void execute(CommandEvent e) {
if (e.getAuthor().isBot()) {
e.reply("Hey you're not a person!!");
} else {
e.reply("Hey " + e.getAuthor().getName() + ", you're not a bot!");
}
}
}

Parse to Clevertap Transition

I am trying to convert Parse to Clevertap in the application I'm working on. I have tried looking at https://blog.clevertap.com/transitioning-from-parse-push-notifications/ but haven't had much luck on what I'm trying to accomplish.
In the method that needs to be converted, I am wanting the user to have the ability to subscribe and unsubscribe from a channel using:
private class AllPushClickListener implements View.OnClickListener {
private AppFeed mAppFeed;
public AllPushClickListener(AppFeed appFeed) {
mAppFeed = appFeed;
}
#Override
public void onClick(View v) {
Log.d(TAG, "subscribing to " + getPushChannelName(mAppFeed) + "_all");
ParsePush.unsubscribeInBackground(getPushChannelName(mAppFeed) + "_top");
ParsePush.subscribeInBackground(getPushChannelName(mAppFeed) + "_all");
mAppFeed.setPushNotificationsOn(true);
mAppFeed.setReceiveTopNotifications(false);
mAppFeed.setChannelName(getPushChannelName(mAppFeed) + "_all");
hideNotificationButtons();
mPushAllStoriesSelectedButton.setVisibility(View.VISIBLE);
mPersistedFeedDaoHelper.createOrUpdate(mAppFeed);
}
}
Not sure how to transition this into Clevertap.
Thanks for the help.
You can find the Parse migration guide here - https://github.com/CleverTap/parse-migrate and, channels is discussed here - https://github.com/CleverTap/parse-migrate#managing-channels. Do write to support#clevertap.com if you need more help, or have any questions.

zk: after confirmation box, page refresh issue, binder not working

I was successfully deleting selected items from listbox and after that all objects were deleted from db and listbox was refreshed.
then i added the confirmation box with yes and no option, then my list wasn't refreshed. i saw this thread with similar problem on zk forum with a solution, i implemented it but getting the class cast exception
I am using MVVM
http://forum.zkoss.org/question/73640/refreshing-listbox-after-deleting-an-itemrow/
code getting the exception:
AnnotateDataBinder binder = (AnnotateDataBinder) userWin.getAttribute("binder");
binder.loadAll();
exception:
Mar 21, 2013 5:22:23 PM org.zkoss.zk.ui.impl.UiEngineImpl handleError:1352
SEVERE: >>java.lang.ClassCastException: org.zkoss.bind.AnnotateBinder cannot be cast to org.zkoss.zkplus.databind.AnnotateDataBinder
looking forward to hear from you. I have searched the net, but couldn't find anything but updating the zk. i am already using the latest version of zk 6.5.1.1.
thanks in advance.
#after adding your suggested line of code, my list was not updated, here is my method
#Override
#Command("deleteAllSelected")
#NotifyChange({"selectedObject","objectList"})
public void deleteAllSelected() {
logger.info("in deleteAllSelected()>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
logger.info("direct selection: " + objectList.getSelection());
final Set<UserIntelliopsDTO> setMe = objectList.getSelection();
logger.info("selectedion size in dellete all" + setMe.size());
EventListener<ClickEvent> clickListener = new EventListener<Messagebox.ClickEvent>() {
public void onEvent(ClickEvent event) throws Exception {
if (Messagebox.Button.YES.equals(event.getButton())) {
int i =0;
for(UserIntelliopsDTO dto:setMe){
userService.deleteUserIntelliops(dto.getUserIntelliOps().getUserId());
logger.info("siapa:userIntelliops " + dto.getUserIntelliOps() + dto.getUserIntelliOps().getUserId());
selectedObject = null;
logger.info("iteration: " + i);
++i;
}
selectedObject = null;
deleteAllSelectedButton.setVisible(false);
enableEditMode(true);
}
}
};
Messagebox.show("Are you sure you want to delete all selected records?", "Delete All Selected",
new Messagebox.Button[] { Messagebox.Button.YES,
Messagebox.Button.NO }, Messagebox.QUESTION,
clickListener);
BindUtils.postNotifyChange(null, null, this, "*");
}
I am assuming you are using MVVM Model..So you can do this thing when you will click on delete button below method will code...
#Command
public void doDeleteItems(#ContextParam(ContextType.VIEW) Component view) {
logger.debug("Delete Icon selected");
if (myModel.getSelectedListItem() == null || myModel.getSelectedListItem().isEmpty()) {
showError("No rows are selected");
} else {
Messagebox.show("Are you sure you want to delete?", "Alert !!", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION,new org.zkoss.zk.ui.event.EventListener() {
public void onEvent(Event evt) throws InterruptedException {
if (evt.getName().equals("onYes")) {
//Add code for Deletion
if (listModel.contains(deletedObj))
listModel.remove(deletedObj);
}
else{
//Do somthing else
}
BindUtils.postNotifyChange(null, null, this, "*");//this means current viewmodel object and refresh the variables
}
As i did BindUtils.postNotifyChange() it will do magic for you refreshing the list or you can use NotifyChange("*")
One more thing you have to do here remove object from list after deleting the record...

Categories

Resources