Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
blocks:advanced_scripting:visitor_identity_tracking [2022-03-04 13:20]
admin created
blocks:advanced_scripting:visitor_identity_tracking [2023-01-23 09:23] (current)
admin Added link toapp notes
Line 1: Line 1:
-====== Visitor Identity and Tracking ======+====== Visitor Data Collection ======
  
 A Visitor Spot in Blocks can be used as a basic entry point for visitors to connect to the system. This is essentially a URL allowing a number of visitors to all connect to the same Visitor Spot. The URL looks something like this: A Visitor Spot in Blocks can be used as a basic entry point for visitors to connect to the system. This is essentially a URL allowing a number of visitors to all connect to the same Visitor Spot. The URL looks something like this:
Line 30: Line 30:
 By selecting "Identify Individual Visitors" you gain two important abilities: By selecting "Identify Individual Visitors" you gain two important abilities:
  
-  - For //each individual visitor//independent control over child blocks, parameters, tags, custom CSS classes, etc, similar to what you have for Display Spots. +  - For //each individual visitor// you gain independent control over child blocks, parameters, tags, custom CSS classes, etc, similar to what you have for Display Spots. 
-  - The ability to collect time-stamped data on each individual visitor, such as any data being entered by that visitor, spots being visited, scores of games, etc. +  - The ability to collect data on each individual visitor, such as any data being entered by that visitor, spots being visited, game scores, etc. 
  
 By combining these two abilities, you can do things such as presenting different content to a visitor depending on where she's been during her visit, points earned along the way, or any other data provided or collected during the visit. Such data can also be archived after the visit for subsequent analyzation, e.g. to understand the route taken by visitors, which exhibits they visited, how long they stayed there, etc. By combining these two abilities, you can do things such as presenting different content to a visitor depending on where she's been during her visit, points earned along the way, or any other data provided or collected during the visit. Such data can also be archived after the visit for subsequent analyzation, e.g. to understand the route taken by visitors, which exhibits they visited, how long they stayed there, etc.
Line 42: Line 42:
   - Using an identification tag, such as an RFID bracelet handed out at the reception.   - Using an identification tag, such as an RFID bracelet handed out at the reception.
   - A combination of the above, where the RFID bracelet acts as the primary identification, and an optional mobile device can be associated with the same visitor for interaction and feedback purposes.   - A combination of the above, where the RFID bracelet acts as the primary identification, and an optional mobile device can be associated with the same visitor for interaction and feedback purposes.
-  Pre-qualified visitors, where each visitor is given a unique log-in code ahead of time (e.g., in an email). Additional data on visitor (such as name, company, etc) is pre-loaded into Blocks, and only pre-qualified visitors can gain access.+  Pre-qualified visitors, where each visitor is given a unique log-in code ahead of time (e.g., in an email). Additional data on visitor (such as name, company, etc) is pre-loaded into Blocks, and only pre-qualified visitors can gain access.
  
 === Using Mobile Phone as Only Identification === === Using Mobile Phone as Only Identification ===
Line 52: Line 52:
   - Create a Blocks user script (see below) defining the type of data to record.   - Create a Blocks user script (see below) defining the type of data to record.
   - Select "Identify Individual Visitors" as discussed above.   - Select "Identify Individual Visitors" as discussed above.
-  - Enter the name of the data record in the "Record type" field.+  - Enter the type-name of the data record in the "Record type" field.
  
 === Using an Identification Token === === Using an Identification Token ===
  
-Here, a unique identification token is handed out to each visitor at the entrance. This token could for example be an RFID bracelet och tag, carried by the visitor. By scanning this token at desired stations, Blocks will learn who's where, and can collect and act on this information. The token may be returned when leaving, and recycled for new visitors.+Here, a unique identification token is handed out to each visitor at the entrance. This token could for example be an RFID bracelet och tag, carried by the visitor. By scanning this token at stations, Blocks will learn who's where, and can collect and act on this information. The token may be returned when leaving, to be recycled for new visitors.
  
 This arrangement removes the need for visitors to have and use a personal mobile phone. Depending on the information collected during the visit, this may also remove any privacy issues (assuming no personally identifiable information is collected). More on this below. This arrangement removes the need for visitors to have and use a personal mobile phone. Depending on the information collected during the visit, this may also remove any privacy issues (assuming no personally identifiable information is collected). More on this below.
  
