How to create a Multi-Language Alexa Skill using Java? - java

I'm quite new to VUI and Alexa. I developed a good working Skill for Alexa Voice Services. Now I want to add a second language. I've found a tutorial in the develop documation, but I'm using Eclipse and Java to create my Lambda function like this walkthrough.
The problem is, that I have no idea how to enable a second language option in the Lambda function. I have to use the same Lambda function for both languages.
My StreamRequestHandler:
public class ApiOmatBlogSpeechletStreamRequestHandler extends SpeechletRequestStreamHandler {
private static final Set<String> supportedApplicationIds = new HashSet<String>();
static {
/*
* This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant
* Alexa Skill and put the relevant Application Ids in this Set.
*/
supportedApplicationIds.add("amzn1.ask.skill.xxxxxxxx");
}
public ApiOmatBlogSpeechletStreamRequestHandler() {
super(new ApiOmatBlogSkillSpeechlet(), supportedApplicationIds);
System.out.println("Super ApiOmatBlogSpeechletStreamRequestHandler");
}
}
My Spechlet:
public SpeechletResponse onIntent(IntentRequest intentRequest, Session session) {
Intent intent = intentRequest.getIntent();
String intentName = (intent != null) ? intent.getName() : null;
System.out.println("onIntent requestId={ " + intentRequest.getRequestId() + " }, sessionId={ "
+ session.getSessionId() + " } ");
Integer step = (Integer) session.getAttribute("step");
System.out.println("IntentName= " + intentName + " | step = " + step);
if ("AMAZON.HelpIntent".equals(intentName)) {
return getHelpResponse();
} else if ("AMAZON.StopIntent".equals(intentName)) {
return getStopResponse();
} else if (step != null) {
return testing(intent, session, step);
} else {
if ("TestIntent".equals(intentName)) {
step = 1;
session.setAttribute("step", step);
return testing(intent, session, step);
} else {
SsmlOutputSpeech speechText = new SsmlOutputSpeech();
speechText.setSsml("<speak> " + "The intent is invalid." + "Please repeat your demand. "
+ "<break time='0.5s'/> " + " </speak>");
// Create reprompt
PlainTextOutputSpeech speech2 = new PlainTextOutputSpeech();
speech2.setText("I'm sorry. Please repeat your statement.");
Reprompt reprompt = new Reprompt();
reprompt.setOutputSpeech(speech2);
return SpeechletResponse.newAskResponse(speechText, reprompt);
}
}
}
/**
* This function will be called if you say 'start'
*/
public SpeechletResponse onLaunch(final LaunchRequest request, final Session session) throws SpeechletException {
System.out.println(
"onLaunch requestId={ " + request.getRequestId() + " }, sessionId={ " + session.getSessionId() + " } ");
return getHelpResponse();
}
Thank you

It's quite difficult to settle it up.
I solved it by asking, which language the user speaks.
In the Spechlet.java I added the code:
private Boolean german;
public SpeechletResponse onIntent(IntentRequest intentRequest, Session session) {
if (intentRequest.getLocale().getLanguage().equals(new Locale("de").getLanguage())){
System.out.println("Spoken language == Deutsch");
german=true;
}else{
System.out.println("Spoken language == Englisch");
german=false;
}
...
}
and follwing I can work with the Boolean german and set up my response.
If there is a better solution, which works on two languages, than I would looking forward to a posted answer or comment. But for the moment this is the best workaround to handle multiple language in Java.

You don't need different Lambda logic to support each language. You can create multiple Lambda functions based on the region to avoid latency. If you choose to deploy your code to multiple endpoints, you must maintain the same code at all endpoints. The code must handle all languages you support. The only setup you need to do is to add Alexa supported language in Alexa Skill Information, which is marked below,
Please read official documentation here

Related

Discord JDA - getMembers() not working, returns 0 anyway

