Extract flows triggered, raised, dropped from processing path at runtime

At the end of each transaction during a Teneo session we would like to extract some general information about what happened during the session: which trigger became active, which flows and sub flows were raised and dropped, etc. More or less the information you see in try out in the icons under the user input:

image

We also would like to log the Teneo and solution version as shown in the publish view.

We will use TQL of course, but this requirement is for an additional logging platform. So during the session we want to save this information, and at session end we would log it via an external api.

  1. How can we use groovy to extract trigger/flow path from the processing path?
  2. Which API call returns the solution/teneo version? (could not find one in the api description).

Thanks in advance for any suggestions!

1 Like

Hi Fred!

As for the first question, I believe the best option is to to this in an End Dialog groovy script, where you use the dialog history to pick out the information you need.
Here’s a groovy snippet which picks out a few fields, but you will need to change the structure to suit the requirements for where you’re sending the information.

def log = []

_.dialogHistory.each { t ->
  def transaction = []
  t.path.each { e ->
    // The type of events that you're interested in, these mirror the names of pathType in Inquire, but in camel case
    if(e.type in ['raiseFlow', 'flowTrigger', 'dropFlow']) {
      def event = [:]
      event['type'] = e.type
      event['flowName'] = e.flowName
      event['flowFolder'] = e.flowFolder
      event['flowId'] = e.flowId
      // Use the elvis operator to get a default value in the event object
      event['subFlow'] = e.subFlow ?: false
      transaction.add(event)
    }
  }
  log.add(transaction)
}
def json = new groovy.json.JsonBuilder(log).toString()
// Instead of println you would here send the json to the logging service
println json

As for your second question, the bot has a /status endpoint which with the verbose flag can provide you with this information.
So you can reach it with https://bot-server.example/bot-name/status?verbose and it should give you Version and Current-Solution-Revision .

Eric

This looks fantastic! Thanks, Eric.

One question, though. Can we also do this in what we know will be the last transaction?
At the End Dialog location we no longer have access to the calling service. So we would intend to return the information via an output parameter.

Worked out this snippet of groovy code to retrieve the version - any groovy gurus reading this, please feel free to suggest improvements:

// Retrieve Teneo version from status URL
// Result will have format, e.g.: Teneo=6.1.0;Solution-Revision=2342

def sVersion = “”
def sRevision = “”

def url = sTeneoStatusUrl.toURL()

url.eachLine {
if (it.contains(“Version”)) { sVersion = it }
if (it.contains(“Current-Solution-Revision”)) { sRevision = it }
}

sVersionRevision = sVersion.replace(“Version”,“Teneo”)+";"+sRevision.replace(“Current-”,"")

1 Like

Great, thanks for sharing, Fred! :grinning: (@Fred.Roberts )

1 Like

Hi @Fred.Roberts!

Another way to do this would be to read the properties and their values into a map using splitEachLine:

def properties = [:]
url.splitEachLine("=") {
    properties << [(it[0]): it[1]]
}

which gives you a map looking something like this (edited for clarity - there are more properties in the full response):

{
    "Teneo-Solution-Full-Published-At": "2021-09-28T11:50:27Z",
    "Teneo-Solution-War-Version": "377",
    "Teneo-Platform-Version": "6.1.1",
    "Teneo-Solution-Engine-Version": "20210812120802",
    "Teneo-Solution-Id": "...",
    "Teneo-Solution-Customer-Id": "...",
    "Teneo-Solution-Initial-Revision": "377",
}

then you could build the string by the property names:

"Teneo:${properties["Teneo-Platform-Version"]},Solution:${properties["Teneo-Solution-Initial-Revision"]}"

This then ensures that you get the exact property value that you are after
With the contains("Version") approach the value you end up with will be whichever one was last in the version response as several of the property names contain “Version”

1 Like

Nice! Thanks, Roger.

As an extension to the script which extracts information from the dialogue history, how can we extract the same from the current transaction? This appears not yet to exist in the history. Is that doable?

Hi Fred,
yes, the data for the current transaction is available using _.processingPath , please see more in EngineAccess (Teneo Engine Scripting API) . This corresponds to one of the entries in the Dialog History.

Hope this helps!
Eric

Thanks Eric!

Is there a way to combine _.dialogHistory with _.processingPath to have one structure to process instead scanning both of them?

E.g. def dh=.dialogHistory; dh= dh<<.processingPath

Was trying a bit and couldn’t find anything that worked. (Except repeating the same processing steps with the separate structures, which is a bit of redundant code).

Hi Fred, I think it’s a great idea to follow the DRY (Don’t Repeat Yourself) approach. :slight_smile:

I would solve this with a Groovy closure like this


def extractHistoryFromPath = { pathElement ->
  // Implement logic to get details from pathElement
}

_.dialogHistory.each { transaction ->
  transaction.path.each { path ->
    extractHistoryFromPath(path)
  }
}
_.processingPath.each { pathElement ->
  extractHistoryFromPath(pathElement)
}

This will let you implement the logic for path elements once and use it in both places.

(You might need to adapt this to use .collect instead of .each depending on if you’re collecting the information on each path element or iterating over all path elements.)

I hope this helps!
Eric