Checking if a member has a certain role - discord-jda

I'm trying to only allow a certain role to view a section of the help command.
I've tried the following, but it doesn't seem to work and it just shows the default help embed:
List<Role> staff = event.getGuild().getRolesByName("Staff", true);
if (event.getGuild().getSelfMember().getRoles().contains(staff)) {
final EmbedBuilder ahelp = new EmbedBuilder();
ahelp.setTitle("Commands List", null);
ahelp.setColor(Color.CYAN);
ahelp.addField("Member:", "*help: Returns with this message." +
"\n*bugreport <Bug>: Creates a new bug report." +
"\n*suggest <Suggestion>: Creates a new suggestion."
, false);
ahelp.addField("Staff:", "*ban <Member> [Reason]: Bans a member." +
"\n*mute <Member> [Reason]: Mutes a member." +
"\n*kick <Member> [Reason]: Kicks a member." +
"\n*unmute <Member>: Unmutes a member."
, false);
ahelp.setFooter("Bot • " + dtf.format(now));
event.getChannel().sendTyping().queue();
event.getChannel().sendMessage(ahelp.build()).queue();
return;
} else {
final EmbedBuilder help = new EmbedBuilder();
help.setTitle("Commands List", null);
help.setColor(Color.CYAN);
help.addField("Member:", "*help: Returns with this message." +
"\n*bugreport <Bug>: Creates a new bug report." +
"\n*suggest <Suggestion>: Creates a new suggestion."
, false);
help.setFooter("Bot • " + dtf.format(now));
event.getChannel().sendTyping().queue();
event.getChannel().sendMessage(help.build()).queue();
return;
}
If there is a better way, or if you know how to answer my question please let me know.
Thanks.

You are trying to check if a List<Role> contains another List<Role>. This is not how contains works. The correct usage would be with a Role object rather than a List<Role> object.
Since I assume you are looking for just the fact that the member has a role with the name "Staff" you can use the Stream API:
public boolean hasRole(Member member, String name) {
return member.getRoles().stream().map(Role::getName).anyMatch(name::equalsIgnoreCase);
}
if (hasRole(event.getGuild().getSelfMember(), "Staff")) {
// ... your code here ...
}
You also only check the "self member" which means you only check the roles of the bot itself rather than the roles of the user. I think you might want to use event.getMember() instead?

Related

Discord JDA can't get getMutualGuilds() to work

Im trying to make a bot that sends a pm when someone joins a server, and then assigns a role based on reply to said Pm.
This is the following code i have so far for onMessageRecieved, issue is that user.getMutualGuilds() returns an empty list even though they are part of the same server as the bot.
#Override
public void onMessageReceived(MessageReceivedEvent event) {
String DmRecieved = event.getMessage().getContentRaw();
User user = event.getAuthor();
boolean isBot = user.isBot();
boolean startsWithAU = DmRecieved.toUpperCase().startsWith("AU", 0);
boolean messageTooLong = DmRecieved.length() > 8;
if (event.getMessage().getContentRaw().isEmpty()) return;
if (isBot) return;
if (!startsWithAU || messageTooLong) {
user.openPrivateChannel().queue((chanel1 ->
chanel1.sendMessage("Not valid AU ID, please try again.").queue()));
} else {
List<Guild> guilds = user.getMutualGuilds();
System.out.println(guilds);
}
}
I found the fix. The members needed to be cached in memory this was done by adding the following line to the JDA:
jda.setMemberCachePolicy(member -> true);

Kinvey-Xamarin: How to recieve Data from a User instance?