This is how my code is looking :
public void onGuildVoiceJoin(GuildVoiceJoinEvent event) {
String channelId = event.getChannelJoined().getId();
if (channelId.equals("904375329764814870")) {
Member member = event.getMember();
String memberName = event.getMember().getEffectiveName();
Category category = event.getGuild().getCategoryById("904364634507706468");
event.getGuild().createVoiceChannel("Coaching " + memberName).setParent(category).complete();
List<VoiceChannel> channelList = event.getGuild().getVoiceChannelsByName("Coaching " + memberName, true);
VoiceChannel channel = channelList.get(0);
event.getGuild().moveVoiceMember(member, channel).queue();
while (true){
event.getGuild().getTextChannelById("904364671467929610").sendMessage(
"Number of people currently on the channel : " + channel.getMembers().size()
).queue();
wait(3000);
}
My goal is to get the number of people currently inside the channel.
I thought the getMembers() method was the good method, but it's not working
I use the infinite while to see if the channel.getMembers().size() changes when i join/leave the channel but it still return 0.
How can i fix this ? And get the correct amount of people inside the channel as return.
The final goal of my code is to delete the channel when he's empty of user
This can be achieved by just checking the member count in the GuildVoiceUpdateEvent:
public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) {
if (channel.getName().startsWith("Coaching ")) { // check if name matches the desired name
if (channel.getMembers().isEmpty()) { // check if channel is empty
channel.delete().queue(); // delete channel
}
}
}

How to validate certain input parameters through a Validation API?

I have an API in which I am doing my own validation for certain input parameters. For example -
public Builder(int clientId) {
TestUtils.assertNonNegative(clientId, "ClientId");
this.clientId = clientId;
}
public Builder setUserId(String userid) {
TestUtils.assertNotNull(userid, "UserId");
this.userid = userid;
return this;
}
And my assertNonNegative and assertNotNull method in TestUtils class is like this -
public static void assertNonNegative(int val, String attr) {
if (val <= 0) {
s_logger.logError("Attribute = ", attr, " Value = ", val, " error=", attr, " cannot be negative or zero");
throw new IllegalArgumentException(attr + " cannot be negative or zero");
}
}
public static void assertNotNull(String value, String key) {
if (value == null || value.isEmpty()) {
s_logger.logError("Key = ", key, " Value = ", value, " error=", key,
" cannot be NULL or empty String");
throw new IllegalArgumentException(key + " cannot be null OR empty");
}
}
I am wondering is there any validation API available in any open source projects which I can use to substitute the above internal method I have? If yes, can anyone provide an example how would I achieve this? I still need to throw the same message back as an IllegalArgumentException
I dont understand why would you use an external API tu achieve a nullOrEmpty or a non-negative number validation but...
If you would like to verifiy an id of a user in a database directly in you Java app
This might interest you to learn:
http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
Use a bit of PHP and verify if the user is in the database.
if(isset($_GET['idcmd']))
{
switch($_GET['idcmd'])
{
case 1:
if(isset($_POST['iduser']))
{
$sql= "SELECT idUser FROM users WHERE idUser=:iduser ";
$result = $db_conn->prepare($sql);
$result->bindParam(":iduser" ,$_POST['iduser']);
$result->execute();
$num=$result->fetchColumn();
if($num > 0){
echo "cool";
}else{
echo "nocool";
}
}
break;
}
}
Now if you make a POST request to the url www.mydomain.com/myapi.php?idcmd=1 and get the response cool, it means that the user is in database.
I hope it helps.

Create Custom InputFormat of ColumnFamilyInputFormat for cassandra

I am working on a project, using cassandra 1.2, hadoop 1.2
I have created my normal cassandra mapper and reducer, but I want to create my own Input format class, which will read the records from cassandra, and I'll get the desired column's value, by splitting that value using splitting and indexing ,
so, I planned to create custom Format class. but I'm confused and not able to know, how would I make it? What classes are to be extend and implement, and how I will able to fetch the row key, column name, columns value etc.
I have my Mapperclass as follow:
public class MyMapper extends
Mapper<ByteBuffer, SortedMap<ByteBuffer, IColumn>, Text, Text> {
private Text word = new Text();
MyJDBC db = new MyJDBC();
public void map(ByteBuffer key, SortedMap<ByteBuffer, IColumn> columns,
Context context) throws IOException, InterruptedException {
long std_id = Long.parseLong(ByteBufferUtil.string(key));
long newSavePoint = 0;
if (columns.values().isEmpty()) {
System.out.println("EMPTY ITERATOR");
sb.append("column_N/A" + ":" + "N/A" + " , ");
} else {
for (IColumn cell : columns.values()) {
name = ByteBufferUtil.string(cell.name());
String value = null;
if (name.contains("int")) {
value = String.valueOf(ByteBufferUtil.toInt(cell.value()));
} else {
value = ByteBufferUtil.string(cell.value());
}
String[] data = value.toString().split(",");
// if (data[0].equalsIgnoreCase("login")) {
Long[] dif = getDateDiffe(d1, d2);
// logics i want to perform inside my custominput class , rather here, i just want a simple mapper class
if (condition1 && condition2) {
myhits++;
sb.append(":\t " + data[0] + " " + data[2] + " "+ data[1] /* + " " + data[3] */+ "\n");
newSavePoint = d2;
}
}
sb.append("~" + like + "~" + newSavePoint + "~");
word.set(sb.toString().replace("\t", ""));
}
db.setInterval(Long.parseLong(ByteBufferUtil.string(key)), newSavePoint);
db.setHits(Long.parseLong(ByteBufferUtil.string(key)), like + "");
context.write(new Text(ByteBufferUtil.string(key)), word);
}
I want to decrease my Mapper Class logics, and want to perform same calculations on my custom input class.
Please help, i wish for the positive r4esponse from stackies...
You can do the intended task by moving the Mapper logic to your custom input class (as you have indicated already)
I found this nice post which explains a similar problem statement as you have. I think it might solve your problem.

Whats the best pratice to show multiple placemarks with photos inside of the ballons?

I have a project as follows: Several photos are taken from a mobile, the photos are saved in a web system, which in turn displays the photos on google earth that is inside it. I've read many articles but all of them were using fetchKml, one good article that i've read was using php, but using fetchKml. I dont know if its possible using parseKml instead. Anyway, I'm not sure how to do this with the kml, so it looks tike this:
My Class KMLGenerator()
public static String getKMLFromObra (List<Obra> obraFotos) {
StringBuffer sb = new StringBuffer();
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<kml xmlns='http://www.opengis.net/kml/2.2' " +
"xmlns:gx='http://www.google.com/kml/ext/2.2' " +
"xmlns:kml='http://www.opengis.net/kml/2.2' " +
"xmlns:atom='http://www.w3.org/2005/Atom'> ");
if (obraFotos != null && obraFotos.size() > 0) {
for (Obra o : obraFotos) {
for (Local local : o.getLocais()) {
sb.append("<Document>");
sb.append("<name>" + local.getName() + "</name>");
sb.append("<Style id='defaultStyles'>");
sb.append("<IconStyle>");
sb.append("<scale>1.1</scale>");
sb.append("<Icon>");
sb.append("<href>" + "http://localhost:8080/ConstruMobilFoto/lib/img/fotoIcon.png" + "</href>");
sb.append("</Icon>");
sb.append("</IconStyle>");
sb.append("</Style>");
sb.append("<Placemark>");
sb.append("<name>" + "Foto" + "</name>");
sb.append("<styleUrl>" + "#defaultStyles"+ "</styleUrl>");
sb.append("<altitudeMode>" + "relativeToGround" + "</altitudeMode>");
sb.append("<Point>");
sb.append("<altitudeMode>relativeToGround</altitudeMode>");
sb.append("<coordinates>" + local.getLongitude() + "," + local.getLatitude() + "," + 50</coordinates>");
sb.append("</Point>");
sb.append("<Link>");
sb.append("<href>" + local.getFotos() + "</href>");
sb.append("</Link>");
sb.append("</Placemark>");
sb.append("</Document>");
sb.append("</kml>");
return sb.toString();
}
}
}
return null;
}
I have a dwr function in my jsp that invokes this method, got its String results and make the parse like this:
Class PainelEarth()
#SuppressWarnings("static-access")
public String geraFotosObra (int idObra) throws Exception {
try {
List<Obra> obraFotos = obraBusiness.getObraLatLong(new Obra(idObra));
return new KMLGenerator().getKMLFromObra(obraFotos);
} catch (Exception e) {
log.error(e.getLocalizedMessage(), e);
return null;
}
}
and in my jsp page
function initCB(instance) {
// other codes
showPics(ge);
}
function showPics(ge) {
PainelEarthAjax.geraFotosObra({
callback : function(kmlString) {
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}
});
return null;
}
Any help will be welcome!!
In your code if you look at the signature of the method geraFotosObra you can see it takes a single int parameter idObra.
public String geraFotosObra (int idObra) throws Exception { ...
Yet when you call the method in your jsp you are passing an an object literal containing a callback function.
PainelEarthAjax.geraFotosObra({
callback : function(kmlString) { ...
As it is I don't see how the kml is generated, unless perhaps geraFotosObra is an overloaded method? Also even if it was generated, as is, I don't see how the callback function that you pass in place of an id is ever called - why for example would kmlString be the result of the call to geraFotosObra?
// How is this called, what sets kmlString!?
callback : function(kmlString) {
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}
All in all the code you posted is a wee bit confusing, so sorry if I have missed something...I think you have possibly copy and pasted some code from a fetchKml example and the asynchronous callbacks used with that method have confused you slightly.
Anyhow, based on what you have posted, you should be passing an int id to the geraFotosObra method, getting the string result and then parsing it in the plug-in.
Something like the following makes sense. Replace the showPics function with the following.
function showPics(ge) {
var kmlString = PainelEarthAjax.geraFotosObra(1); // or something?
var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
}

How to use resultset.next method after executing result.beforeFirst in java using mysql

I need help on how to scroll back to the next record on the resultset returned by java. I'm using mysql database.
Here is the code inside the formshow event. Where I load the first resultset that is being returned:
if (rs.next()) {
jLabel5.setText(rs.getString("Question"));
jRadioButton1.setText("A. " + rs.getString("A"));
jRadioButton2.setText("B. " + rs.getString("B"));
jRadioButton3.setText("C. " + rs.getString("C"));
jRadioButton4.setText("D. " + rs.getString("D"));
}
And here's the button which is supposed to be used to scroll forward through the database.
I need to execute rs.beforeFirst because the things that are displayed on the jFrame doesn't match with the variable that I'm trying to validate:
try {
rs.beforeFirst();
if (rs.next()) {
jLabel5.setText(rs.getString("Question"));
jRadioButton1.setText("A. " + rs.getString("A"));
jRadioButton2.setText("B. " + rs.getString("B"));
jRadioButton3.setText("C. " + rs.getString("C"));
jRadioButton4.setText("D. " + rs.getString("D"));
if (jRadioButton1.isSelected()) {
rval = jRadioButton1.getText().charAt(0);
if (String.valueOf(rval).equalsIgnoreCase(rs.getString("Answer"))) {
JOptionPane.showMessageDialog(null, "Correct! Your answer is " + rval + " answer is: " + rs.getString("Answer"));
} else {
JOptionPane.showMessageDialog(null, "Wrong! your answer is " + rval + " answer is: " + rs.getString("Answer"));
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
My question is how do I continue on scrolling through the database. Because the resultset doesn't progress when I use the rs.beforeFirst() before the rs.next()
I also tried doing:
while(rs.next()){...}
It worked but it didn't let me choose what radioButton I want. And it continued to execute until the end of the result set even without manually clicking on the button(for scrolling) multiple times. Please help me figure out what's the solution to this. If you need more details just ask. Thanks.
You shouldn't be mingling database access logic with presentation logic. That only leads to tight coupled code where the both concerns only collides with each other. The database job needs to be done as soon as possible.
You need to separate the concerns.
First create a class which represents a single row of the database.
public class Question {
private String text;
private String answer;
private String optionA;
private String optionB;
private String optionC;
private String optionD;
// Add/generate c'tors/getters/setters/equals/hashcode and other boilerplate.
}
(a bit decent IDE like Eclipse can autogenerate them)
Then create a class which does the following JDBC job:
public List<Question> list() throws SQLException {
List<Question> questions = new ArrayList<Question>();
// ...
try {
// ...
while (resultSet.next()) {
Question question = new Question();
question.setText(resultSet.getString("Question"));
question.setAnswer(resultSet.getString("Answer"));
question.setOptionA(resultSet.getString("A"));
question.setOptionB(resultSet.getString("B"));
question.setOptionC(resultSet.getString("C"));
question.setOptionD(resultSet.getString("D"));
questions.add(question);
}
} finally {
// ...
}
return questions;
}
Finally just work with List<Question> the straightforward way.
List<Question> questions = questionDAO.list();
int size = questions.size();
JOptionPane.showMessageDialog(null, "There are " + size + " questions!");
for (Question question : questions) {
jLabel5.setText(question.getText());
jRadioButton1.setText("A. " + question.getOptionA());
jRadioButton2.setText("B. " + question.getOptionB());
jRadioButton3.setText("C. " + question.getOptionC());
jRadioButton4.setText("D. " + question.getOptionD());
// ...
}
No need to massage the resultset forth and back.

Categories

Resources