Deep Linking

Follow this guide set up a deelink to an advisor portal page. The deeplink will contain three parts:

  1. The link
  2. The login for an agent
  3. The UID for the recipient being looked up(optional)

Use this URL:

https://<Server_name>/advisor/faces/public/exo/<Advisor_page>
Parameter Description Example
Server_Name Your Agillic instance candy-prod.agillic.eu
Advisor_page Menu Item URI of the Advisor page to show ‘Result’ or ‘Search’

The token parameter for the agent is required to log into the Advisor portal and the pid parameter is optional for instantly looking up a user. If the pid parameter is not added, it is recommend to link to a ‘search’ site where recipients can be looked up.

Functions

MD5 is the MD5 Hashing Algorithm.

URISAFE_BASE64 is a variant of base64 encoding, which replaces certain base64 characters so that they can be transported in urls, url parameters, and cookies without being escaped.

Character Replacement
+
/ _
= !

Parameters

For each parameter a token must be created.

Parameter Description Format Example
Agent_username The Username for the Agent logging in String AdamE
UID Recipient ID, set in Agillic Administration under ‘Person Data’ String user@sweetmail.com
Timestamp Describes when the link expires Unix number 1505812061
Secretsalt Used to authorise the deeplink. Can be found in Agillic Administration under ‘Web’ String QXPKpm8fu0Q8GDF1S6YKzFSSzHcZgf

Examples

Deep Linking to a “Known Visitor” Page

In this example we have a “Profile Management” page configured in Agillic as a “Known Visitor” Page. We wish to “deep link” to that from a third party CRM system – that is, create a link that contains authentication and enables the end user to skip the login page.

This is what the final link will look like.

https://web.cafeconnect.net/web/namedservice/profilemanagement?lgn_uid=LkVickI6MTcxOTMyMzY2MVpruOWZdjzfTEiiUDqxBdY!

Let’s break down the example link into its various components:

Link domain nameRequired syntaxPage URIlgn_uid
https://web.cafeconnect.net/web/namedservice/profilemanagementLkVickI6MTcxOTMyMzY2MVpruOWZdjzfTEiiUDqxBdY

How is an ‘lgn_uid’ constructed?

Warning:
All of these actions must be performed securely in a backend environment. They contain highly sensitive operations.

Let’s break down the example link ‘lgn_uid’ into its various components:

Part 1Part 2Final
AGILLIC_ID + “:” + Unix Timestamp (Expiry)MD5 of AGILLIC_ID + ":" + Unix Timestamp (Expiry) + SaltBase64url encode Part 1 + Part 2
Example Output.xVtC:1687873910�<�;]w�؋�G�K�@�LnhWdEM3MUY4Nzg3MzkxMOl-k3tg1InLkWHgbNfi3VA

Note:
Output of Part 2 will not be human readable

Part 1

We have two core components. They are concatenated, inserting a “:” (colon) in-between the agillicId and expiry

const agillicId = '.xVtC'
const expiry = '1735689600'
const b1 = Buffer.from(agillicId + ":" + expiry);

Part 2 (MD5 Hash)

We have three core components:

const agillicId = '.xVtC'
const expiry = '1735689600'
const salt = 'EvzcyfUyNHNX2Q8VotyTwkhwYtoIK4'

In this example we will be using the Nodejs ‘crypto’ library:

import * as crypto from "node:crypto"
const agillicId = '.xVtC'
const expiry = '1735689600'
const salt = 'EvzcyfUyNHNX2Q8VotyTwkhwYtoIK4'

The three variables are concatenated before hashing. They are concatenated, inserting a “:” (colon) in-between the agillicId and (expiry + salt)

const agillicIdTimestampSecretSalt = agillicId + ":" + expiry + salt

Gotcha
The ‘digest’ must be of the type ‘binary’.
Many tools will try to output it in a human readable format, but this is not what we want here.

import * as crypto from "node:crypto";
const agillicId = '.xVtC';
const expiry = '1735689600';
const salt = 'EvzcyfUyNHNX2Q8VotyTwkhwYtoIK4';

const agillicIdTimestampSecretSalt = agillicId + ":" + expiry + salt;

const md5Binary = crypto
  .createHash("md5")
  .update(agillicIdTimestampSecretSalt)
  .digest("binary");
  
const b1 = Buffer.from(agillicId + ":" + expiry);
const b2 = Buffer.from(md5Binary, "binary");

Combining them all

In order to produce the final ‘lgn_uid’ value, we concatenate the components and ‘base64url’ encode them.

const lgnUid = Buffer.concat([b1, b2]).toString("base64url");

Putting it all together:

import * as crypto from "node:crypto";
const agillicId = ".xVtC";
const timestamp = "1735689600";
const salt = "EvzcyfUyNHNX2Q8VotyTwkhwYtoIK4";
const agillicIdTimestampSecretSalt = agillicId + ":" + timestamp + salt;

const md5Binary = crypto
  .createHash("md5")
  .update(agillicIdTimestampSecretSalt)
  .digest("binary");

const b1 = Buffer.from(agillicId + ":" + timestamp);
const b2 = Buffer.from(md5Binary, "binary");
const lgnUid = Buffer.concat([b1, b2]).toString("base64url");

console.log(lgnUid);

Deep Linking to a “Known Advisor” Page

import * as crypto from "node:crypto";

const agentId = "agentProfile";
const uid = ".xVtC";
const timestamp = "1735689600";
const salt = "EvzcyfUyNHNX2Q8VotyTwkhwYtoIK4";

const uidTimeStampSalt = uid + ":" + timestamp + salt;
const agentTimestampSalt = agentId + ":" + timestamp + salt;

const uidMd5Binary = crypto
  .createHash("md5")
  .update(uidTimeStampSalt)
  .digest("binary");

const agentMd5Binary = crypto
  .createHash("md5")
  .update(agentTimestampSalt)
  .digest("binary");

let a1 = Buffer.from(uid + ":" + timestamp);
let a2 = Buffer.from(uidMd5Binary, "binary");
let lgnUid = Buffer.concat([a1, a2]).toString("base64url");

let b1 = Buffer.from(agentId + ":" + timestamp);
let b2 = Buffer.from(agentMd5Binary, "binary");
let token = Buffer.concat([b1, b2]).toString("base64url");

console.log(lgnUid);
console.log(token);
Link structure
Link domain name https://web.cafeconnect.net
Required syntax /advisor/faces/public/exo
Page URI /profileresultpage
Token ?token=LnhWdEM6MTczNTY4OTYwMAVO9WSfS8vIBhraSWhjUO0
pid &pid=YWdlbnRQcm9maWxlOjE3MzU2ODk2MDCQFdM70Wfc6Zvgh5eIa6S9