I'm working on a Kinvey project right now, and I'm having some Problems with reading the Username or special Attributes from a User instance. I first tried it the same way getting _User.ID by calling _User.UserName, but this didnt return anything(But ID did curiously). I also searched on Google, but there weren't any articles about it. Hope you can help, would be greatly appreciated!
For special attributes, use the .Attributes array on the User class.
Like this code:
Console.WriteLine ("custom attribute is: " + kinveyClient.User ().Attributes["myAttribute"]);
For username, try .UserName() but it seems you must do an explicit retrieval of the User object before this field is populated
User retrieved;
try {
retrieved = await kinveyClient.User().RetrieveAsync();
} catch (Exception e) {
Console.WriteLine("{0} caught exception: ", e);
retrieved = null;
}
Console.WriteLine ("logged in as: " + retrieved.Username );
Console.WriteLine ("custom attribute is: " + retrieved.Attributes["myAttribute"]);
Documentation: http://devcenter.kinvey.com/xamarin/guides/users#UserClass
(answer applies to SDK version 1.6.11)

Update Kaltura Media entry plays

I'm trying to update field "plays" of a media Entry but while the code runs without any problems/exceptions the value of the entry stays the same.
The code i'm using is below :
try {
String ks = client.getSessionService().start(ADMIN_SECRET, "admin",
KalturaSessionType.ADMIN, PARTNER_ID, 86400, "disableentitlement");
client.setKs(ks);
client.setSessionId(ks);
// Get Media Entry
KalturaMediaEntry getMediaEntry = client.getMediaService().get(entry_id);
// Get plays of Media Entry
int plays = getMediaEntry.plays;
int updatedPlays = plays + 1;
// Create updated Media Entry with plays+1
KalturaMediaEntry updatedMediaEntry = new KalturaMediaEntry();
updatedMediaEntry.plays = updatedPlays;
// Update
client.getMediaService().update(entry_id, updatedMediaEntry);
} catch (KalturaApiException e) {
e.printStackTrace();
Log.i(TAG, "Update Num of plays error: " + e.getMessage() );
}
Anyone can help me with this?
Thanks in advance.
KalturaMediaEntry.plays is not updatable using the API, this is a read-only field.
See https://github.com/kaltura/server/blob/Kajam-11.18.0/api_v3/lib/types/entry/KalturaPlayableEntry.php#L12
The API should actually be throwing an error when trying to update this field.
I assume that you are using a self hosted version of Kaltura, in that case it is possible to update plays using a direct DB script.
You can use https://github.com/kaltura/server/blob/Kajam-11.18.0/alpha/scripts/utils/updateEntryInSphinx.php as an example.
Located at /opt/kaltura/app/alpha/scripts/utils/updateEntryInSphinx.php
Before $sphinx->saveToSphinx($entry, false, true); add
$entry->setPlays($entry->getPlays() + 1);
$entry->save();
Execute with php /opt/kaltura/app/alpha/scripts/utils/updateEntryInSphinx.php ENTRY_ID execute

How to validate that password field is empty or not?

public void onMyButtonClick1(View view)
{
final EditText emailValidate = (EditText)findViewById(R.id.emailid);
final TextView passValidate = (TextView)findViewById(R.id.password);
String email = emailValidate.getText().toString().trim();
String pass= passValidate.getText().toString().trim();
String emailPattern = "[a-zA-Z0-9._-]+#[a-z]+\\.+[a-z]+";
// onClick of button perform this simplest code.
if (email.matches(emailPattern)&&(passValidate!=null))
{
//Toast.makeText(this,"valid email address",Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Welcome To Sun Telematics", Toast.LENGTH_SHORT).show();
Intent getStarted = new Intent(getApplicationContext(), FourthActivity.class);
startActivity(getStarted);
/*else
{
Toast.makeText(this, "Field Required", Toast.LENGTH_SHORT).show();
}*/
}
else
{
Toast.makeText(getApplicationContext(),"Invalid email address", Toast.LENGTH_SHORT).show();
}
}
I want to check that password field is empty or not. If it is empty it will not go to the next activity. It will show toast message.
I can validate that field. Where can i do the changes in the code.
You shouldn't check if the instance of the password field is null but whether the string content is actually empty or not. There are various utility libraries for this but it would probably suffice to check !"".equals(pass)
Note that by putting the "" up front you will avoid a NullPointerException even if your string could be null. In this case it wouldn't matter since you already got the string and trimmed it.
I recommend using StringUtils in the common lang library by Apache to handle this kind of stuff though, you could just write StringUtils.isNotEmpty(pass) in that case and it has various utility methods for checking whitespaces, converting strings, etc.

