Wiki

You can use iOS and Android SDK to use Personyze on mobile devices. But under certain circumstances you may want to implement a Personyze tracker by yourself. This may be needed if you use a platform different from Android and iOS, or if you want to use a programming language or a framework that Personyze doesn't support.

Implementing full-featured tracker, like we did in our SDKs is not trivial, but if you want to use limited features subset, it can be relatively easy. Here we will show you how to implement an application that will use only recommendations feature of the Personyze system.

You will need to create a "Product recommendations in JSON format" action, or "Content recommendations in JSON format" in the Personyze panel, and your application will receive the JSON array with information about what products or articles are recommended to current user.

This application will query Personyze server through REST API.

  • First, you need to obtain the API key for your account here - use the key from the "Full-featured API" section.
  • In your application you will need to detect some system settings, like system language, etc.
  • You will need to make a HTTP request to Personyze server, passing required information in JSON format.
  • In response you will receive the "Session ID" token. Your application will need to store it in permanent storage. Always store the "Session ID" from each response from Personyze, and send the last stored value back with each request.
  • Personyze recommends products and articles to users depending on their activity. Your application will need to send to Personyze interaction events. When you presented some product to the app user, you need to tell about this to Personyze through API call. The same if your user added a product to cart and purchased a product. For content recommendations events are like "article viewed", "article liked", etc.
  • The response from Personyze server will contain list of recommended products in JSON format.

All these operations are done through one REST API call like this:

curl --header 'User-Agent: Superagent/1.0' --header 'Content-Type: application/json' --data '{"user_id": 123456, "commands": [["Product viewed", "Chair"], ["Navigate", "urn:personyze:doc:Default"]]}' 'https://api:17A9187F88BDBEA9957EBDD4F56B5C2B54354952@app.personyze.com/rest/tracker-v1'
  • The endpoint URL is https://app.personyze.com/rest/tracker-v1
  • There is "Basic" HTTP authentication. Username must be always "api". The password is your API key (in my example 17A9187F88BDBEA9957EBDD4F56B5C2B54354952).
  • Content-Type must be application/json
  • You can use any User-Agent header. It will appear in Personyze dashboard
  • The JSON payload must contain:
    1. "user_id" - Any signed or unsigned 32-bit integer, which is constant for each user. Can be device ID (on single-user devices), vendor ID, etc.
    2. "languages" - comma-separated list of 2-letter language codes, like "en, es". Only first 3 will be respected. The first in list is the main system language.
    3. "time_zone' - time zone offset in hours relative to GMT. For example New York is GMT-4, so "time_zone" must be -4.
    4. "screen" - device screen resolution like "1920x1080"
    5. "os" - Operating system name and version, like "Ubuntu/18.04".
    6. "platform" - like "x86_64"
    7. "device_type" - one of "regular", "tablet", "phone".
    8. "session_id" - in first request ever on this device send null (or omit this field). On next requests include the "session_id" from the most recent response.
    9. "commands" - array of commands to perform on Personyze end, like [["Product Viewed", "Product 1"], ["Product Added to cart", "Product 2"]]. Our application will support the following commands:
      • ["User Profile", "first_name", "John", "industry": "e-commerce"] - set user's profile data (in this case set two fields "first_name" and "industry" - you can create user fields in the account)
      • ["Product Viewed", "Internal ID"] - product viewed
      • ["Product Added to cart", "Internal ID"] - product added to cart
      • ["Product Liked", "Internal ID"] - product liked (added to wish list)
      • ["Product Purchased", "Internal ID"] - product purchased
      • ["Product Removed from cart", "Internal ID"] - product removed from cart
      • ["Product Unliked", "Internal ID"] - product unliked (removed from wish list)
      • ["Products Purchased"] - all products in cart purchased
      • ["Products Unliked"] - wish list cleared
      • ["Article Viewed", "Internal ID"] - article viewed
      • ["Article Liked", "Internal ID"] - article liked
      • ["Article Commented", "Internal ID"] - article commented
      • ["Article Unliked", "Internal ID"] - article unliked
      • ["Article Goal", "Internal ID"] - article reached it's goal, as understood by your application (e.g. lead to purchase)
      • ["Articles Unliked"] - mark all previously liked articles as not liked
      • If you presented the recommended products to the user, and he viewed one, you need to log this, so you will see action usefulness in Personyze dashboard. ["Product Viewed", "Internal ID", "action_id", 10] - means product "Internal ID" is viewed through action 10.
      • ["Navigate", "urn:personyze:doc:DocumentName"] - logs navigation to a new "page". We need to send this command with each request where we want to receive back recommendations (and other actions). This is because Personyze doesn't execute the same action several times on single page. DocumentName can be any URL-encoded text. It will appear in the dashboard.

