AI Zone Admin Forum Add your forum

NEWS: Chatbots.org survey on 3000 US and UK consumers shows it is time for chatbot integration in customer service!read more..

How to preprocess a special trigger?
 
 

I am storing the name of the user in a database and from time to time, the database sends the session a message “setname username”. See the example:

setname *
- <
set name=<formal>>

+ (
what is my name|who am i)
You're <get name>, right?

+ didntlike
- {topic=nlike}Why?

> topic nlike

+ *
- {topic=random}Thanks for charing.

< topic

+ *
- I don'
t have a reply for that.
- Try 
asking that a different way

The problem is when the user is in a topic like ‘nlike’ that is exited by * and I send the message to set the name, then the conversation exits the topic.

Is there a way to treat that in the begin block? I tried different syntaxes, but no positive result. I thought of something like:

begin

setname *
- <
set name=<formal>>

request
{ok}

begin 

Thanks!

 

 
  [ # 1 ]

Update: I’ve created a question with bounty on Stackoverflow for this. Url: https://stackoverflow.com/questions/48007450/how-to-preprocess-a-special-trigger-in-rivescript-python

 

 
  [ # 2 ]

Two ideas:

1. The default topic is named “random”, and topics can include/inherit other topics.

Knowing this, you could make a special topic of super important triggers that must work everywhere, and make the “random” topic include that one.

topic important
    
setname *{weight=9991234}
    
- <set name=<star1>>
topic

topic random includes important
    
// you don't actually need to put anything inside here, since triggers
    // without a topic are in the "random" topic automatically, but this
    // topic declaration line will make "random" include "important"
topic

// but for your other topics, include the important one
topic nlike includes important
    
+ *
    - 
{topic=random}Thanks for caring.
topic 

Note: “include” means the triggers from “important” would appear in “random” as if they were in there in the first place. The {weight} tag then hoists these triggers to the very top of the sort list so they’re tested first for all messages.

2. Use an object macro in the begin block

begin
    
request
    
* <call>intercept</call> == true => <get intercepted_reply>
    - 
{ok}
begin

object intercept javascript
    
var message rs.getUservarrs.currentUser(), "originalMessage" );
    var 
message.match(/^setname (.+?)$/);
    if (
m{
        rs
.setUservar(rs.currentUser(), "name"m[1]);
        
rs.setUservar(rs.currentUser(), "intercepted_reply""Name set!");
        return 
true;
    
}
    
return false;
object 

That example also assumes that in your code (before calling `reply()`) you set the user variable `originalMessage` to their message, so that the macro can parse it out. There isn’t currently a way for the object macro to get the message yet, because the “message” that the begin block sees is the word “request”

 

 
  [ # 3 ]
Noah Petherbridge - Jan 19, 2018:

Two ideas:

1. The default topic is named “random”, and topics can include/inherit other topics.

Knowing this, you could make a special topic of super important triggers that must work everywhere, and make the “random” topic include that one.

topic important
    
setname *{weight=9991234}
    
- <set name=<star1>>
topic

topic random includes important
    
// you don't actually need to put anything inside here, since triggers
    // without a topic are in the "random" topic automatically, but this
    // topic declaration line will make "random" include "important"
topic

// but for your other topics, include the important one
topic nlike includes important
    
+ *
    - 
{topic=random}Thanks for caring.
topic 

Note: “include” means the triggers from “important” would appear in “random” as if they were in there in the first place. The {weight} tag then hoists these triggers to the very top of the sort list so they’re tested first for all messages.

2. Use an object macro in the begin block

begin
    
request
    
* <call>intercept</call> == true => <get intercepted_reply>
    - 
{ok}
begin

object intercept javascript
    
var message rs.getUservarrs.currentUser(), "originalMessage" );
    var 
message.match(/^setname (.+?)$/);
    if (
m{
        rs
.setUservar(rs.currentUser(), "name"m[1]);
        
rs.setUservar(rs.currentUser(), "intercepted_reply""Name set!");
        return 
true;
    
}
    
return false;
object 

That example also assumes that in your code (before calling `reply()`) you set the user variable `originalMessage` to their message, so that the macro can parse it out. There isn’t currently a way for the object macro to get the message yet, because the “message” that the begin block sees is the word “request”

Thanks for your answer Noah. I’ve tried both solutions. The first one worked well. Although your object macro in Rivescript Playground gone out of topic in the setname message. I also tried making an object macro on Python Rivescript and it didn’t work with that begin block.

This is my expected test case:

Mehello
Bot
I don't have a reply for that.
Me: didntlike
Bot: Why?
Me: setname John
Bot:
Me: I didn'
t like because I wanted a greeting.
BotThanks for sharing.
MeWho am I?
BotYou're John, right? 
 

 
  [ # 4 ]

That object example wouldn’t work on the Playground because it requires cooperation with the code running the RiveScript bot itself.

It relies on the user variable “originalMessage” being set to the user’s original message before reply() gets called. So for your custom bot’s code, you could do something like this:

# (in python)
username "kirsle"
message "setname John"

# first, set their user variable so it can be retrieved in the object macro,
# then get a reply as normal
bot.set_uservar(username"originalMessage"message)
reply bot.reply(usernamemessage

One of the first things reply() does is test the begin block by calling its “request” trigger. The object macro in the condition then looks up the current user’s originalMessage, parses it to see if it fits the “setname *” pattern, and handles it returning a response that the condition can check to see what happened.

Another thing to note is that, since the macro ran in the condition half of the reply, its text output can’t be given to the user very easily. So the macro sets a user variable “intercepted_reply” before it finishes, and the reply half of the condition uses <get intercepted_reply> to return it to the user.

 

 
  login or register to react