Mention any member via Java DIscord Bot - java

So i am making a bot where the purpose of it would be to tag the user who has been reported by typing .inappropriate #discordUser.
Here is the sample:
if(message.getMessageContent().equalsIgnoreCase(main.prefix + "inappropriate"))
{
message.getChannel().sendMessage("username of <#!USER_ID> is inappropriate.");
}
However, the problem is that it is not a specified user. In other words, it won't always be the same user.
So this is how it should look on Discord:
Me: .inappropriate #discordUser
Bot: username of #discordUser is inappropriate.
So, i wanted to know, how i can make this possible?

You didn't tell which discord wrapper you are using, but from getMessageContent(), it seems to be Javacord. And if it not, note that everything that I will say are the same/have equivalent in other wrappers.
First you need to get the id or the member mentioned.
Second you have to make a mention from it.
To get the mentioned member, you can use the method Message#getMentionedUsers() which returns a List of the users mentioned in the message. This means that you can even get several users.
To get the id, either you use User#getId() or User#getIdAsString() or you can try to parse the Message#getMessageContent() by for example splitting it and then using a regex (remember that a mention is <#!id>)
How do you get a mention from user or id ? From the user, you can simply use the method User#getMentionTag​() or User#getNicknameMentionTag​​(). From the id, you can append "<#!" + id + ">".
So in short, you can either do :
message → member (method) → mention (method)
message → id (manual parsing) → mention (manual appending)
message → member (method) → id (getter method) → mention (method)
The last one may seem useless, but in the case where you store ids (you can't store entities), it can be useful.
And also, you can retrieve member from id, but it's useless here compared to the other on top of needing intents, actually you can simply do the first solution, it's just two method calls.
I gave you several ways to do it, some of them are manual, other use existing methods. You should prefer using those method unless it's not convenient for you (ie you want your own command parser so you can't use getMentionedUsers()).
Also, you can look up at the method of each classes, you may find gold, the doc is available in your ide or online here with a search bar.
I knew the wrapper JDA but I have no idea about Javacord until I answer your question.
It's my first answer, I hope I didn't mess up something.

Related

Karate framework: how to reuse variable used in one sceario to be called in another without declaring it as global variables [duplicate]

Does Karate supports a feature where you can define a variable in a scenario and reuse it in other scenarios in the same feature file. I tried doing the same but get an error. What's the best way to reuse the variables within the same feature file ?
Scenario: Get the request Id
* url baseUrl
Given path 'eam'
When method get
Then status 200
And def reqId = response.teams[0]resourceRequestId
Scenario: Use the above generated Id
* url baseUrl
* print 'From the previous Scenario: ' + reqId
Error:
Caused by: javax.script.ScriptException: ReferenceError: "reqId" is not defined in <eval> at line number 1
Use a Background: section. Here is an example.
EDIT: the variable if in the Background: will be re-initialized for every scenario which is standard testing framework "set up" behavior. You can use hooks such as callonce - if you want the initialization to happen only once.
If you are trying to modify a variable in one scenario and expect it to be now having that modified value when the next Scenario starts, you have misunderstood the concept of a Scenario. Just combine your steps into one Scenario, because think about it: that is the "flow" you are trying to test.
Each Scenario should be able to run stand-alone. In the future the execution order of Scenario-s could even be random or run in parallel.
Another way to explain this is - if you comment out one Scenario other ones should continue to work.
Please don't think of the Scenario as a way to "document" the important parts of your test. You can always use comments (e.g. # foo bar). Some teams assume that each HTTP "end point" should live in a separate Scenario - but this is absolutely not recommended. Look at the Hello World example itself, it deliberately shows 2 calls, a POST and a GET !
You can easily re-use code using call so you should not be worrying about whether code-duplication will be an issue.
Also - it is fine to have some code duplication, if it makes the flow easier to read. See this answer for details - and also read this article by Google.
EDIT: if you would like to read another answer that answers a similar question: https://stackoverflow.com/a/59433600/143475

How to set a hostname in a jsonnet file?

