Skip to content

Commit

Permalink
Added quick reply function and tests. Some code tweaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
rabidgremlin committed May 22, 2017
1 parent 71d9336 commit 2aee2d7
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.rabidgremlin.mutters.bot.BotException;
import com.rabidgremlin.mutters.bot.BotResponse;
import com.rabidgremlin.mutters.bot.ink.functions.AddAttachmentFunction;
import com.rabidgremlin.mutters.bot.ink.functions.AddQuickReplyFunction;
import com.rabidgremlin.mutters.bot.ink.functions.SetHintFunction;
import com.rabidgremlin.mutters.bot.ink.functions.SetRepromptFunction;
import com.rabidgremlin.mutters.core.Context;
Expand Down Expand Up @@ -97,6 +98,7 @@ public AbstractInkBot()
addFunction(new SetHintFunction());
addFunction(new SetRepromptFunction());
addFunction(new AddAttachmentFunction());
addFunction(new AddQuickReplyFunction());

// add any other functions for the bot
setUpFunctions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void addResponseAttachement(BotResponseAttachment attachment)
responseAttachments.add(attachment);
}

public void addQuickReply(String quickReply)
public void addResponseQuickReply(String quickReply)
{
if (responseQuickReplies == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@
import com.rabidgremlin.mutters.session.Session;

/**
* This class implements the ADD_ATTACHMENT Ink bot function. It is added by default to the AbstractInkBot. The ADD_ATTACHMENT
* function allows the bot to pass attachments to the client that the user is using to talk to the bot with. It could be
* used to pass hyper-links, images or button lists.
* This class implements the ADD_ATTACHMENT Ink bot function. It is added by default to the AbstractInkBot. The
* ADD_ATTACHMENT function allows the bot to pass attachments to the client that the user is using to talk to the bot
* with. It could be used to pass hyper-links, images or button lists.
*
* For example in the ink script you could have the following hyperlink attachment that might get rendered as a button:
*
* ```
* I've found a website with that information...
* ::ADD_ATTACHMENT type::link url::https:\/\/en.wikipedia.org/wiki/Chatbot title::Here is the link
* ```
* ``` I've found a website with that information... ::ADD_ATTACHMENT type::link
* url::https:\/\/en.wikipedia.org/wiki/Chatbot title::Here is the link ```
*
* This function uses the first word as the action name that is returned by the bot. The rest of the line is assumed to
* be name-value pairs which are returned as action parameters by the bot.
* The type parameter is a required parameter. Other parameters are parsed and pass along.
*
* @author rabidgremlin
*
Expand Down Expand Up @@ -51,19 +48,22 @@ public void execute(CurrentResponse currentResponse, Session session, IntentMatc
Story story, String param)
{
FunctionDetails details = FunctionHelper.parseFunctionString(param);

if (details.getFunctionParams() == null ||
details.getFunctionParams().get("type") == null ||
details.getFunctionParams().get("url") == null ||
details.getFunctionParams().get("title") == null)

if (details.getFunctionParams() == null || details.getFunctionParams().get("type") == null)
{
throw new IllegalArgumentException("Missing type value for ADD_ATTACHMENT function.");
}

BotResponseAttachment attachment = new BotResponseAttachment(details.getFunctionParams().get("type"));

for (String key : details.getFunctionParams().keySet())
{
throw new IllegalArgumentException("Missing values for ADD_ATTACHMENT function. Expected type, url and title");
if (!key.equals("type"))
{
attachment.addParameters(key, details.getFunctionParams().get(key));
}
}

BotResponseAttachment attachment = new BotResponseAttachment(details.getFunctionParams().get("type"));
attachment.addParameters("url", details.getFunctionParams().get("url"));
attachment.addParameters("title", details.getFunctionParams().get("title"));


currentResponse.addResponseAttachement(attachment);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.rabidgremlin.mutters.bot.ink.functions;

import com.bladecoder.ink.runtime.Story;
import com.rabidgremlin.mutters.bot.BotResponseAttachment;
import com.rabidgremlin.mutters.bot.ink.CurrentResponse;
import com.rabidgremlin.mutters.bot.ink.InkBotFunction;
import com.rabidgremlin.mutters.core.IntentMatch;
import com.rabidgremlin.mutters.session.Session;

/**
* This class implements the ADD_QUICK_REPLY Ink bot function. It is added by default to the AbstractInkBot. The ADD_QUICK_REPLY
* function allows the bot to pass a list of quick reply options back to the client. Depending on the chat interface these
* options can be displayed as quick menu options so that a user does not have to enter a response manually.
*
* Multiple quick reply functions can be called to build up a list of quick replies.
*
* ```
* I can help you manage your taxi service. Try say something like 'Order me a cab' or 'Where is my taxi'.
* ::ADD_QUICK_REPLY Order me a cab
* ::ADD_QUICK_REPLY Where is my taxi
* ```
*
*
* @author rabidgremlin
*
*/
public class AddQuickReplyFunction
implements InkBotFunction
{

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#getFunctionName()
*/
@Override
public String getFunctionName()
{
return "ADD_QUICK_REPLY";
}

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#respondexecute(CurrentResponse currentResponse, Session
* session, IntentMatch intentMatch, Story story, String param)
*/
@Override
public void execute(CurrentResponse currentResponse, Session session, IntentMatch intentMatch,
Story story, String param)
{
currentResponse.addResponseQuickReply(param);
}

}
4 changes: 3 additions & 1 deletion src/test/ink/order_taxi.ink
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ What is the pick up address ?
::ORDER_TAXI
Taxi {taxiNo} is on its way
::ADD_ATTACHMENT type::link url::http:\/\/trackcab.example.com/t/{taxiNo} title::Track your taxi here
-> END
::ADD_QUICK_REPLY Where is my taxi?
::ADD_QUICK_REPLY Cancel my taxi
-> END
22 changes: 22 additions & 0 deletions src/test/java/com/rabidgremlin/mutters/bot/ink/TestTaxiInkBot.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;

import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;

Expand Down Expand Up @@ -271,4 +273,24 @@ public void testSessionEndClearsReprompts()
assertThat(response.getResponse(), is("Pardon?"));
assertThat(response.isAskResponse(), is(true));
}