Example application in PHP

<?php

// Usage:
// php personyze-recom.php --viewed="Product 1" --viewed="Product 2" # log products view ("Product 1" and "Product 2" are product Internal IDs)
// php personyze-recom.php --viewed="Product 1" --viewed="Product 2" --action=10 # products viewed from action ID 10 (will show contribution rate in dashboard)
// php personyze-recom.php --cart="Product 1" # log product added to cart
// php personyze-recom.php --liked="Product 1" # log product liked (added to wish list)
// php personyze-recom.php --purchased="Product 1" # log product purchased
// php personyze-recom.php --removed="Product 1" # log product removed from cart
// php personyze-recom.php --unliked="Product 1" # log product unliked (removed from wish list)
// php personyze-recom.php --purchased-all # log all products in cart purchased
// php personyze-recom.php --unliked-all # log wish list cleared

// Put your Personyze API key here. You can obtain it from https://personyze.com/panel/#cat=Account%20settings%2FMain%20settings%2FIntegrations
// from the "Full-featured API" section.
define('PERSONYZE_KEY', '17A9187F88BDBEA9957EBDD4F56B5C2B54354952');

// This User-Agent will appear in Personyze dashboard in Live Visits - https://personyze.com/panel/#cat=Dashboard%2FReal%20time%20visitors
define('USER_AGENT', 'Superagent/1.0');

// Proceed
main();
exit;

function main()
{   try
    {   // We need to use permanent storage for session information.
        // Always store the "session_id" field from each response from Personyze, and send the last stored value with each request.
        // In this example we will store it in a file.
        $file = sys_get_temp_dir()."/personyze_session.dat";

        // Build the request
        $request = get_system_constants();
        $request['session_id'] = is_file($file) ? file_get_contents($file) : null;
        $request['commands'] = get_commands();

        // Send the request and get the response
        $response = tracker_v1($request);

        // Store the "session_id"
        file_put_contents($file, $response['session_id']);

        // Find out what actions matched
        foreach ($response['actions'] as $action)
        {   // There can be various types of actions. Some of them can contain HTML to be presented.
            // We are only interested in actions that have product recommendations in JSON format.
            // To create such actions, go to Personyze panel, create new Campaign of "Targeting and Personalization" type, and add action of type "Product recommendations in JSON format".
            // Such actions will have $action['data']['data'] set to the JSON string.
            if (isset($action['data']['data']))
            {   $action_id = $action['id'];
                // Actually the resulting JSON string will not have surrounding square brackets.
                // "data" field of each resulting action only contains varying part of the action's content.
                // We can request the constant wrapping part with another REST API call.
                // But for the "Product recommendations in JSON format" actions the wrapping part will always be square brackets, so we can just add them by ourselves.
                $action_data = '['.$action['data']['data'].']';
                // It's JSON
                $action_data = json_decode($action_data, true);
                if ($action_data !== null) // json_decode will return null if that was not a JSON
                {   // Action $action_id matched.
                    // Here we just print it.
                    echo "Action $action_id: ", json_encode($action_data), "\n";
                }
            }
        }
    }
    catch (Exception $e)
    {   exit($e->getMessage()."\n");
    }
}

/** The user of this script must supply the commands through command-line options.
    **/
