SAFRActions.config

The SAFRActions.config file defines which events will trigger specified actions. You can also specify additional condition constraints before the action(s) will trigger. It also contains basic configuration information so that ARES can communicate with other SAFR components, such as the Event Archive.

SAFRActions.config JSON Schema

{
   environment : "string",
                 <optional, 
                 - values: "LOCAL", "DEV", "INT2", "PROD", "Custom"
                 - if not specified assumed PROD >
   eventServer : "string", 
                 <optional, 
                 - required in case of Custom environment
                 - only affects Custom environment>
   replyServer : "string", 
                 <optional,
                 - only affects Custom environment>
   coviServer : "string",
                 <optional,
                 - only affects Custom environment>
   reportServer : "string",
                 <optional,
                 - only affects Custom environment>
 
   configServer : "string",
                 <optional, "https://cvos.int2.real.com" for 
                                            integration environment
                            "https:\/\/cvos.real.com" for 
                                            production environment
                 - if specified Config is retrieved from Cloud using
                  following address: <configServer>/obj/ares/<aresId> >
 
   userId :      "string", <optional>
   userPwd :     "string", <optional, encrypted or open text>
  
   directory :   "string", <required>
   site :        "string", <optional>
   source :      "string", <optional>
  
   aresId :      "string", <optional>
  
   maxEventLatency: <long>,  <optional, in milliseconds, default = 8000>
 
   logActionResponses: <bool>,  <optional, default = false>
 
   rules: [
      {
        event : {
          type: [ "string", ... , "string" ],       
                 <optional, values=(person, tag, action, or recognizedObject), default = all> 
          personType: [ "string", ... , "string" ], 
                 <optional, default = all, "" = no personType>
          personTags: [
                 [ "string", ... , "string" ],
                 ...
                 [ "string", ... , "string" ]
          ]
                 <optional, default = all>
          tagType: [ "string", ... , "string" ]     
                 <optional, values=(april), default = all, "" = no tagType>
          tagId: [ "string", ... , "string" ],     
                 <optional, values=(Ids of tagType) default = all, "" = no tagId>
          actionType: [ "string", ... , "string" ],
                 <optional, values=(smileToActivate) default = all, "" = no actionType>
          actionId: [ "string", ... , "string" ],
                 <optional, default = all, "" = no actionId>
          directionId: [ "string", ... , "string" <"left", "right", "up", "down"> ],
                 <optional, default = all, "" = no directionId>
          ended: <boolean>,                   
                 <optional, default = false>
          name: [ "string", ... , "string" ],       
                 <optional, default = all, "" = no name>
          company: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          moniker: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no moniker>
          personId: [ "string", ... , "string" ],   
                 <optional, default = all, "" = no personId>
          hasPersonId: <boolean>,                   
                 <optional, default = all>
          hasFaceId: <boolean>,                   
                 <optional, default = all>
          hasName: <boolean>,                       
                 <optional, default = all>
          hasMoniker: <boolean>,                      
                 <optional, default = all>
          hasRootEventId: <boolean>,                   
                 <optional, default = all>
          gender: [ "string", ... , "string" ],     
                 <optional, default = all>
          age: [                                    
                 <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ],
          smile: <boolean>,                         
                 <optional, default = all>
          avgSentiment: [                              
                 <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ],
          liveness: {                             
                 <optional, default = all>
             min: <float>,
             max: <float>
          },
          livenessConfirmed: <boolean>,                       
                 <optional, default = all>
          mask: <boolean>,                       
                 <optional, default = all>          
          similarityScore: {                             
                 <optional, default = all>
             min: <float>,
             max: <float>
          },
          occlusion: {                             
                 <optional, default = all>
             min: <float>,
             max: <float>
          },
          site: "string",                           
                 <optional if specified at the root>
          source: "string",                         
                 <optional if specified at the root>
          idClass: [ "string", ... , "string" ],                      
                 <optional, default = all, "" = no idClass>
          directGazeDuration: {                             
                 <optional, default = all>
             min: <long>,
             max: <long>
          }
          objectType: [ "string", ... , "string" ]    
                 <optional, default = all, "" = no objectType>
          objectId: [ "string", ... , "string" ],     
                 <optional, default = all, "" = no objectId>
          accessClearance: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          accessClearanceLevel: {                             
                 <optional, default = all>
             min: <long>,
             max: <long>
          }
          accessCardId: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          accessFacilityId: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          accessCardFormat: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          groups: [
                 [ "string", ... , "string" ],
                 ...
                 [ "string", ... , "string" ]
          ]
                 <optional, default = all>
          srcUserId: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          statusType: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          feed: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          processor: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          mode: [ "string", ... , "string" ],      
                 <optional, default = all, "" = no company>
          longitude: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          latitude: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          altitude: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          srcHeading: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          srcHeadingPitch: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          srcOrientation: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          srcOrientationPitch: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
          srcSpeed: [                                   
               <optional, default = all>
             {
                min: <float>,
                max: <float>
             },
             ...
          ]
       }
  
       triggers : [
          {
             triggerId : "string", 
                 <optional>
             daysOfWeek: ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],       
                 <optional, default = all>
             timesOfDay: [                          
                 <optional, default = all>
                {
                   start: "11:00",                  <required>
                   end: "17:00"                     <required>
                },
                ...
             ],
             actions: [                             
                 <required - can be empty (no actions)>
                "string",
                ...
             ],
             reply: {                               
                 <optional, default = no reply>
                "replyDelay": long,
                     <optional, in milliseconds, default = 0>
                "message": "string",                
                     <optional, default = no message>
                "disposition": double,
                     <optional, range [-1 .. 1], default = 1>
                "tags": [ "tag1", ... "tagN" ]      
                     <optional, default = no tags>
             },
             conditionalReply: [  
                 <optional, default = no conditional reply>                    
                 {       
                      "actionResponse": [ integer, ..., integer ],   
                           <required>                     
                      "replyDelay": long,
                           <optional, in milliseconds, default = 0>
                      "message": "string",               
                           <optional, default = no message>
                      "disposition": double,
                           <optional, range [-1 .. 1], default = 1>
                      "tags": [ "tag1", ... "tagN" ]     
                           <optional, default = no tags>
                 }
                 ...
             ],
          },
          ...
       ],
  
       excludeDates : [                             
           <optional, default = none>
                "7/4",
                "12/25",
                "4/10/2017",
                ...
       ],
 
       triggerFrequencyLimit : {
           <optional, default = unlimited>
          "minSeparationInterval" : long,
               <optional, in milliseconds, default = 0>,
          "spanRootPersonIds": bool,
               <optional, default = false>
          "spanSources" : bool,
               <optional, default = false>
          "spanSites" : bool
               <optional, default = false>
       }
      }
      ...
   ],
  
   noTriggerReply: {                                
                 <optional, default = no reply>
      "replyDelay": long,
                     <optional, in milliseconds, default = 0>
      "message": "string",                          
                     <optional, default = no message>
      "disposition": double,
                     <optional, range [-1 .. 1], default = -1>
      "tags": [ "tag1", ... "tagN" ]                
                     <optional, default = no tags>
   },
  
   nFactorDef: [
      {
         "name": string,              
            <required>
         "failOnMismatch": string,      
            <optional: "delayed"/"immediate"/"none", default = "delayed">
         "maxDelay": <milliseconds>,    
            <optional, default = 60000 (1min)>
         "factors": [
            "<factor_name>|<factor_value>",
            ...
         ],
         "actions": [
            "<action_command>",
            ...
         ]
      },
      ...
   ],
   emailDef: [
      {
         "label": string,             
            <required>
         "recipients": [ "recipient1", ... "recipientN" ],               
            <required, escape sequences can be used>
         "subject": string,             
            <required, escape sequences can be used>
         "cc": [ "cc1", ... "ccN" ],               
            <optional, escape sequences can be used>
         "bcc": [ "bcc1", ... "bccN" ],               
            <optional, escape sequences can be used>
         "message": string,             
            <optional, escape sequences can be used>
         "attachments": [ "attachment1", ... "attachmentN" ],               
            <optional, escape sequences can be used
             http://, https://, cvos:// url schemes are supported, not to indicated file type,
             so attachment looks ok prepend | with a file name, for instance: cvos:://xyuz/best|bestimage.jpg>
      },
      ...
   ],
      smsDef: [
      {
         "label": string,             
            <required>
         "recipients": [ "recipient1", ... "recipientN" ],               
            <required, escape sequences can be used, phone numbers using the the E.164 format required>
         "maxPrice": string,             
            <optional>
         "message": string,             
            <optional, escape sequences can be used>
      },
      ...
   ],
}

