Client-side event tracking

Castle lets you track page views on web and screen views on mobile to get better visibility into where the user spends their time between server-side events.

This chapter assumes that you have completed the Baseline Integration, including adding Castle.js or the mobile SDKs to track client-side activity.


Step 1. Identifying the logged in user

On any page where the user is logged in, call identify with the User ID of the currently logged in user as the first argument. This method sets the identifier in memory and does not trigger any outbound request. Castle’s tracking pixels are automatically sent on each page load and they will include the set User ID.

Alternative A. Using a templating language

If you are using a templating language where the User ID can be set from the server-side before the page is served up, then you should set the User ID in the <head> tag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<head>
  <!-- Replace the digits at the end of the URL with your Castle App ID -->
  <script src="https://d2t77mnxyo7adj.cloudfront.net/v1/c.js?123456789012345"></script>

  <!-- Use your favorite templating language to inject the User ID -->
  <script>
    <%% if user_logged_in? %>
      _castle('identify', '<%%= current_user.id %>'); // Set the current user's id
    <%% end %>
  </script>

  ...
</head>

Alternative B. Not using a templating language

If you are not using a templating language or are unable to set the User ID inside the <head> tag, for example if you have single-page application, then you should disable Castle from automatically sending tracking pixels by setting autoTrack to false.

Once you have authenticated via an asynchronous API call, you’ll call identify followed by trackPageview make sure the User ID is tracked to Castle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<head>
  <!-- Replace the digits at the end of the URL with your Castle App ID -->
  <script src="https://d2t77mnxyo7adj.cloudfront.net/v1/c.js?123456789012345"></script>
  <script>
    _castle('autoTrack', false); // Disable Castle from auto-sending tracking pixels on page load
  </script>

  ...
</head>
<body>
  ...

  <!-- Once you are able to identify the user -->
  <script>
    _castle('identify', '{current_user_id}'); // Set the current user's id
    _castle('trackPageview'); // Manually send a Castle tracking pixel
  </script>

  ...
</body>

trackPageview appends the current URL and page title as metadata on the event. If you prefer to manually set the URL and title, you can pass them as parameters:

1
_castle('trackPageview', 'https://example.com', 'Any title you want');

Pageviews

Since we’ve now turned off autoTrack, you will need to explicitly call trackPageview in order to track a page view every time the URL changes. It’s recommended that you only track this for full view transitions, and for example not in-page updates to the URL hash.

Logging out

In a similar way to how you logged in the user, you’ll also need to reset the state on logout. Finish it up by tracking a page view to ensure the reset call reaches the Castle API.

1
2
	_castle('reset');
	_castle('trackPageview');

Step 2. Signing the requests

In order to prevent attackers from spoofing user activity, you’ll need to ensure that each page or screen view originates from the currently logged in user by signing each request.

To sign requests, you’ll need to generate a user signature on your server-side and pass it to the JavaScript snippet:

1
	_castle('secure', 'YOUR_GENERATED_SIGNATURE');

The signature is a SHA-256 HMAC in hex format. The HMAC shared secret is your API Secret, and the value is the User ID sent to identify.

Identifying the user after page load

Keep in mind that if the User ID is set after page load, you will also need to disable autoTrack in order to prevent the tracking pixel from firing prematurely:

1
2
3
4
	_castle('autoTrack', false);
	_castle('identify', {{user_id}});
	_castle('secure', {{secure_signature}});
	_castle('trackPageview');

Example

1
2
3
4
5
	<script type="text/javascript">
		_castle('identify', '<%%= user_id %>');
	  _castle('secure',
	    '<%%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_API_SECRET", "1234") %>');
	</script>
1
2
3
4
5
	<script type="text/javascript">
		_castle('identify', '<?= user_id ?>');
	  _castle('secure',
	    '<?= hash_hmac("sha256", "1234", "YOUR_API_SECRET"); ?>');
	</script>
1
2
3
4
5
	<script type="text/javascript">
		_castle('identify', '<%%= user_id %>');
	  _castle('secure',
	    '<%%= Castle.instance().secureUserID("1234") %>');
	</script>
