I want to send a status update-message when an admin goes online, idle, .... offline. My Code is working but there is a bug.
The bot will send update-messages for all users on the server .. i just want to get status updates of admins ..
This is my code:
public class LoginMessageListener extends ListenerAdapter {
public void onUserUpdateOnlineStatus(UserUpdateOnlineStatusEvent event) {
OnlineStatus os = event.getGuild().getMember(event.getUser()).getOnlineStatus();
if (event.getGuild().getRoleById("628650613152153640") != null) {
TextChannel channel = event.getGuild().getTextChannelById("628645905955815454");
EmbedBuilder builder = new EmbedBuilder();
builder.setThumbnail("http://i.epvpimg.com/t43Pfab.gif");
builder.setFooter("Powered by Backxtar.");
builder.setTimestamp(OffsetDateTime.now());
builder.setColor(0xf22613);
builder.setDescription("Admin **" + event.getUser().getAsMention() + "** is now **" + os + "**!\nI'm __always available__ for questions,\nsuggestions or problems!\n:point_right: [**Da Hood - Join NOW!**](https://discord.gg/xyz) :point_left:");
channel.sendMessage(builder.build()).complete().delete().queueAfter(15, TimeUnit.SECONDS);
}
else {
return;
}
}
}
Your check with if (event.getGuild().getRoleById("628650613152153640") != null) only checks if the role exists in the server. To check if the user has the role you have to check the roles with event.getMember():
private static boolean isAdmin(Member member) {
return member.getRoles().stream()
.mapToLong(Role::getIdLong) // we check by id
.anyMatch(id -> id == 628650613152153640L); // true if any role has that id
}
#Override
public void onUserUpdateOnlineStatus(UserUpdateOnlineStatusEvent event) {
OnlineStatus os = event.getGuild().getMember(event.getUser()).getOnlineStatus();
if (isAdmin(event.getMember())) {
// code
}
// the else here is unnecessary
}
Related
I am trying to save a new document to MongoDB using the Vertx MongoClient as follows:
MongoDBConnection.mongoClient.save("booking", query, res -> {
if(res.succeeded()) {
documentID = res.result();
System.out.println("MongoDB inserted successfully. + document ID is : " + documentID);
}
else {
System.out.println("MongoDB insertion failed.");
}
});
if(documentID != null) {
// MongoDB document insertion successful. Reply with a booking ID
String resMsg = "A confirmed booking has been successfully created with booking id as " + documentID +
". An email has also been triggered to the shared email id " + emailID;
documentID = null;
return new JsonObject().put("fulfillmentText", resMsg);
}
else {
// return intent response
documentID = null;
return new JsonObject().put("fulfillmentText",
"There is some issues while booking the shipment. Please start afreash.");
}
The above code successfully writes the query jsonObject to MongoDB collection booking. However, the function which contains this code always returns with There is some issues while booking the shipment. Please start afreash.
This is happening probably because the MongoClient save() handler "res" is asynchronous. But, I want to return conditional responses based on successful save() operation and on failed save operation.
How to achieve it in Vertx Java?
Your assumption is correct, you dont wait for the async response from the database. What you can do, is to wrap it in a Future like this:
public Future<JsonObject> save() {
Future<JsonObject> future = Future.future();
MongoDBConnection.mongoClient.save("booking", query, res -> {
if(res.succeeded()) {
documentID = res.result();
if(documentID != null) {
System.out.println("MongoDB inserted successfully. + document ID is : " + documentID);
String resMsg = "A confirmed booking has been successfully created with booking id as " + documentID +
". An email has also been triggered to the shared email id " + emailID;
future.complete(new JsonObject().put("fulfillmentText", resMsg));
}else{
future.complete(new JsonObject().put("fulfillmentText",
"There is some issues while booking the shipment. Please start afreash."))
}
} else {
System.out.println("MongoDB insertion failed.");
future.fail(res.cause());
}
});
return future;
}
Then i assume you have and endpoint that eventually calls this, eg:
router.route("/book").handler(this::addBooking);
... then you can call the save method and serve a different response based on the result
public void addBooking(RoutingContext ctx){
save().setHandler(h -> {
if(h.succeeded()){
ctx.response().end(h.result());
}else{
ctx.response().setStatusCode(500).end(h.cause());
}
})
}
You can use RxJava 2 and a reactive Mongo Client (io.vertx.reactivex.ext.mongo.MongoClient)
Here is a code snippet:
Deployer
public class Deployer extends AbstractVerticle {
private static final Logger logger = getLogger(Deployer.class);
#Override
public void start(Future<Void> startFuture) {
DeploymentOptions options = new DeploymentOptions().setConfig(config());
JsonObject mongoConfig = new JsonObject()
.put("connection_string",
String.format("mongodb://%s:%s#%s:%d/%s",
config().getString("mongodb.username"),
config().getString("mongodb.password"),
config().getString("mongodb.host"),
config().getInteger("mongodb.port"),
config().getString("mongodb.database.name")));
MongoClient client = MongoClient.createShared(vertx, mongoConfig);
RxHelper.deployVerticle(vertx, new BookingsStorage(client), options)
.subscribe(e -> {
logger.info("Successfully Deployed");
startFuture.complete();
}, error -> {
logger.error("Failed to Deployed", error);
startFuture.fail(error);
});
}
}
BookingsStorage
public class BookingsStorage extends AbstractVerticle {
private MongoClient mongoClient;
public BookingsStorage(MongoClient mongoClient) {
this.mongoClient = mongoClient;
}
#Override
public void start() {
var eventBus = vertx.eventBus();
eventBus.consumer("GET_ALL_BOOKINGS_ADDRESS", this::getAllBookings);
}
private void getAllBookings(Message msg) {
mongoClient.rxFindWithOptions("GET_ALL_BOOKINGS_COLLECTION", new JsonObject(), sortByDate())
.subscribe(bookings -> {
// do something with bookings
msg.reply(bookings);
},
error -> {
fail(msg, error);
}
);
}
private void fail(Message msg, Throwable error) {
msg.fail(500, "An unexpected error occurred: " + error.getMessage());
}
private FindOptions sortByDate() {
return new FindOptions().setSort(new JsonObject().put("date", 1));
}
}
HttpRouterVerticle
// inside a router handler:
vertx.eventBus().rxSend("GET_ALL_BOOKINGS_ADDRESS", new JsonObject())
.subscribe(bookings -> {
// do something with bookings
},
e -> {
// handle error
});
i have below code that gets executed when an admin is creating or deleting a user in the keycloak UI.
Through the help of the adminEvent: http://www.keycloak.org/docs/3.0/server_admin/topics/events/admin.html
Creating a user returns the user details via adminEvent.getRepresentation().
However when deleting a user returns me a null.
This is also the same when deleting a role, deleting a group or deleting a user_session.(ResourceTypes)
My question is how can i retrieve the deleted details?
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.models.UserModel;
public void handleResourceOperation(AdminEvent adminEvent, UserModel user) {
MQMessage queueMessage = new MQMessage();
queueMessage.setIpAddress(adminEvent.getAuthDetails().getIpAddress());
queueMessage.setUsername(user.getUsername());
switch (adminEvent.getOperationType()) {
case CREATE:
LOGGER.info("OPERATION : CREATE USER");
LOGGER.info("USER Representation : " + adminEvent.getRepresentation());
String[] split = adminEvent.getRepresentation().split(",");
queueMessage.setTransactionDetail("Created user " + split[0].substring(12));
sendQueueMessage(adminEvent, queueMessage);
break;
case DELETE:
LOGGER.info("OPERATION : DELETE USER");
LOGGER.info("USER Representation : " + adminEvent.getRepresentation());
queueMessage.setTransactionDetail("User has been deleted.");
sendQueueMessage(adminEvent, queueMessage);
break;
}
I'm not sure you got the answer by now. Sharing the solution that may be helpful for others. User details can be captured in postInit method of EventListenerProviderFactory as below,
public class UserEventListenerProviderFactory implements EventListenerProviderFactory {
#Override
public EventListenerProvider create(KeycloakSession keycloakSession) {
return new UserEventListenerProvider(keycloakSession);
}
#Override
public void init(Config.Scope scope) {
}
#Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
keycloakSessionFactory.register(
(event) -> {
if (event instanceof UserModel.UserRemovedEvent) {
UserModel.UserRemovedEvent dEvent = (UserModel.UserRemovedEvent) event;
//TODO YOUR LOGIC WITH `dEvent.getUser()`
}
});
}
#Override
public void close() {
}
#Override
public String getId() {
return "sample_event_listener";
}
}
smack presence listener in multi user chat not getting called. Used Smack Api to login and then added roster.addRosterListener(mRoasterListener); but could not get any success to listen when presence of other user of the chat room changes. I tried following code to get the presence listener to work :
connection.login(loginUser, passwordUser);
MultiUserChatManager manager =
MultiUserChatManager.getInstanceFor(connection);
muc = manager.getMultiUserChat(roomID + "#" +context.getString(R.string.group_chat_id));
Log.d("Join User: ", "Already Created");
muc.join(Utilities.getUserPhoneNo(context));
muc.addMessageListener(mGroupMessageListener);
Roster roster = Roster.getInstanceFor(connection);//luna
roster.addRosterListener(mRoasterListener);//roasterListener
Log.d("Joined User Phone: ", " " + Utilities.getUserPhoneNo(context));
and this class to listen for presence change...
public class RoasterListener implements RosterListener{
public RoasterListener(Context context){
}
#Override
public void entriesAdded(Collection<String> collection) {
}
#Override
public void entriesUpdated(Collection<String> collection) {
}
#Override
public void entriesDeleted(Collection<String> collection) {
}
#Override
public void presenceChanged(Presence presence) {
System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
}
}
I tried many links available by stackoverflow but could not get any success.
Please Help!
For Multi User Chat you don't have to use Roster, because it's normal to meet people you don't have in Roster.
To know who is in a muc, first ask for occupants:
muc.join(user,password);
List<String> occupantsAtJoinTime = muc.getOccupants();
for (String occupant : occupantsAtJoinTime)
{
System.out.println("occupant: "+occupant);
//actions
}
then, to keep Occupants list updated, register a DefaultParticipantStatusListener to your muc and define that Listner:
muc.addParticipantStatusListener(new CustomParticipantStatusListner());
definied as (there are many methods to implement if you need):
public class CustomParticipantStatusListner extends DefaultParticipantStatusListener
{
public void joined(String participant)
{
System.out.println(participant + "just joined MUC");
//actions (add occupantsRightNow)
}
public void left(String participant)
{
System.out.println(participant + " just left MUC");
//actions (remove occupantsRightNow)
}
}
All this with smack 4.1.7
It's about the Manage role modifications in Multi User Chat.
This example shows how to grant voice to a visitor and listen for the notification events:
// User1 creates a room
muc = new MultiUserChat(conn1, "myroom#conference.jabber.org");
muc.create("testbot");
// User1 (which is the room owner) configures the room as a moderated room
Form form = muc.getConfigurationForm();
Form answerForm = form.createAnswerForm();
answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
muc.sendConfigurationForm(answerForm);
// User2 joins the new room (as a visitor)
MultiUserChat muc2 = new MultiUserChat(conn2, "myroom#conference.jabber.org");
muc2.join("testbot2");
// User2 will listen for his own "voice" notification events
muc2.addUserStatusListener(new DefaultUserStatusListener() {
public void voiceGranted() {
super.voiceGranted();
...
}
public void voiceRevoked() {
super.voiceRevoked();
...
}
});
// User3 joins the new room (as a visitor)
MultiUserChat muc3 = new MultiUserChat(conn3, "myroom#conference.jabber.org");
muc3.join("testbot3");
// User3 will lister for other occupants "voice" notification events
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
public void voiceGranted(String participant) {
super.voiceGranted(participant);
...
}
public void voiceRevoked(String participant) {
super.voiceRevoked(participant);
...
}
});
// The room's owner grants voice to user2
muc.grantVoice("testbot2");
Details can be refered in http://web.mit.edu/svalente/lib/smack_3_0_4/documentation/extensions/muc.html .
Firstly, join a chat room:
public MultiUserChat joinMultiUserChat(String user, String roomsName,
String password) {
if (getConnection() == null)
return null;
try {
MultiUserChat muc = new MultiUserChat(getConnection(), roomsName
+ "#conference." + getConnection().getServiceName());
DiscussionHistory history = new DiscussionHistory();
history.setMaxChars(0);
// history.setSince(new Date());
muc.join(user, password, history,
SmackConfiguration.getPacketReplyTimeout());
Log.i("MultiUserChat", "Chat room【"+roomsName+"】joined........");
return muc;
} catch (XMPPException e) {
e.printStackTrace();
Log.i("MultiUserChat", "Chat room【"+roomsName+"】failed........");
return null;
}
}
Then, use MultiChatUser to send Message:
try {
multiUserChat.sendMessage(message);
} catch (XMPPException e) {
e.printStackTrace();
}
Add a Listener:
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
public class TaxiMultiListener implements PacketListener {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
String body = message.getBody();
}
}
Finally, call the Listener using MultiUserChat:
multiUserChat.addMessageListener(new TaxiMultiListener());
I have created a .NET backend Mobile Service on Windows Azure using the code sample provided on the website article.
Now I am trying to register a user with android client but I can't.
My backend registration control looks like below;
[AuthorizeLevel(AuthorizationLevel.Anonymous)]
public class CustomRegistrationController : ApiController
{
public ApiServices Services { get; set; }
// POST api/CustomRegistration
public HttpResponseMessage Post(RegistrationRequest registrationRequest)
{
if (!Regex.IsMatch(registrationRequest.username, "^[a-zA-Z0-9]{4,}$"))
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid username (at least 4 chars, alphanumeric only)");
}
else if (registrationRequest.password.Length < 8)
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid password (at least 8 chars required)");
}
hadContext context = new hadContext();
Account account = context.Accounts.Where(a => a.Username == registrationRequest.username).SingleOrDefault();
if (account != null)
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Username already exists");
}
else
{
byte[] salt = CustomLoginProviderUtils.generateSalt();
Account newAccount = new Account
{
Id = Guid.NewGuid().ToString(),
Username = registrationRequest.username,
Salt = salt,
SaltedAndHashedPassword = CustomLoginProviderUtils.hash(registrationRequest.password, salt)
};
context.Accounts.Add(newAccount);
context.SaveChanges();
return this.Request.CreateResponse(HttpStatusCode.Created);
}
}
}
I wrote this code on android client app
public void register(View view) {
if ( txtUsername.getText().toString().equals("")
&& txtPassword.getText().toString().equals(""))
{
Log.w(TAG,"tüm alanları girmen gerek");
return;
}
else
{
RegistrationRequest register = new RegistrationRequest();
register.setUsername(txtUsername.getText().toString());
register.setPassword(txtUsername.getText().toString());
mClient.invokeApi("CustomRegistration",register,RegistrationRequest.class,
new ApiOperationCallback<RegistrationRequest>() {
#Override
public void onCompleted(RegistrationRequest result, Exception exception, ServiceFilterResponse response) {
if (exception==null)
{
Log.w(TAG,"kayıt başarılı");
}
else
{
Log.w(TAG,"kayıt başarısız " +exception);
}
}
});
}
}
It's not working. How should I do for registration.
I am new to this OpenFire and asmack, i want the user to have a functionality of Multi Users Chatting so i searched around and i found MUC i have implemented this for creating a room and sending invitation to other users these works, other user receives the invitation but the other user is not able to join the room.
I am doing this on other user invitation receiving
Here connection is the connection of this user and room is the room name that we getting in invitation.
MultiUserChat muc3 = new MultiUserChat(connection,room);
muc3.join("testbot3");
testbot3 is just some random name.
But this throws 404 error.
Do i need to join the user before sending the invitation i.e if A user sending invitation to B , before invitation sent do A needs to join these users by default to room and then it depends on B to decline or just keep quite.
What i am doing is B receives invitation from A in that InvitationListner of B i am trying to join with the above code.
I have been trying for long now i am not sure what is going wrong, some one can give a sample code of how to do this it would be great help for me.
Thanks
Here is more information on my issue
As i go and check on Openfire i can see the room created by the user and he has been added himself as an owner so i dont think so it would be an issue with room getting created.
May be this can be an issue with room getting locked, as i have read through the room is locked when the room is not completely created , i guess this is an issue with form filling when we create the room, i am not filling in the password in the form can this be an issue ?
Please see the following code below inside the handler i am calling a method "checkInvitation" which does the same as above code posted still i get 404. Can you please tell me what i wrong in my code.
Do the nickname that needs to be added can be anything or it needs to something user specific ?
public void createChatroom(){
MultiUserChat muc = null;
try {
muc = new MultiUserChat(connection, "myroom#conference.localhost");
muc.create("testbot");
// Get the the room's configuration form
Form form = muc.getConfigurationForm();
// Create a new form to submit based on the original form
Form submitForm = form.createAnswerForm();
// Add default answers to the form to submit
for (Iterator fields = form.getFields(); fields.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
// Sets the default value as the answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
// Sets the new owner of the room
List owners = new ArrayList();
owners.add("admin#localhost");
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
// Send the completed form (with default values) to the server to configure the room
muc.sendConfigurationForm(submitForm);
muc.join("d");
muc.invite("b#localhost", "Meet me in this excellent room");
muc.addInvitationRejectionListener(new InvitationRejectionListener() {
public void invitationDeclined(String invitee, String reason) {
// Do whatever you need here...
System.out.println("Initee "+invitee+" reason"+reason);
}
});
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message
.getFrom());
Log.i("XMPPClient", "Got text [" + message.getBody()
+ "] from [" + fromName + "]");
messages.add(fromName + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
checkInvitation();
}
});
}
}
}, filter);
mHandler.post(new Runnable() {
public void run() {
checkInvitation();
}
});
}
}
The 404 error indicates that:
404 error can occur if the room does not exist or is locked
So, ensure that your room is not locked or existed! The code below is how I join the room when there's an in-comming invitation:
private void setChatRoomInvitationListener() {
MultiUserChat.addInvitationListener(mXmppConnection,
new InvitationListener() {
#Override
public void invitationReceived(Connection connection,
String room, String inviter, String reason,
String unKnown, Message message) {
//MultiUserChat.decline(mXmppConnection, room, inviter,
// "Don't bother me right now");
// MultiUserChat.decline(mXmppConnection, room, inviter,
// "Don't bother me right now");
try {
muc.join("test-nick-name");
Log.e("abc","join room successfully");
muc.sendMessage("I joined this room!! Bravo!!");
} catch (XMPPException e) {
e.printStackTrace();
Log.e("abc","join room failed!");
}
}
});
}
Hope this helps your error!
Edit:this is how I config the room:
/*
* Create room
*/
muc.create(roomName);
// muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
for (Iterator fields = form.getFields(); fields.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType())
&& field.getVariable() != null) {
show("field: " + field.getVariable());
// Sets the default value as the answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
List<String> owners = new ArrayList<String>();
owners.add(DataConfig.USERNAME + "#" + DataConfig.SERVICE);
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
submitForm.setAnswer("muc#roomconfig_roomname", roomName);
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
muc.sendConfigurationForm(submitForm);
// submitForm.
show("created room!");
muc.addMessageListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
show(packet.toXML());
Message mess = (Message) packet;
showMessageToUI(mess.getFrom() + ": " + mess.getBody());
}
});
With this cofiguration, I can join a room easily without password.
You may use the code snippet to join the chat:
public void joinMultiUserChatRoom(String userName, String roomName) {
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat multiUserChat = manager.getMultiUserChat(roomName + "#conference.localhost");
DiscussionHistory history = new DiscussionHistory();
history.setMaxStanzas(-1);
try {
multiUserChat.join(userName, "", history, connection.getPacketReplyTimeout());
} catch (Exception e) {
e.printStackTrace();
}
}
Invite a friend:
/**
* Invites another user to this room.
*
* #param userAddress the address of the user to invite to the room.(one
* may also invite users not on their contact list).
* #param reason a reason, subject, or welcome message that would tell
* the the user why they are being invited.
*/
public void invite(String userAddress, String reason)
{
multiUserChat.invite(userAddress, reason);
}