I am trying to get the hang of jsonnet files. So far all I have is hard-coded values but what if I wanted to get the hostname for a Java application. For example in Java I would just do:
String hostName = System.getenv("HOSTNAME");
But obviously I can't just have a key-value pair like the following JSON in a jsonnet file.
{name: "hostname", value:System.getenv("HOSTNAME")}
I need a bit of help in understanding how I can do this.
I have looked up std.extvar(x) but the examples I look at just arent clear to me for whatever reason. Is this method relevant? Otherwise, I'm not really sure.
Jsonnet requires all parameters to be passed explicitly. To use a hostname in your Jsonnet code, you need to pass it to the interpreter. For example you can run it as follows:
❯ jsonnet --ext-str "HOSTNAME=$HOST" foo.jsonnet
foo.jsonnet:
std.extVar('HOSTNAME')
You can also use top-level-arguments mechanism to a similar effect (top-level-arguments are passed as function arguments to the evaluated script.
Please see: https://jsonnet.org/learning/tutorial.html#parameterize-entire-config for more in-depth explanation of these features.
FYI not being able to just grab any environment variable or access the system directly is very much by design. The result of Jsonnet evaluation depends only on the code and explicitly passed parameters. This has a lot of benefits, such as the following:
You can easily evaluate on another machine, even on a completely different platform and get exactly the same result.
You are never locked in to configuration on any particular machine – you can always pass any parameters on any machine (very useful for development and debugging).
Avoiding surprises – the evaluation won't break one day, because some random aspect of local configuration changed and some deep part of the code happens to depend on it – all parameters are accounted for.

How can I stop Eclipse's auto-completion feature from suggesting made up variable names?

I've set up Content Assist to trigger on aAbBcCdDeEfFgGhHjIiJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ.() rather than only on .( (Under Window/Preferences/Java/Editor/Content Assist->Auto activation triggers for Java:) so that I can quickly select classes without pressing Ctrl+Space.
This was all good until I went back to creating variable names rather than using them, and it started suggesting a camel case variant of the name I just type, which doesn't yet exist, suffixed with the type! And of course pressing space afterwards uses this suggestion.
i.e. I type only the keys needed for
private static String HELLO = "hello";
I'll end up with the line
private static String hELLOString = "hello";
This comes under Java Proposals (Task-Focused), but turning this off under Advanced options obviously removes all the useful suggestions.
My aim is to allow auto-completion using known objects, not make them up, is there a way of doing this, and if so, How?
It looks like you're asking for code completion at a point (variable declaration) where there are no correct answers since only you know what name you want to enter. Eclipse does try to suggest a possible name, as you point out, from the already-entered type, but it can only guess.
Once you've declared the variable, Eclipse will be able to offer up that correct variable name later on in the code.
You can reduce the likelihood of accidentally selecting suggested variable names by increasing the 'Auto activation delay (ms)', and making sure that when you type a variable name you press [space] or [;] immediately afterwards before thinking about what to type next (if you haven't already).
Unfortunately there is no way (at least in the current Kepler SR1 release) of turning off variable name suggestion without also losing declared variable name suggestion, which is too useful to lose.

JVMTI - how to get the value of a method parameter from callback

I am recording all method entries from my Java app thanks to a JVMTI Agent. For now, I am able to get the name of each method, but I'd want to be able to get the value of the parameters that method received.
This problem has already been discussed in an older topic (see How to get parameter values in a MethodEntry callback); it fits perfectly what I'm looking for, so I know I have to use GetLocalObject function, but I can't figure out how to (the example given in the topic is broken).
Can anyone help me finding out how to do this? Thanks.
I think you want to access arbitrary method parameters without foreknowledge of their content, if not could you clarify your question?
See the JVMTI docs on local variables.
First, you need to ensure you have enabled local variable access in your capabilities list. Then, find out what parameters are available using GetLocalVariableTable. The returned table will contain a description of each local variable in the method, including the parameters. Don't forget to Deallocate it when you're done.
You'll need to work out which variables are parameters. You can do that by finding the current jlocation and eliminating local variables which are not yet available. This won't tell you the parameter order, but it'll tell you which locals are parameters. You can probably assume that the slot number is the correct order.
Find the current jlocation using GetFrameLocation, iterate over the local variable table, and for each local variable whose start_location is less than or equal to your current location, add the slot number and type to your list of parameters.
For each parameter, call the appropriate GetLocal{X} method based on its type. You'll need the depth of your current frame, which you already have from GetFrameLocation.
That should get you your parameters, but it'll be slow and tricky to implement. You'd be far better off following the guide's recommendation of avoiding MethodEntry callbacks and use bytecode instrumentation (BCI) instead.

How best to implement user selectable variables in web application

I have a Java based web-application and a new requirement to allow Users to place variables into text fields that are replaced when a document or other output is produced. How have others gone about this?
I was thinking of having a pre-defined set of variables such as :
#BOOKING_NUMBER#
#INVOICE_NUMBER#
Then when a user enters some text they can specify a variable inline (select it from a modal or similar). For example:
"This is some text for Booking #BOOKING_NUMBER# that is needed by me"
When producing some output (eg. PDF) that uses this text, I would do a regex and find all variables and replace them with the correct value:
"This is some text for Booking 10001 that is needed by me"
My initial thought was something like Freemarker but I think that is too complex for my Users and would require them to know my DataModel (eww).
Thanks for reading!
D.
Have a look at java.text.MessageFormat - particularly the format method - as this is designed for exactly what you are looking for.
i.e.
MessageFormat.format("This is some text for booking {0} that is needed by me, for use with invoice {1}", bookingNumber, invoiceNumber);
You may even want to get the template text from a resource bundle, to allow for support of multiple languages, with the added ability to cope with the fact that {0} and {1} may appear in a different order in some languages.
UPDATE:
I just read your original post properly, and noticed the comment about the PDF.
This suggest that the template text is going to be significantly larger than a line or two.
In such cases, you may want to explore something like StringTemplate which seems better suited for this purpose - this comment is based solely on initial investigations, as I've not used it in anger.
I have used a similiar replacement token system before. I personally like something like.
[MYVALUE]
As it is easy for the user to type, and then I just use replacements to swap out the tokens for the real data.

Categories

Resources