-The visitor can still have a personalized experience, based on where she's been or interactions performed or information entered at visited spots. Personalized information can be presented on Display Spots as the visitor presents the identification token (e.g., scans the RFID bracelet).+The visitor can still have a personalized experience, based on where she's been or interactions performed or information entered at visited spots. Personalized information can be shown on Display Spots as the visitor presents the identification token (e.g., scans the RFID bracelet).
  
 To use this method, do as follows: To use this method, do as follows:
  
   - Create a Blocks user script (see below) defining the type of data to record.   - Create a Blocks user script (see below) defining the type of data to record.
-  - Select "Identify Individual Visitors" as discussed above. 
-  - Enter the name of the data record in the "Record type" field. 
   - Connect the desired number of token scanners (RFID, or similar) to Blocks.   - Connect the desired number of token scanners (RFID, or similar) to Blocks.
   - Scan the token when handing it out to the visitor.   - Scan the token when handing it out to the visitor.
Line 73: Line 71:
 Now, as the visitor scans the token at desired spots, Blocks will learn about this and can take actions as desired (including presenting personalized interactions at display spots).  Now, as the visitor scans the token at desired spots, Blocks will learn about this and can take actions as desired (including presenting personalized interactions at display spots). 
  
-To scan the tokens, you can use either stand-alone scanners connected to the network, managed by a Device Driver in Blocks. Or use a Display Spot with a keyboard-emulating scanner connected to its USB port. Set the Display Spot to use "RFID/QR Keyboard Input" in its Advanced tab.+To scan the tokens, you can use stand-alone scanners connected to the network, managed by a Device Driver in Blocks. Or use a Display Spot with a keyboard-emulating scanner connected to its USB port. Set the Display Spot to use "RFID/QR Keyboard Input" in its Advanced tab.
  
-IMPORTANT: If tokens are reused, make sure tokens are disassociated from their visitors. This can be done in one or more of the following means:+IMPORTANT: If tokens are reused, make sure tokens are disassociated from their visitors. This can be done by one or more of the following means:
  
   * When returned at the exit, by canning it in a specific "exit scanner".   * When returned at the exit, by canning it in a specific "exit scanner".
   * When handed out to another visitor.   * When handed out to another visitor.
-  * En masse, for all tokens, once every night. This method assumes tokens aren't re-used the same day.+  * En masse, for all tokens, once every night. This method assumes tokens aren't re-used during the day.
  
 === Using a Combination of Token and Mobile Phone === === Using a Combination of Token and Mobile Phone ===
  
