How to preprocess a special trigger in Rivescript-Python?

540 Views Asked by At

My bot stores the name of the user in a database, and, from time to time, the database sends the session a message “setname username”. Sample rivescript:

+ 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.

Expected conversation:

Me: hello
Bot: I don't have a reply for that.
Me: didntlike
Bot: Why?
Me: setname John
Bot:
Me: I didn't like because you are ugly.
Bot: Thanks for charing.
Me: Who am I?
Bot: You're John, right?

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

One workaround is to add the same trigger inside all topics, but I need a better solution, because that approach is error prone as my rive files get bigger.

==== Code tried based on Nelson's answer =====

> begin
    + request
    - {ok}{topic=specialtriggers}
< begin

> topic specialtriggers

+ setname *
- <set name=<formal>>

< topic

+ (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.

I think adding the topic to {ok}{topic=specialtriggers} making all triggers outside this topic fail. After the preprocessing, Rivescript should answer if it is a specialtrigger or else search for the normal triggers.

2

There are 2 best solutions below

0
On BEST ANSWER

Answer based on Noah Petherbridge's response on chatbots.org, one viable solution is using topic inheritance:

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

> topic random includes specialtriggers
    // 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 specialtriggers one
> topic nlike includes specialtriggers
    + *
    - {topic=random}Thanks for caring.
< topic
1
On

If your question is only about how to always preprocess user message using begin block, the answer is:

  • Don't need to enter trigger into the begin block. A + request is generic representation of any user message.
  • If you would like to limit the triggers to be matched in begin block only from current topic, an {ok} tag is sufficient.

Modify your code as follow

+ didntlike
- {topic=nlike}Why?

> topic nlike
    + *
    - Thanks for charing.
< topic

> begin
    + request
    - {ok} (Preprocessed in begin)
< begin

Try the following sequence of message didntlike, hello, and you will see the replies are appended with (Preprocessed in begin).

  • Otherwise, reply in begin block need to add a topic where (which topic) to fetch the triggers and replies from. If you would like to fetch the trigger for setname in random topic, you can add the begin block into the end of your first code snippet.

The RiveScript code

> begin
    + request
    - {ok}{topic=random}
< begin

In this case, the topic after serving the request to setname is topic random.