rules

event

trigger

conditionalReply and reply

actions

Action and Reply Message Escape Sequences

#N - name
#F - first name (name prefix up to first white-space)
#U - surname (name postfix: staring after first white-space sequence to the end of name string)
#T - person type
#S - source
#I - site
#D - person id
#R - root person id
#E - person external id
#G - gender
#A - age       (###)
#M - sentiment (#.##)
#L - smile     (true/false)
#V - event type
#v - event id
#B - tag type
#C - action type
#b - tag id
#c - action id
#k - direction id
#s - event start time (milliseconds since epoch)
#r - event start date/time (local time)
#p - validation phone
#e - validation email
#H - home location
#t - personTags (comma separate list of personTags)
#O - company
#m - moniker
#<d>m - moniker substring (delimited by white-space) 
        indexed by single decimal digit 0-9 .  E.g.:  #0m or #3m
#l - similarityScore (#.####)
#a - idClass
#Z - directGazeDuration
#o - objectType
#d - objectId
#u - occlusion (#.##)
#i - liveness (#.##)
#n - livenessConfirmed (true/false)
#z - mask (true/false)
#X - access clearance
#x - access clearance level
#Q - access card id
#q - access facility id
#f - access card format
#g - groups (comma separate list of groups)
#j - source user id
#w - status type
#K - feed
#P - processor
#W - mode
#1 - longitude
#2 - latitude
#3 - altitude
#4 - source heading
#5 - source heading pitch
#6 - source orientation
#7 - source orientation pitch
#8 - source speed
#9 - source position time (milliseconds since epoch)
#0 - source position date/time (local time)