@Test
public void testQuickReplies()
throws BotException
{
Session session = new Session();
Context context = new Context();

BotResponse response = taxiBot.respond(session, context, "Send a taxi to 56 Kilm Steet");

assertThat(response, is(notNullValue()));
assertThat(response.getResponse(), is("Taxi 1e1f is on its way"));
assertThat(response.isAskResponse(), is(false));
assertThat(response.getQuickReplies(), is(notNullValue()));

assertThat(response.getQuickReplies().size(), is(2));
List<String> quickReplies = response.getQuickReplies();
assertThat(quickReplies.get(0), is("Where is my taxi?"));
assertThat(quickReplies.get(1), is("Cancel my taxi"));
}
}
2 changes: 1 addition & 1 deletion src/test/resources/taxibot.ink.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"inkVersion":16,"root":["\n","\n","\n","\n","\n","\n",{"->":"start"},"done",{"start":[["ev",{"^->":"start.0.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^OrderTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.0.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"order_taxi"},{"#f":7}]}],["ev",{"^->":"start.1.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^CancelTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.1.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"cancel_taxi"},{"#f":7}]}],["ev",{"^->":"start.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^WhereTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.2.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"where_taxi"},{"#f":7}]}],{"#f":3}],"order_taxi":[[[["G>",["ev",{"VAR?":"address"},"str","^","/str","==","/ev",{"->":".^.b","c":true},{"b":[{"->":"order_taxi.request_address"},{"->":".^.^.^.3"},null]}],[{"->":".^.b"},{"b":[{"->":"order_taxi.order_the_taxi"},{"->":".^.^.^.3"},null]}],"nop","G<",null],"\n","end",{"#f":7,"#n":"order_taxi_loop"}],null],{"request_address":[["^What is the pick up address ?","\n","^::SET_REPROMPT Where would you like to be picked up ?","\n","^::SET_HINT 123 Someplace Rd","\n",["ev",{"^->":"order_taxi.request_address.0.6.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^GaveAddress",{"->":"$r","var":true},null],"c":["ev",{"^->":"order_taxi.request_address.0.6.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.^.g-0"},{"#f":7}]}],{"g-0":[{"->":".^.^.^.^.0.order_taxi_loop"},{"#f":7}]}],{"#f":3}],"order_the_taxi":["^::ORDER_TAXI","\n","^Taxi ",["G>","ev",{"VAR?":"taxiNo"},"out","/ev","G<",null],"^ is on its way","\n","^::ADD_ATTACHMENT type::link url::http://trackcab.example.com/t/",["G>","ev",{"VAR?":"taxiNo"},"out","/ev","G<",null],"^ title::Track your taxi here","\n","end",{"#f":3}],"#f":3}],"cancel_taxi":["^Your taxi has been cancelled","\n","end",{"#f":3}],"where_taxi":["^Your taxi is about 7 minutes away","\n","end",{"#f":3}],"stop":["^Ok","\n","end",{"#f":3}],"help":["^I can help you order a taxi or find out the location of your current taxi.","\n","^Try say \"Order a cab\" or \"Where is my cab\"","\n","end",{"#f":3}],"confused_bot":["^I'm sorry I'm not understanding you at all :(","\n","^If you are in a hurry, please call 555-12345 to order your taxi.","\n","end",{"#f":3}],"global decl":["ev","str","^","/str",{"VAR=":"address"},"str","^","/str",{"VAR=":"taxiNo"},"/ev","end",null],"#f":3}],"listDefs":{}}
{"inkVersion":16,"root":["\n","\n","\n","\n","\n","\n",{"->":"start"},"done",{"start":[["ev",{"^->":"start.0.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^OrderTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.0.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"order_taxi"},{"#f":7}]}],["ev",{"^->":"start.1.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^CancelTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.1.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"cancel_taxi"},{"#f":7}]}],["ev",{"^->":"start.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^WhereTaxi",{"->":"$r","var":true},null],"c":["ev",{"^->":"start.2.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":"where_taxi"},{"#f":7}]}],{"#f":3}],"order_taxi":[[[["G>",["ev",{"VAR?":"address"},"str","^","/str","==","/ev",{"->":".^.b","c":true},{"b":[{"->":"order_taxi.request_address"},{"->":".^.^.^.3"},null]}],[{"->":".^.b"},{"b":[{"->":"order_taxi.order_the_taxi"},{"->":".^.^.^.3"},null]}],"nop","G<",null],"\n","end",{"#f":7,"#n":"order_taxi_loop"}],null],{"request_address":[["^What is the pick up address ?","\n","^::SET_REPROMPT Where would you like to be picked up ?","\n","^::SET_HINT 123 Someplace Rd","\n",["ev",{"^->":"order_taxi.request_address.0.6.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.c","flg":2},{"s":["^GaveAddress",{"->":"$r","var":true},null],"c":["ev",{"^->":"order_taxi.request_address.0.6.c.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.^.g-0"},{"#f":7}]}],{"g-0":[{"->":".^.^.^.^.0.order_taxi_loop"},{"#f":7}]}],{"#f":3}],"order_the_taxi":["^::ORDER_TAXI","\n","^Taxi ",["G>","ev",{"VAR?":"taxiNo"},"out","/ev","G<",null],"^ is on its way","\n","^::ADD_ATTACHMENT type::link url::http://trackcab.example.com/t/",["G>","ev",{"VAR?":"taxiNo"},"out","/ev","G<",null],"^ title::Track your taxi here","\n","^::ADD_QUICK_REPLY Where is my taxi?","\n","^::ADD_QUICK_REPLY Cancel my taxi","\n","end",{"#f":3}],"#f":3}],"cancel_taxi":["^Your taxi has been cancelled","\n","end",{"#f":3}],"where_taxi":["^Your taxi is about 7 minutes away","\n","end",{"#f":3}],"stop":["^Ok","\n","end",{"#f":3}],"help":["^I can help you order a taxi or find out the location of your current taxi.","\n","^Try say \"Order a cab\" or \"Where is my cab\"","\n","end",{"#f":3}],"confused_bot":["^I'm sorry I'm not understanding you at all :(","\n","^If you are in a hurry, please call 555-12345 to order your taxi.","\n","end",{"#f":3}],"global decl":["ev","str","^","/str",{"VAR=":"address"},"str","^","/str",{"VAR=":"taxiNo"},"/ev","end",null],"#f":3}],"listDefs":{}}

0 comments on commit 2aee2d7

Please sign in to comment.