-This method is essentially the same as the previous one, but with the additional ability of also associating a mobile phone with the same visitor. This may allow for basic tracking and personalized experience using the token, while using an (optionalmobile phone to augment the experience, acting as a personal point of interaction and feedback.+This method is essentially the same as the previous one, but with the additional ability of also associating a mobile phone with the same visitor. This provides basic tracking and personalized experience using the token, while an optional mobile phone enhances the experience, acting as a personal point of interaction and feedback.
  
 To use this method, do as follows: To use this method, do as follows:
Line 96: Line 94:
   - Optionally, also scan the visitors mobile phone. This can be done using a QR code shown on the phone. This links the mobile phone to the same data record as identified by the token.   - Optionally, also scan the visitors mobile phone. This can be done using a QR code shown on the phone. This links the mobile phone to the same data record as identified by the token.
  
-You'll then use the token at each station to identify yourself. The optional mobile phone can be used as feedback (e.g., scores at game stations) or to enter information that will then go into the visitor's data record and/or be directly acted upon by the user script.+You'll then use the token at each station to identify yourself. The optional mobile phone can be used as feedback (e.g., scores at game stations) or to enter additional information that goes into the visitor's data record and/or affects functions in the user script.
  
 ==== Privacy Issues ==== ==== Privacy Issues ====
  
-Depending on what information you collect and the jurisdiction in your country, you may need to pay attention to privacy regulations, such as europe's GDPR law. This can be handled by presenting a notice on visitors' mobile devices that must be agreed to before proceeding, or similar.+Depending on what information you collect and the laws governing your area, you may need to pay attention to privacy regulations, such as europe's GDPR law. This can be done by presenting a notice on visitors' mobile devices that must be agreed to before registering, or similar.
  
  
 ===== User Script ===== ===== User Script =====
  
-To utilize the individual visitor tracking and interaction capabilities, you need a Blocks [[blocks:advanced_scripting|user script]]. This script defines the data that may be collected. It also decides what will happen as visitors arrive at interaction spots.+To create a //personalized visitor journey//, as outlined above, you need a Blocks [[blocks:advanced_scripting|user script]]. This script defines the data that can be collected. It also decides what will happen as visitors arrive at interaction spots.
  
 ==== Data Record Declaration ==== ==== Data Record Declaration ====
  
-A key function of the user script is to declare what data to be collected from visitors. This is done using a //record declaration//, typically located at the beginning of the script. Such a declaration could look line this:+A key feature of this user script is to declare what data to be collected from visitors. This is done using a //record declaration//, typically located at the beginning of the script. Here's an example of such record declaration:
  
 <code> <code>
Line 122: Line 120:
 </code> </code>
  
-The name of this record type is "ExampleRecord". That's the name to enter in the "Record type" field of the Identity tab in the Visitor Spot's settings. The declaration shown above has five data fields. What data fields to use and what they're called depends entirely on what data you want to collect. Each data field must be marked with the @field() decorator. +The name of this record type is "ExampleRecord". That's the name to enter in the "Record type" field of the Identity tab in the Visitor Spot's settings. The declaration shown above has five data fields. What data fields to use, their names and data types, depend entirely on what information you want to collect. Each data field must be marked with either a @field() or an @id() decorator, where @id() indicates a unique ID field (a "secondary key" in database-speak)
  
-In addition to the fields shown above, each record also has a unique identification number named //$puid//, which is declared in the RecordBase base class, which all custom record declarations must extend. This $puid number can be used to uniquely identify each data record. When using the visitors mobile phone as the only identification, this matches the identity ID assigned to the phone when it first connects to Blocks through this mobile spot's URL.+In addition to the fields mentioned above, each record also has a built-in, unique identity field named //$puid//, declared in RecordBase. This is the base class of ExampleRecordas you can see above. All custom record declarations must extend RecordBase. This $puid uniquely identifies each data record. When using a visitor'mobile phone as the only identification, this matches the identity ID assigned to the phone when it first connects to Blocks through this mobile spot's URL.
  
 === Record Field Decorators === === Record Field Decorators ===
  
-As mentioned above, each field in the record must be marked with the @field() decorator, as you can see above. In addition to this mandatory decorator, you may use the following optional decorators:+As mentioned above, each field in the record must be marked with either a @field() an @id() decorator. In addition to these mandatory decorators, you may optionally add a @spotParameter() decorator.
  
-  * **@spotParameter()** marks the field as an alias of a Spot Parameter. +The **@id()** decorator indicates that the field is to be used as a secondary key (an "index" in database terms), allowing the record to be looked up also by this value. This index is in addition to the standard $puid field mentioned above. This is useful in cases where you have other means of identifying the visitor than just mobile phoneFor instance, when using an RFID tag, you'll want the ID number of the visitor's tag stored in a field marked with an @id() decorator. Note that the value in @id() field //must// be unique for any given record type. Thus, if you re-cycle RFID tags, you //must// delete (or archive) any previous record using that same RFID code before assigning it to an @id() field of a new visitor. More on how to delete/archive records below. Use the @id() decorator on its own – do not combine it with @field().
-  * **@id()** marks the field as holding a unique value that can be used to identify the record.+
  
-The **@spotParameter()** decorator causes data stored in the record to be linked to a spot parameter with the same name. You must establish this spot parameter separately, making sure it has the same name and data type as the record field. This can be done either in the Block to be used by the Visitor Spot, or on the Visitor Spot itself (on the Parameters tab of the Visitor Spots settings). Once you've linked the record field to a spot parameter in this way+**@spotParameter()** decorator causes data stored in the record to be linked to a Visitor Spot parameter with the same name and data type. This must be used together with the @field() decorator, as shown above. You must establish this parameter separately, making sure it has the same name and data type as the record field. This must be done in the Block assigned to the Visitor Spot (here accessible as a //Local// parameter). Once you've linked the record field to a spot parameter in this way, any changes made to the parameter will be reflected in the data record field and vice versa. This could, for example, be used to allow a visitor to enter a nickname on her phone, or other relevant information, then automatically stored and persisted in the visitor's data record.
  
-=== Data Record Storage ===+==== Creating and Finding Records ====
  
-In addition to being available inside your user scriptdata records are also stored on disk inside the //record// directory located in your Blocks root directory. Inside this record directoryBlocks creates one sub-directory per record type, named by the record type ("ExampleRecord" in the example shown above)Inside such type-specific subdirectoryyou'll find one directory per record instanceThis is named with //Pn// where //n// is the $puid identified discussed above.+When using a mobile phone (i.e.a Visitor Spot) as the only identifier of a visitor, the associated data record is implicitly created when the visitor connects to BlocksA 'visitor' event is fired on the MobileSpot to indicate this. This event provides Visitor objectwhich represents the individual visitor's mobile phoneThe Visitor object provides access to the data record, allowing you to use this right away.
  
-Inside that record instance directory, you'll find at least a file named "log.tsv". This is a log file of all data stored or changed in the data record, along with a time stamp for each action. This file uses the popular TSV format (a variant of the more well-known CSV format, but using a tabs as separators rather than commas). For each change applied to the data record, a new line is appended to this file, describing what was changed, when the change was made and what the new value is. This data is used by Blocks to resurrect the data in case you must restart the Blocks server while there are active visitors. It can also be used to analyze visitor behavior, by deriving data such as:+When using other means of visitor identification, such as RFID, NFC or other such tokens, there's no automatic record creation. You must then listen for the ID to arrive from the token scanner. You can use a Display Spot to connect many types of such scanners, often exposing the scanned code as its //scannerInput// property- Alternatively, a Device Driver can be used to accept a code from a scanner connected to your network. Once the scanned code appears, you can either use it to look up the corresponding record (assuming it exists), using the //getRecordSec// script function. Alternatively, you can create the record using the //newRecord// Script function. Then remember to immediately store the scanner ID in an @id() field in the record, allowing you to find it later using that ID. 
 + 
 +When using a combination of identity token and mobile devices, you need to find a way by which both these methods of identification can be bound to the same record. In this case, you must use two separate @id() fields, one holding the token's ID and the other the Visitor's phone identity (available in the //identity// field of the associated Visitor object). It's often non-trivial to determine which phone belongs to which token. This can be handled, for example, using dynamically generated QR code shown on the check-in station as the ID token is handed out, where the visitor needs to scan this QR code with her phone to establish the connection. The QR code will then provide both the URL used to access Blocks and the associated token ID (as a query parameter), allowing these two to be set on the same record.  
 + 
 +=== Visitor Lifecycle === 
 + 
 +Note that the Visitor object, provided when a visitor's phone connects to Blocks, is available //only as long as the visitor's phone remains connected//. If the phone disconnects (e.g., the visitor turns it off or closes the web page), the Visitor object is discarded. This is indicated by the 'finish' event being emitted by the Visitor object. You must not hold on to or use a Visitor object beyond this point. Thus, it is important that you listen for this event and release all references to the Visitor object when this event fires. Furthermore, if you open any other event or property subscriptions associated with the Visitor object, you must close those when the Visitor goes away. Doing so avoids memory leaks and the possibility "ghost calls" into code that's no longer supposed to be alive. 
 + 
 +While the Visitor object will come and go as the visitor's phone connects and disconnects, any associated data record remains intact. hence this data record should hold all "important" data associated with a visitor. The Visitor object can be used to communicate with the individual visitor's phone, either by making explicit calls to functions available on the Visitor object or by changing the value of a record field marked with //@spotParameter()//, which will then be reflected by any Spot Parameter with the same name and type. The value of such a Spot Parameter can be used in a variety of ways on the Spot; e.g. to show information to the visitor, acting as data input, affecting property bindings, etc. 
 + 
 +==== Data Record Storage ==== 
 + 
 +In addition to being available inside your user script, data records are also stored on disk inside the //record// directory located in your Blocks root directory. Inside this record directory, Blocks creates one sub-directory per record type, named by the record type ("ExampleRecord" in the example shown above). Inside such a type-specific subdirectory, you'll find one directory per record instance. This is named with //Pn// where //n// is the $puid identifier mentioned above. 
 + 
 +Inside that record instance directory, you'll find at least a file named "log.tsv". This is a log file of all data stored or updated in the data record, along with a time stamp for each action. This file uses the popular TSV format (a variant of the more well-known CSV format, but using a tabs as separators rather than commas). For each change applied to the data record, a new line is appended to this file, describing what was changed, when the change was made and what the new value is. This data is used by Blocks to resurrect the data in case you must restart the Blocks server while there are active visitors. It can also be used to analyze visitor behavior, by deriving data such as:
  
   * Time of arrival.   * Time of arrival.
Line 146: Line 157:
   * Name, game scores, or any other data you chose to collect along the way.   * Name, game scores, or any other data you chose to collect along the way.
  
-You must not modify this data while the visitor is still on site+You must not remove or change this file while the visitor is still active
  
-=== Data Record Clean-up ===+==== Data Record Clean-up ====
  
-Once a visitor leaves, this data must be discarded to not consume excessive amounts of server memory as new visitors join in. You user script must manage this clean-up of visitor data records, either one by one (as each visitor leaves or any identifying token is recycled) or en masse once closed for the day (e.g., at 3:00am every day).+Once a visitor leaves, this data must be discarded to not consume excessive amounts of server memory as new visitors join in. Your user script must manage this clean-up of visitor data records, either one by one (as each visitor leaves or any identifying token is recycled) or en masse once closed for the day (e.g., at 3:00am every day).
  
-This data record clean-up can either simply delete the record(s) or archive them. Use the archive method if you intend to use the data for further analysis of visitor's behaviors. If this is not desired, the data can be completely erased. This latter method also helps alleviate any privacy-related concerns, since no data is being retained. Archived data sets are moved into a subdirectory named "archive" found inside the data set's directory+This data record clean-up can either simply delete the record(s) or archive them. Use the archive method if you intend to use the data for further analysis of visitor's behaviors. If this is not desired, the data can be completely erased. This latter method also helps alleviate any privacy-related concerns, since no data is being retained past the visit. Archived data sets are moved into a subdirectory named "archive" found inside the data set's directory.
- +
-To remove individual records, call the $delete function on the record itself. Pass //true// to the +
-$delete function to archive the record rather than deleting it. To remove all records of a particular type, call the deleteRecords function on the user script itself, passing it the record type and a second optional boolean parameter set to true to archive the records (if desired). See the declarations of these functions in the ScriptBase.ts and Script.ts system_lib files for details.+
  
 +To remove individual records, call the **deleteRecord** function on the user script, passing it the record to discard. Pass //true// as the second parameter to archive the record rather than deleting it. To remove //all// records of a particular type, call the **deleteRecords** function on the user script, passing it the record type and a second optional boolean parameter set to true to archive the records (if desired). See the declarations of these functions in the Script.ts file in system_lib for details.
  
 ==== Other User Script Functions ==== ==== Other User Script Functions ====
Line 165: Line 174:
   * A mechanism to clean up data records, as described above. This can be done one by one as visitors leave or tokens are recycled, or en masse once every night. Such a nightly clean-up can be exposed as a public function marked with @callable(), which is then called by a task scheduled to run once every night.   * A mechanism to clean up data records, as described above. This can be done one by one as visitors leave or tokens are recycled, or en masse once every night. Such a nightly clean-up can be exposed as a public function marked with @callable(), which is then called by a task scheduled to run once every night.
  
-In addition to these mandatory functions, you most likely will have additional functions performing your desired logic as visitors arrive at certain spots, interact with objects, enter data on their mobile phones, etc. The details here depend entirely on your own requirements. An application note will be provided, describing some common scenarios. +In addition to these mandatory functions, you most likely will have additional functions performing your desired logic as visitors arrive at spots, interact with objects, enter data on their mobile phones, etc. The details here depend entirely on your own requirements. 
- +
- +
- +
- +
  
  
 +===== Where to go from Here =====
  
 +Here are a few [[blocks:app-note#personal_visitor_experience|application notes]] you can download and run to see how this works in practice. You can learn from these application notes, and perhaps use one of them as a starting point for building your own Personal Visitor Experience.