Skip to content

Commit f000133

Browse files
committed
Create WorkoutHelperDemo.java
1 parent 4dd4443 commit f000133

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package net.b07z.sepia.sdk.services.uid1007;
2+
3+
import java.util.TreeSet;
4+
5+
import org.json.simple.JSONObject;
6+
7+
import net.b07z.sepia.server.assist.answers.Answers;
8+
import net.b07z.sepia.server.assist.answers.ServiceAnswers;
9+
import net.b07z.sepia.server.assist.assistant.LANGUAGES;
10+
import net.b07z.sepia.server.assist.data.Parameter;
11+
import net.b07z.sepia.server.assist.interpreters.NluResult;
12+
import net.b07z.sepia.server.assist.interviews.InterviewData;
13+
import net.b07z.sepia.server.assist.services.ServiceBuilder;
14+
import net.b07z.sepia.server.assist.services.ServiceInfo;
15+
import net.b07z.sepia.server.assist.services.ServiceInterface;
16+
import net.b07z.sepia.server.assist.services.ServiceResult;
17+
import net.b07z.sepia.server.assist.services.ServiceInfo.Content;
18+
import net.b07z.sepia.server.assist.services.ServiceInfo.Type;
19+
import net.b07z.sepia.server.core.assistant.PARAMETERS;
20+
import net.b07z.sepia.server.core.data.Language;
21+
import net.b07z.sepia.server.core.tools.JSON;
22+
import net.b07z.sepia.server.core.tools.Sdk;
23+
24+
/**
25+
* Demo for a workout help service. This is mainly to demonstrate follow-up messages.
26+
*
27+
* @author Florian Quirin
28+
*
29+
*/
30+
public class WorkoutHelperDemo implements ServiceInterface {
31+
32+
//Command name of your service (will be combined with userId to be unique)
33+
private static final String CMD_NAME = "workout_helper";
34+
35+
//Define some sentences for testing:
36+
37+
@Override
38+
public TreeSet<String> getSampleSentences(String lang) {
39+
TreeSet<String> samples = new TreeSet<>();
40+
//GERMAN
41+
if (lang.equals(Language.DE.toValue())){
42+
samples.add("Ein einfaches Workout starten.");
43+
//OTHER
44+
}else{
45+
samples.add("Start a simple workout.");
46+
}
47+
return samples;
48+
}
49+
50+
//Basic service setup:
51+
52+
//Overriding the 'getAnswersPool' methods enables you to define custom answers with more complex features.
53+
//You can build a pool of answers that can have multiple versions of the same answer used for different
54+
//situations like a repeated question (what was the time? -> sorry say again, what was the time? -> ...).
55+
56+
@Override
57+
public ServiceAnswers getAnswersPool(String language) {
58+
ServiceAnswers answerPool = new ServiceAnswers(language);
59+
60+
//Build German answers
61+
if (language.equals(LANGUAGES.DE)){
62+
answerPool
63+
.addAnswer(successAnswer, 0, "Ok, <1> Minuten Workout in 3, 2, 1, los gehts!")
64+
.addAnswer(successAnswer, 0, "Ok <user_name>, <1> Minuten Workout in 3, 2, 1, los!")
65+
.addAnswer(successWithTimeAdjust, 0, "Hab die Zeit etwas angepasst <user_name>, <1> Minuten Workout in 3, 2, 1, los!")
66+
.addAnswer(okAnswer, 0, "Sorry aber das hat nicht geklappt. Ich weiß nicht warum.")
67+
.addAnswer(followUpFinish, 0, "Fertig mit dem Training! Gut gemacht!")
68+
.addAnswer(followUpIntervalMinutes, 0, "<1> Minuten noch! Weiter so!")
69+
.addAnswer(followUpIntervalSeconds, 0, "<1> Sekunden noch! Fast geschafft!")
70+
;
71+
return answerPool;
72+
73+
//Fall back to English
74+
}else{
75+
answerPool
76+
.addAnswer(successAnswer, 0, "Ok, <1> minutes workout in 3, 2, 1, go!.")
77+
.addAnswer(successAnswer, 0, "Ok <user_name>, <1> minutes workout in 3, 2, 1, go!.")
78+
.addAnswer(successWithTimeAdjust, 0, "I've adjusted the time a bit <user_name>, <1> minutes workout in 3, 2, 1, go!.")
79+
.addAnswer(okAnswer, 0, "Sorry that did not work out. I don't know why.")
80+
.addAnswer(followUpIntervalMinutes, 0, "<1> minutes to go! Keep it up!")
81+
.addAnswer(followUpIntervalSeconds, 0, "<1> seconds to go! Almost there!")
82+
.addAnswer(followUpFinish, 0, "Done with the training! Good job!")
83+
;
84+
return answerPool;
85+
}
86+
}
87+
//We keep a reference here for easy access in getResult - Note that custom answers need to start with a certain prefix
88+
private static final String failAnswer = "error_0a";
89+
private static final String successAnswer = ServiceAnswers.ANS_PREFIX + "workout_helper_success_0a";
90+
private static final String successWithTimeAdjust = ServiceAnswers.ANS_PREFIX + "workout_helper_success_0b";
91+
private static final String okAnswer = ServiceAnswers.ANS_PREFIX + "workout_helper_ok_0a";
92+
private static final String followUpFinish = ServiceAnswers.ANS_PREFIX + "workout_helper_fu_finish_0a";
93+
private static final String followUpIntervalMinutes = ServiceAnswers.ANS_PREFIX + "workout_helper_fu_interval_0a";
94+
private static final String followUpIntervalSeconds = ServiceAnswers.ANS_PREFIX + "workout_helper_fu_interval_0b";
95+
96+
@Override
97+
public ServiceInfo getInfo(String language) {
98+
//Type of service (for descriptions, choose what you think fits best)
99+
ServiceInfo info = new ServiceInfo(Type.plain, Content.data, false);
100+
101+
//Should be available publicly or only for the developer? Set this when you are done with testing and want to release
102+
//info.makePublic();
103+
104+
//Command
105+
info.setIntendedCommand(Sdk.getMyCommandName(this, CMD_NAME));
106+
107+
//Direct-match trigger sentences in different languages:
108+
String EN = Language.EN.toValue();
109+
info.addCustomTriggerSentence("Start a simple workout.", EN);
110+
String DE = Language.DE.toValue();
111+
info.addCustomTriggerSentence("Ein einfaches Workout starten.", DE);
112+
113+
//Regular expression triggers:
114+
info.setCustomTriggerRegX(".*\\b("
115+
+ "(start)\\b.* (training|work(-| |)out)"
116+
+ ")\\b.*", EN);
117+
info.setCustomTriggerRegX(".*\\b("
118+
+ "(starte)\\b.* (training|work(-| |)out|uebung(en|))" + "|"
119+
+ "(training|work(-| |)out|uebung(en|)) (starten)"
120+
+ ")\\b.*", DE);
121+
info.setCustomTriggerRegXscoreBoost(5); //boost service a bit to increase priority over similar ones
122+
123+
//Parameters:
124+
125+
//This service has only an optional parameter to set the a training time.
126+
//Optional parameters will be extracted from initial sentence but not asked automatically but set to a default if not given.
127+
128+
Parameter p1 = new Parameter(PARAMETERS.TIME)
129+
.setRequired(false);
130+
info.addParameter(p1);
131+
132+
//Answers (these are the default answers, you can trigger a custom answer at any point in the module
133+
//with serviceBuilder.setCustomAnswer(..)):
134+
info.addSuccessAnswer(successAnswer)
135+
.addFailAnswer(failAnswer)
136+
.addOkayAnswer(okAnswer);
137+
//.addCustomAnswer("askTimeAndDate", askTimeAndDate); //optional, just for info
138+
139+
//Add answer parameters that are used to replace <1>, <2>, ... in your answers.
140+
//The name is arbitrary but you need to use the same one in getResult(...) later for api.resultInfoPut(...)
141+
info.addAnswerParameters("time"); //<1>=time, ...
142+
143+
return info;
144+
}
145+
146+
@Override
147+
public ServiceResult getResult(NluResult nluResult) {
148+
//initialize result
149+
ServiceBuilder api = new ServiceBuilder(nluResult,
150+
getInfoFreshOrCache(nluResult.input, this.getClass().getCanonicalName()),
151+
getAnswersPool(nluResult.language));
152+
153+
//get optional parameters:
154+
155+
//-time
156+
long timeMs = 1000 * 60 * 5; //5min
157+
long maxTimeMs = 1000 * 60 * 60; //60min
158+
long minTimeMs = 1000 * 60 * 2; //2min
159+
Parameter dateTimeParameter = nluResult.getOptionalParameter(PARAMETERS.TIME, timeMs);
160+
if (!dateTimeParameter.isDataEmpty()){
161+
timeMs = JSON.getLongOrDefault((JSONObject) dateTimeParameter.getDataFieldOrDefault(InterviewData.TIME_DIFF), "total_ms", timeMs);
162+
}
163+
if (timeMs > maxTimeMs){
164+
timeMs = maxTimeMs;
165+
api.setCustomAnswer(successWithTimeAdjust);
166+
}else if (timeMs < minTimeMs){
167+
timeMs = minTimeMs;
168+
api.setCustomAnswer(successWithTimeAdjust);
169+
}else if (timeMs % 60000 > 0){
170+
api.setCustomAnswer(successWithTimeAdjust);
171+
}
172+
//NOTE: I'm cheating a bit here to save some answer variations by allowing only full minutes as time ;-)
173+
long timeMinutes = Math.round(timeMs / 60000.0d);
174+
long halfTimeMinutes = (long) Math.floor(timeMinutes / 2.0d);
175+
176+
//Set answer parameters as defined in getInfo():
177+
api.resultInfoPut("time", timeMinutes);
178+
179+
//Schedule intervals
180+
if (nluResult.input.isDuplexConnection()){
181+
//System.out.println(nluResult.input.connection);
182+
//System.out.println(nluResult.input.msgId);
183+
//System.out.println(nluResult.input.duplexData);
184+
//Finish
185+
api.runInBackground(timeMinutes * 60 * 1000, () -> {
186+
//initialize follow-up result
187+
ServiceBuilder service = new ServiceBuilder(nluResult);
188+
service.answer = Answers.getAnswerString(nluResult, followUpFinish);
189+
service.status = "success";
190+
/*boolean wasSent =*/ service.sendFollowUpMessage(nluResult.input, service.buildResult());
191+
return;
192+
});
193+
//Interval minutes
194+
if (halfTimeMinutes >= 2){
195+
api.runInBackground(halfTimeMinutes * 60 * 1000, () -> {
196+
//initialize follow-up result
197+
ServiceBuilder service = new ServiceBuilder(nluResult);
198+
service.answer = Answers.getAnswerString(nluResult, followUpIntervalMinutes, halfTimeMinutes);
199+
service.status = "success";
200+
/*boolean wasSent =*/ service.sendFollowUpMessage(nluResult.input, service.buildResult());
201+
return;
202+
});
203+
}
204+
//Interval 30s seconds
205+
long seconds = 30;
206+
api.runInBackground((timeMinutes * 60 * 1000) - (seconds * 1000), () -> {
207+
//initialize follow-up result
208+
ServiceBuilder service = new ServiceBuilder(nluResult);
209+
service.answer = Answers.getAnswerString(nluResult, followUpIntervalSeconds, seconds);
210+
service.status = "success";
211+
/*boolean wasSent =*/ service.sendFollowUpMessage(nluResult.input, service.buildResult());
212+
return;
213+
});
214+
}
215+
216+
//all good
217+
api.setStatusSuccess();
218+
219+
//build the API_Result
220+
ServiceResult result = api.buildResult();
221+
return result;
222+
}
223+
}

0 commit comments

Comments
 (0)