The \ character is used as an escape character. Thus, if you wanted the string "Welcome, Ms. #N!" to appear as a reply, you would need to have the following in your config file:

"reply" : {
    "message" : "Welcome, Ms. \#N!"
},

Passing Script Arguments

When passing in simple arguments, you simply pass in the arguments with white space separating them from the script and from each other. For example:

"actions": [
    "python ./scripts/write_result.py Jamie"
],

When a single argument contains whitespace, or when you want to use one of the #<letter> tokens listed above on a Windows machine, use escaped "" characters. For example:

"actions": [
    "python ./scripts/write_result.py \"Jamie Rodriguez\""
],

or

"actions": [
    "python .\\scripts\\write_result.py \"#N\""
],

Note the need to escape the path separator character \ in the Windows example above.

When you want to use one of the #<letter> tokens listed above on a Linux machine, use escaped '' characters. For example:

"actions": [
    "python ./scripts/write_result.py \'#N\'"
],

N-factor Actions

When the action starts, the following occurs:

Response codes for nFactorStart actions:

nFactorStart-ed actions are resolved via nFactorResolve commands. When all factors needed for the actions are resolved, actions are executed:

{
   triggerId : "string",
   ...
   actions: [                            
      "@nFactorResolve <name> <factor_name>|<factor_value>",
      ...
   ],
   reply: {       
      ...
   },
   conditionalReply: [                              
      ...
   ]
}

@personEventFromMoniker action generates a pseudo person event from moniker created by combining all the resolved factor values (separated by space) in the order listed in factors array. The generated event is of type person which is populated with the meta-data of person with moniker matching the assembled moniker value.

{
   nFactorDef : [ {
      factors : [
            "moniker|**",
            "moniker|1**",
            "moniker|2**",
            "moniker|3**"
      ],
 
 
      actions : [
            "@personEventFromMoniker"
      ]                   
      }
   ]
}

Email Actions

To send emails using actions, you must do the following:

  1. Obtain an SMTP server account that you can use to send emails.

  2. Configure SAFR so that it's ready to use your SMTP server account to send emails. You can do this from the Status page of the Web Console. On Windows and macOS machines, you can also do this via Tools -> Configure Email Server in SAFR Actions.

  3. Configure the emailDef section of the SAFRActions.config, as described below. Note that your emailDef section can define multiple emails, each one being identified by the label field.

    emailDef: [
        {
            "label": string,             
                <required>
            "recipients": [ "recipient1", ... "recipientN" ],               
                <required, escape sequences can be used>
            "subject": string,             
                <required, escape sequences can be used>
            "cc": [ "cc1", ... "ccN" ],               
                <optional, escape sequences can be used>
            "bcc": [ "bcc1", ... "bccN" ],               
                <optional, escape sequences can be used>
            "message": string,             
                <optional, escape sequences can be used>    
            "attachments": [ "attachment1", ... "attachmentN" ],               
                <optional, escape sequences can be used
                    http://, https://, cvos:// url schemes are supported>
        },
    ]
    • label: The label used to identify this particular email.
    • recipients: One or more email addresses where the email will be sent.
    • subject: The text that will appear in the email's subject line.
    • cc: List of email addresses that will be cc'ed on the email.
    • bcc: List of email addresses that will be bcc'ed on the email.
    • message: The text that will be the body of the email.
    • attachments: The location of any attachments you want to attach to the email.
  4. In the actions field of SAFRActions.config, enter a string with the following syntax: "@emailSend <label>", where <label> = the label of whichever email within your SAFRActions.config that you want to use.

SMS Actions

To use Short Message Service (SMS) notifications within actions, you must do the following:

  1. Obtain an AWS account which is configured for your region so it can send SMS messages.

  2. Configure SAFR so that it's ready to use your AWS account to send SMS notifications. You can do this from the Status page of the Web Console. On Windows and macOS machines, you can also do this via Tools -> Configure SMS Sender in SAFR Actions.

  3. Configure the smsDef section of the SAFRActions.config, as described below. Note that your smsDef section can define multiple SMS messages, each one being identified by the label field.

    smsDef: [
       {
          "label": string,
             <required>
          "recipients": [ "recipient1", ... "recipientN" ],
             <required, escape sequences can be used, phone numbers using the the E.164 format required>
          "maxPrice": string,
             <optional>
          "message": string,
             <optional, escape sequences can be used>
       },
    ]
    • label: The label used to identify this particular SMS message.
    • recipients: The list of recipients to receive the SMS message, formatted using the E.164 format. (e.g. +12065551313)
    • maxPrice: The maximum amount in USD that you are willing to spend to send the SMS message. Amazon SNS will not send the message if it determines that doing so would incur a cost that exceeds the maximum price. See the description of the AWS.SNS.SMS.MaxPrice attribute here for more information about this field.
    • message: The text message to be sent.
  4. In the actions field of SAFRActions.config, enter a string with the following syntax: "@smsSend <label>", where <label> = the label of whichever SNS message within your SAFRActions.config that you want to use.

Sample SAFRActions.config Files

See Also