13. Advance Conversation Rules¶
In this chapter, we are going to see more advance options that are available for the use of the conversation rules to provide more tools for defining more complete scenarios, or just easy the use of Lope to operators.
13.1. Conditional External Connector Execution¶
This feature allows the external connector to wait for certain conditions before starting to interact with third parties. This feature needs the use of multi external connector memory varibales, because the external connector starts its execution but it does not interact directly with third parties. It will wait until some conditions are satisfied (memory variables in Redis have the right values), before starting any interaction. We can say that the external connector is ‘sleeping’ until the right time to ‘wake up’.
In order to use this functionality, you have to configure it in the operation
section of the conversation rules. It can get the IP and port for the execution from some
memory variables as well, so as to start the execution using dynamic data. The memory variables used for the conditions can be different for those declared to be used in the
interaction, therefore you do not need to declare them as you do for those you are going to use. In the following example you can see how this can be configured.
# -----------------------------------------------------------
# Operational parameters of the interation
# and connection with third parties
# -----------------------------------------------------------
operation:
# GENERAL ASPECTS
# ===============
...
# TO ENABLE TLS/DTLS USE
# ======================
...
# SOCKET CONNECTION CLOSE
# =======================
...
# SESSION SUPPORT
# ===============
...
# CONDITIONAL EXT CONN EXECUTION
# ==============================
conditional_execution:
# use conditional execution in this execution?
enable: no # yes/no(default)
# list of conditions: memory values and the value
conditions:
# One condition
- var_name: order_66
value: True
# Another condition
- var_name: order_67
value: False
# If present, the ip value will be
# gathered from this memory variable
mem_var_ip: var1
# If present, the port value will be
# gathered from this memory variable
mem_var_port: var2
# OTHER TOPICS
# ============
# Additional aspects should be defined here, but
# they will be described in the respective sections
# of this documentation, for the sake of clarity
...
13.2. Async Switch¶
We have already seen that one custom rule can trigger several async or hybrid custom rules as well. However, the ‘OR’ is missing, this means that you may trigger this set of custom rules asynchronously, or this another set of them; depending on some conditions (memory variables and their values). This provides flexibility to interact differently depending on the execution context, so alternative interactions now can take place.
In order to configure that, you can follow the below example. Any ‘case’ of the ‘switch’ has to define the list of conditions
that make it applicable,
and the list of rules
to trigger asynchronously when that happens. The ‘switch’ structure is made up of options
(cases) and the dafault
(when
no option is applicable). However, the default
one is optional.
any_custom_rule:
# GENERAL FIELDS
# ==============
...
# ASYNC SWITCH
# ============
# Switch for executing some async (or hybrid) rules depending
# on conditions. E.g., ff memory variable 'AAAA' has the value
# 'X' (value field), or it has the same content of the memory
# variable 'BBB', then execute the async Rule 'N'. In case no
# option fits, use the async rule of the default field (if present,
# and the list length is greater than 0)
async_switch:
options:
# first option or 'case' wit a list of conditions to satisfy
- conditions:
# list of conditions
- var_name: var1
value: 2
reference_variable: var2
# if conditions are satisfied, then a set of async
# (or hybrid) rules to execute
rules:
- rule_id: 3
delay: 3
# second option or 'case'
- conditions:
- var_name: var1
value: 2
reference_variable: var2
rules:
- rule_id: 3
delay: 3
# other cases:
# Another case
# - conditions:...
# rules:...
#
# and another one
# - conditions:...
# rules:...
default:
# set of async ruls to execute if no 'case' statement
# is applicable
- rule_id: 3
delay: 3
# OTHER FIELDS
# ============
# Other fields expalined in this documentation
...
13.3. Async Loop¶
The async loop is another interesting feature to model interactions and provide more flexibility. This feature allows you execute a set of rules asynchronously while some conditions are satisfied. Every time the rules are going to be executed, the loop conditions are reviewed for checking if a new iteration should take places. This means that iterations will may take place in different times, according to the different delays of the rules. Howevever, every rule will have its loop. Not all the rules of the loop are executed in every iteration, only the rule that is going to be executed. Therefore, we can say that we have several parallel virtual loops in place with the memory same conditions.
any_custom_rule:
# GENERAL FIELDS
# ==============
...
# ASYNC LOOP
# ==========
# Switch for executing some async (or hybrid) rules depending
# on conditions. E.g., ff memory variable 'AAAA' has the value
# 'X' (value field), or it has the same content of the memory
# variable 'BBB', then execute the async Rule 'N'. In case no
# option fits, use the async rule of the default field (if present,
# and the list length is greater than 0)
async_loop:
# list of the conditions of the loop
# they can use another memory variable
# or a fixed value. In case of both are
# present, the memory variable will be used
conditions:
- var_name: var1
value: 2
# OR
reference_variable: var2
# list of rules to execute
rules:
# this rule will be executed every 3 seconds, 5 times
# as maximum
- rule_id: 3
delay: 3
# if present and grater than 0, this means the number
# of times the iteration can take place per each rule
max_number_iterations: 5
# this rule will be executed every 5 seconds
- rule_id: 17
delay: 5
# OTHER FIELDS
# ============
# Other fields expalined in this documentation
...
13.4. External Connector Fork¶
If having an external connector (or some of them) is great, why not inviting more to the party?!. This is exactly what this feature does: It allows you to create new external connectors during the interaction.
any_custom_rule:
# GENERAL FIELDS
# ==============
...
# EXT CONN FORK
# =============
# You can create new instances of external connectors
# if a rule is executed and optionally, passing a
# new configuration file, external connector id and
# password (secret). If these parameters are not provided,
# the new instance of external connector will start as
# as the original did (this is powered by python subprocess module)
fork:
# is this feature enable?
enable: yes
# Optional parameters.
# -------------------
# If they are not provided, the paremeters of the current
# external connector will be used
# config file to use for the new external connector
config_file: "/path/to/a/different/config/file"
# ID to use for the new external connector
new_id: "Terminator"
# password to use for the new external connector
new_secret: "sshhhhhh...it's_a_secret"
# number of instances to create
number: 3 # Number of instances to create
# OTHER FIELDS
# ============
# Other fields expalined in this documentation
...
13.5. Conversation Rules Groups¶
As you may have already realised, for complex interaction scenarios you will need a lot of rules. This could be a performance issue when you have a new input, despite of having a parallel analysis of the potential RegEx. In order to overcome that issue, the rule groups comes into play: they group rules in blocks, and that block is only applicable under some conditions (It could be a RegEx, or some values for some memory variables). In any case, the rules of the group are not evaluated (or disabled) until the group applicable.
This measure can really help in the reduction of the number of RegEx evaluations, apart of providing a bit of order in the conversation rule file. Just for your information, groups are evaluated after the evaluation of the non-grouped conversation rules. Below you can find how you can implement that feature in the conversation rule file:
# -----------------------------------------------------------
# Conversation Rules
# -----------------------------------------------------------
conversation:
greetings:... # Basic Rule
default:... # Basic Rule
empty:... # Basic Rule
timeout:... # Basic Rule
ending:... # Basic Rule
custom_rules: # Set of custom rules
# GROUPED RULES
# ------------
groups:
# list of groups
# One group that is enabled using regex
- id: group_A
# The regex that makes this group applicable
regex: [any regex]
# list of custom rules
rules: ...
# Another group is enabled using memory variables
- id: group_B
# List of memory conditions that make the group applicable
memory_conditions:
# var1 == fixed_value?
- var_name: var1
value: [any fixed_value]
# var2 == var3?
- var_name: var2
reference_variable: var3
# list of custom rules
rules: ...
# NON-GROUPED RULES
# -----------------
rules: ... # list of custom rules that do not
# belong to any group
13.6. Multiple Conversation Rules Files¶
We have seen that there are plenty of possibilities about what you can do with the rules and the memory variables. However, having everything in one file could be a madness to work with that. The proposed solution is to split the conversation rules file into a primary one, and a set of auxiliary ones that will be imported at the time of loading the primary conversation rules file.
This also allows that you can have some things defined in specific files and imported into several different conversation rules files. The things that you can put in this secondary kind of files are custom conversation rules, and memory variables declaration. The auxiliary files can import other auxiliary files as well, providing more flexibility at the time of creating smaller piece of conversarion rules in different files.
In order to this, you have to do the following in the primary conversation rule file:
# ====================================================
# EXAMPLE PROTOCOL
# Author: Alberto Dominguez
# ====================================================
# this is just a field just for 'operators', it is not relevant for operation
name: example
# Which external connector group is assigned for this rules.
# If empty, or 'default' ==> no group (only one file valid without group)
ext_conn_group: B
# This enables the use of this conversation rules.
# This means that you can have some conversation rules files
# that are in the folder, but they are deactivated and then,
# they will no be sent to any external connector.
enable_use: no # yes/no (default).
# -----------------------------------------------------------
# Operational parameters of the interation
# and connection with third parties
# -----------------------------------------------------------
operation: ... # to be explained later
# -----------------------------------------------------------
# Execution memory
# -----------------------------------------------------------
memory_variables:
# some memory variables defined (if any)
# ...
multi_extconn_level:...
global_level:...
connection_level:...
# list of files to import
import:
# ALWAYS IMPORT .YML FILES!
- path: /path/to/auxiliary/file/for/more/memory/variables.yml
is_relative: yes
# -----------------------------------------------------------
# Conversation Rules
# -----------------------------------------------------------
conversation:
greetings:... # Basic Rule
default:... # Basic Rule
empty:... # Basic Rule
timeout:... # Basic Rule
ending:... # Basic Rule
custom_rules:
rules:...
groups:...
# list of files to import
import:
# ALWAYS IMPORT .YML FILES!
- path: /path/to/auxiliary/file/for/more/custom/rules.yml
is_relative: yes
And, in any auxiliary conversation rule file, you can add the following information:
# ====================================================
# AUXILIARY CONVERSATION RULE FILE
# Author: Alberto Dominguez
# ====================================================
# this is just a field just for 'operators',
# it is not relevant for operation
name: additional file x32
# Fields used at the time of importing memory variables
# -----------------------------------------------------
multi_extconn_level:...
global_level:...
connection_level:...
# Fields used at the time of importing conversation rules
# -------------------------------------------------------
rules:...
groups:...
# Fields used to import additional auxiliary files
# ------------------------------------------------
# list of files to import
import:
# ALWAYS IMPORT .YML FILES!
- path: /path/to/another/auxilary/file.yml
is_relative: yes
The auxiliary files can have any of those fields, bnut they are not mandatory. It could happen that one file has one one field of them, or you have rules and memory variables in the same file, but this file should be used in the memory and in the rules sections to really import the whole content.
The following image expand the previous used image of how the external connectors are linked with the conversation rules, adding some different imported files to the existing example.