function get_commands()
{   $options = getopt("", ['viewed:', 'cart:', 'liked:', 'purchased:', 'removed:', 'unliked:', 'purchased-all', 'unliked-all', 'action:']);
    $names =
    [   'viewed' => 'Product Viewed',
        'cart' => 'Product Added to cart',
        'liked' => 'Product Liked',
        'purchased' => 'Product Purchased',
        'removed' => 'Product Removed from cart',
        'unliked' => 'Product Unliked',
        'purchased-all' => 'Products Purchased',
        'unliked-all' => 'Products Unliked',
    ];

    $action_id = intval($options['action'] ?? 0);

    $commands = [];

    foreach ($options as $option => $item_ids)
    {   $command_name = $names[$option] ?? null;
        if ($command_name)
        {   foreach ((is_array($item_ids) ? $item_ids : [$item_ids]) as $item_id)
            {   $command = $item_id===false ? [$command_name] : [$command_name, $item_id];
                if ($action_id > 0)
                {   $command[] = 'action_id';
                    $command[] = $action_id;
                }
                $commands[] = $command;
                if ($item_id === false)
                {   break;
                }
            }
        }
    }
    if (!$commands)
    {   throw new Exception("One of the following is required: --viewed=PRODUCT_ID or --cart=PRODUCT_ID or --liked=PRODUCT_ID or --purchased=PRODUCT_ID or --removed=PRODUCT_ID or --unliked=PRODUCT_ID or --purchased-all or --unliked-all");
    }
    $commands[] = ['Navigate', 'urn:personyze:doc:Default'];

    return $commands;
}

/** You need to scan the current device for it's properties, like device ID, system languages, screen resolution, etc.
    These information will be presented in Personyze dashboard in Live Visits - https://personyze.com/panel/#cat=Dashboard%2FReal%20time%20visitors
    and it can be used in Campaign rules to trigger specific actions to specific users.
    Here is the code that will detect system properties on Linux systems.
    If you want to run this script on different environment, you'll need to correct this function.
**/
function get_system_constants()
{   // Any signed or unsigned 32-bit integer, which is constant for each user. Can be device ID (on single-user devices), vendor ID, etc.
    $user_id = crc32(is_file('/etc/machine-id') ? file_get_contents('/etc/machine-id') : '-');

    // e.g. en, es
    $languages = substr(getenv('LANG'), 0, 2);

    // e.g. -4 (means GMT-4)
    $time_zone = date('Z')/3600;

    // e.g. 1920x1080
    preg_match('~\n\s*dimensions:\s*([0-9x]+)~', `xdpyinfo`, $screen);
    $screen = $screen[1];

    // e.g. Android/9
    $os = php_uname('s');

    // e.g. Linux x86_64
    $platform = PHP_OS.' '.php_uname('m');

    // One of: regular, phone, tablet
    $device_type = 'regular';

    return
    [   'user_id' => $user_id,
        'languages' => $languages,
        'time_zone' => $time_zone,
        'screen' => $screen,
        'os' => $os,
        'platform' => $platform,
        'device_type' => $device_type,
    ];
}

/** Make the REST API call.
    **/
function tracker_v1($post_data)
{   $hurl = curl_init("https://app.personyze.com/rest/tracker-v1");
    curl_setopt($hurl, CURLOPT_POST, true);
    curl_setopt($hurl, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($hurl, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Authorization: Basic '.base64_encode("api:".PERSONYZE_KEY)]);
    curl_setopt($hurl, CURLOPT_USERAGENT, USER_AGENT);
    curl_setopt($hurl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($hurl, CURLOPT_ENCODING, '');
    $response_str = curl_exec($hurl);
    if ($response_str === false)
    {   $err_msg = curl_error($hurl);
        curl_close($hurl);
        throw new Exception($err_msg);
    }
    $status = curl_getinfo($hurl, CURLINFO_RESPONSE_CODE);
    curl_close($hurl);
    if ($status == 500)
    {   throw new Exception($response_str);
    }
    if ($status != 200)
    {   throw new Exception("HTTP Status $status");
    }
    return json_decode($response_str, true);
}
©2008-2023 All rights reserved. Personyze® is a registered trademark. Privacy Policy. Terms of Use.