Google+ insert moment using google-api-dotnet-client

I am trying to write an activity in Google+ using the dotnet-client. The issue is that I can't seem to get the configuration of my client app correctly. According to the Google+ Sign-In configuration and this SO question we need to add the requestvisibleactions parameter. I did that but it did not work. I am using the scope https://www.googleapis.com/auth/plus.login and I even added the scope https://www.googleapis.com/auth/plus.moments.write but the insert still did not work.
This is what my request url looks like:
https://accounts.google.com/ServiceLogin?service=lso&passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/plus.login%2Bhttps://www.googleapis.com/auth/plus.moments.write%26response_type%3Dcode%26redirect_uri%3Dhttp://localhost/%26state%3D%26requestvisibleactions%3Dhttp://schemas.google.com/AddActivity%26client_id%3D000.apps.googleusercontent.com%26request_visible_actions%3Dhttp://schemas.google.com/AddActivity%26hl%3Den%26from_login%3D1%26as%3D-1fbe06f1c6120f4d&ltmpl=popup&shdf=Cm4LEhF0aGlyZFBhcnR5TG9nb1VybBoADAsSFXRoaXJkUGFydHlEaXNwbGF5TmFtZRoHQ2hpa3V0bwwLEgZkb21haW4aB0NoaWt1dG8MCxIVdGhpcmRQYXJ0eURpc3BsYXlUeXBlGgdERUZBVUxUDBIDbHNvIhTeWybcoJ9pXSeN2t-k8A4SUbfhsygBMhQivAmfNSs_LkjXXZ7bPxilXgjMsQ&scc=1
As you can see from there that there is a request_visible_actions and I even added one that has no underscore in case I got the parameter wrong (requestvisibleactions).
Let me say that my app is being authenticated successfully by the API. I can get the user's profile after being authenticated and it is on the "insert moment" part that my app fails. My insert code:
var body = new Moment();
var target = new ItemScope();
target.Id = referenceId;
target.Image = image;
target.Type = "http://schemas.google.com/AddActivity";
target.Description = description;
target.Name = caption;
body.Target = target;
body.Type = "http://schemas.google.com/AddActivity";
var insert =
new MomentsResource.InsertRequest(
// this is a valid service instance as I am using this to query the user's profile
_plusService,
body,
id,
MomentsResource.Collection.Vault);
Moment result = null;
try
{
result = insert.Fetch();
}
catch (ThreadAbortException)
{
// User was not yet authenticated and is being forwarded to the authorization page.
throw;
}
catch (Google.GoogleApiRequestException requestEx)
{
// here I get a 401 Unauthorized error
}
catch (Exception ex)
{
} `
For the OAuth flow, there are two issues with your request:
request_visible_actions is what is passed to the OAuth v2 server (don't pass requestvisibleactions)
plus.moments.write is a deprecated scope, you only need to pass in plus.login
Make sure your project references the latest version of the Google+ .NET client library from here:
https://developers.google.com/resources/api-libraries/download/stable/plus/v1/csharp
I have created a project on GitHub showing a full server-side flow here:
https://github.com/gguuss/gplus_csharp_ssflow
As Brettj said, you should be using the Google+ Sign-in Button as demonstrated in the latest Google+ samples from here:
https://github.com/googleplus/gplus-quickstart-csharp
First, ensure you are requesting all of the activity types you're writing. You will know this is working because the authorization dialog will show "Make your app activity available via Google, visible to you and: [...]" below the text that starts with "This app would like to". I know you checked this but I'm 90% sure this is why you are getting the 401 error code. The following markup shows how to render the Google+ Sign-In button requesting access to Add activities.
<div id="gConnect">
<button class="g-signin"
data-scope="https://www.googleapis.com/auth/plus.login"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-clientId="YOUR_CLIENT_ID"
data-accesstype="offline"
data-callback="onSignInCallback"
data-theme="dark"
data-cookiepolicy="single_host_origin">
</button>
Assuming you have a PlusService object with the correct activity type set in data-requestvisibleactions, the following code, which you should be able to copy/paste to see it work, concisely demonstrates writing moments using the .NET client and has been tested to work:
Moment body = new Moment();
ItemScope target = new ItemScope();
target.Id = "replacewithuniqueforaddtarget";
target.Image = "http://www.google.com/s2/static/images/GoogleyEyes.png";
target.Type = "";
target.Description = "The description for the activity";
target.Name = "An example of add activity";
body.Target = target;
body.Type = "http://schemas.google.com/AddActivity";
MomentsResource.InsertRequest insert =
new MomentsResource.InsertRequest(
_plusService,
body,
"me",
MomentsResource.Collection.Vault);
Moment wrote = insert.Fetch();
Note, I'm including Google.Apis.Plus.v1.Data for convenience.
Ah it's that simple! Maybe not? I am answering my own question and consequently accept it as the answer (after a few days of course) so others having the same issue may be guided. But I will definitely up-vote Gus' answer for it led me to the fix for my code.
So according to #class answer written above and as explained on his blog the key to successfully creating a moment is adding the request_visible_actions parameter. I did that but my request still failed and it is because I was missing an important thing. You need to add one more parameter and that is the access_type and it should be set to offline. The OAuth request, at a minimum, should look like: https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/plus.login&response_type=code&redirect_uri=http://localhost/&request_visible_actions=http://schemas.google.com/AddActivity&access_type=offline.
For the complete and correct client code you can get Gus' example here or download the entire dotnet client library including the source and sample and add what I added below. The most important thing that you should remember is modifying your AuthorizationServerDescription for the Google API. Here's my version of the authenticator:
public static OAuth2Authenticator<WebServerClient> CreateAuthenticator(
string clientId, string clientSecret)
{
if (string.IsNullOrWhiteSpace(clientId))
throw new ArgumentException("clientId cannot be empty");
if (string.IsNullOrWhiteSpace(clientSecret))
throw new ArgumentException("clientSecret cannot be empty");
var description = GoogleAuthenticationServer.Description;
var uri = description.AuthorizationEndpoint.AbsoluteUri;
// This is the one that has been documented on Gus' blog site
// and over at Google's (https://developers.google.com/+/web/signin/)
// This is not in the dotnetclient sample by the way
// and you need to understand how OAuth and DNOA works.
// I had this already, see my original post,
// I thought it will make my day.
if (uri.IndexOf("request_visible_actions") < 1)
{
var param = (uri.IndexOf('?') > 0) ? "&" : "?";
description.AuthorizationEndpoint = new Uri(
uri + param +
"request_visible_actions=http://schemas.google.com/AddActivity");
}
// This is what I have been missing!
// They forgot to tell us about this or did I just miss this somewhere?
uri = description.AuthorizationEndpoint.AbsoluteUri;
if (uri.IndexOf("offline") < 1)
{
var param = (uri.IndexOf('?') > 0) ? "&" : "?";
description.AuthorizationEndpoint =
new Uri(uri + param + "access_type=offline");
}
// Register the authenticator.
var provider = new WebServerClient(description)
{
ClientIdentifier = clientId,
ClientSecret = clientSecret,
};
var authenticator =
new OAuth2Authenticator<WebServerClient>(provider, GetAuthorization)
{ NoCaching = true };
return authenticator;
}
Without the access_type=offline my code never worked and it will never work. Now I wonder why? It would be good to have some explanation.

Resources