1
2
3
4
5
	<script type="text/javascript">
		_castle('identify', 'user_id');
	  _castle('secure',
	    '@Castle.Signature.Compute("YOUR_API_SECRET", "1234")');
	</script>

Step 3. Enabling secure mode in the dashboard

Once the secure signatures are included in your requests, you need to enable Secure Mode in the Castle dashboard. This informs Castle that only requests including the secure signature should be trusted, and all other client-side events will be dropped.

Mobile
If you are using Castle’s mobile SDKs, be sure to configure secure signatures for them as well or their client-side screen views will be dropped.

To enable secure mode, visit the Castle Dashboard and select the environment in the top right for which you want to enable Secure Mode. Then go to Settings > General and toggle on Secure Mode.


Mobile

Identify logged in users

The identify call lets you tie a user to their action and should be called right after the user logged in successfully. The user_id will be persisted locally so subsequent activity will automatically be tied to that user.

1
Castle.identify("e325bcdd10ac")
1
[Castle identify:@"e325bcdd10ac"];
1
Castle.identify("e325bcdd10ac");

If secure mode is enabled make sure to call secure before identify or any other tracking calls (track, screen) since any events not containing the user_signature will be discarded.


Tracking screen views

Screen

The screen call lets you record whenever a user sees a screen. It could look something like this:

1
2
3
4
5
6
7
	// Track a screen view
	Castle.screen("Menu")

	// OR

	// Track screen view and include some properties
	Castle.screen("Menu", properties: ["locale": "en_US"])
1
2
3
4
5
6
7
	// Track a screen view
	[Castle screen:@"Menu"];

	// OR

	// Track a screen view and include some properties
	[Castle screen:@"Menu" properties:@{ @"locale": @"en_US" }];
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
	// Track a screen view
	Castle.screen("Menu");

	// OR

	// Track a screen view and include some properties
	Map<String, String> properties = new HashMap<String, String>() {{
		put("locale", "en_US");
	}};
	Castle.track("Menu", properties);

Securing requests from Mobile SDKs

Secure Mode is available in Castle iOS SDK v1.0.0+ and Android SDK v1.1.0+

Securing requests is optional, but recommended. We strongly encourage all Castle customers to enable Secure Mode to prevent fraudsters from impersonating your users. This is important to make sure fraudsters can’t lock out your users by feeding in bad behavior. Read more about Secure mode in the “Secure Requests” section of the documentation.

Since the secure mode signature is generated on your backend you will need to pass it to your application. A straight forward way of doing that is by including the signature in the authentication response. After receiving the authentication response the application can set the signature by calling the secure method.

The secure mode signature is a SHA-256 HMAC in hex format where the shared secret is your API Secret, and the value is the User ID being tracked in identify.

See the example below on how the signature can be generated on your backend.

1
2
		OpenSSL::HMAC.hexdigest("sha256", "YOUR_API_SECRET", "1234");
	
1
2
		hash_hmac("sha256", "1234", "YOUR_API_SECRET");
	
1
2
3
		// Use the secureUserID method in our Java SDK to generate the signature
		castle.secureUserID("1234");
	
You will need to set the secure mode signature before calling identify, otherwise the identify event will be rejected by the API since it won’t include the secure mode signature.

If Secure Mode is enabled on your Castle environment, you will need to pass the user signature to the mobile SDK using the secure method:

1
Castle.secure("944d7d6c5187cafac297785bbf6de0136a2e10f31788e92b2822f5cfd407fa52")
1
[Castle secure:@"944d7d6c5187cafac297785bbf6de0136a2e10f31788e92b2822f5cfd407fa52"];
1
Castle.secure("944d7d6c5187cafac297785bbf6de0136a2e10f31788e92b2822f5cfd407fa52");

Once enabled the user signature will be included in every event. The user_signature will be persisted locally. Calling reset will remove the stored user signature and calling secure again will replace the old user signature. Once secure mode is enabled any events not containing the user_signature field will be discarded.