Context links are links in the conversation sidebar that open one of your own tools, such as a CRM, a billing system or an internal admin page, with the customer's details already in the address. An agent clicks the link instead of copying an email address or an ID by hand.
Add a context link
- Open Admin > Integrations > Context links and click New context link.
- In Name, type the text agents will see in the sidebar, for example
Billing. - In URL template, enter the address of your tool with variables in double curly braces, for example
https://crm.example.com/search?email={{email}}. - Fill in Secret only if the template uses
{{token}}: it must be exactly 32 characters. Use plain letters and digits, since the length is counted in bytes. - Token expiry (seconds) sets how long a token stays valid. The default is 1200, which is 20 minutes.
- Click Create.
Managing context links needs the Manage context links permission in the agent's role, see Roles and permissions.
Where agents find context links
Active context links appear in the conversation sidebar, below the contact details, each as its name with a link icon. The newest link comes first. Every agent who can open a conversation sees all active links in it.
When an agent clicks a link, EPAV Desk fills in the variables with the data of this conversation's contact at that moment, creates a fresh token if the template has one, and opens the result in a new browser tab.
Variables for the URL template
| Variable | Replaced with |
|---|---|
{{email}} |
the contact's email address |
{{phone}} |
the contact's phone number |
{{phone_country_code}} |
the country code saved with the phone number, such as IT |
{{external_user_id}} |
the contact's ID in your own system, known for visitors your website or app signs in to the chat |
{{contact_id}} |
the contact's ID in EPAV Desk |
{{first_name}} |
the contact's first name |
{{last_name}} |
the contact's last name |
{{conversation_uuid}} |
the UUID of the open conversation |
{{token}} |
an encrypted token with all of the above plus the agent's ID and email address |
{{token}} works only when the link has a Secret. Without one, the text {{token}} stays in the address as it is.
How values are encoded
EPAV Desk URL-encodes each value for use in a query string, so an address such as maria+orders@example.com arrives intact. Only {{contact_id}} and {{conversation_uuid}} are inserted as they are: they are a number and a UUID and need no encoding.
When the contact has no value for a variable, for example no phone number, the variable is replaced with an empty string. The token is URL-encoded as well; any standard query string parser gives you back the plain Base64 text.
Examples of URL templates
Find the customer in a CRM by email address:
https://crm.example.com/search?email={{email}}
Open the billing account by your own customer ID, with the email address as a fallback:
https://billing.example.com/accounts?customer={{external_user_id}}&email={{email}}
Open an internal admin page that also records which conversation the agent came from:
https://admin.example.com/support/contact?id={{contact_id}}&conversation={{conversation_uuid}}
Send everything in one encrypted token:
https://app.example.com/support-context?token={{token}}
The encrypted token
With {{token}}, the address carries no readable personal data: the contact's details and the agent's identity travel inside one encrypted value. Your application decrypts it with the same 32-character Secret that you entered in the context link, and can trust the data because only EPAV Desk and your application know that secret.
Plain variables such as {{email}} suit trusted internal tools. Use the token when the address may end up in logs, browser history or a third-party system, or when your application must know which agent opened it.
The token is AES-256-GCM encrypted. It is Base64 text (standard alphabet, with padding) of these bytes: a 12-byte nonce, then the ciphertext, then the 16-byte authentication tag. The key is the 32 characters of the secret taken as bytes, and no additional authenticated data is used.
What the token contains
After decryption the token is a JSON object:
{
"agent_email": "anna@yourcompany.example",
"agent_id": 5,
"contact_id": 87,
"conversation_uuid": "9b2e7d10-3c4a-4f8b-8e21-5a6b7c8d9e0f",
"email": "maria@example.com",
"exp": 1791109200,
"external_user_id": "cus_10452",
"first_name": "Maria",
"iat": 1791108000,
"last_name": "Rossi",
"phone": "5550123",
"phone_country_code": "IT"
}
agent_id and agent_email belong to the agent who clicked the link. iat is when the token was made and exp when it expires, both in Unix seconds; exp is iat plus the Token expiry (seconds) of the link. Your application should refuse a token whose exp has passed.
Decrypt the token in Python
import json
import time
from base64 import b64decode
from cryptography.hazmat.primitives.ciphers.aead import AESGCM # pip install cryptography
def open_context_token(token: str, secret: str) -> dict:
blob = b64decode(token)
nonce, sealed = blob[:12], blob[12:] # sealed: ciphertext followed by the tag
data = json.loads(AESGCM(secret.encode("ascii")).decrypt(nonce, sealed, None))
if data["exp"] < time.time():
raise ValueError("context link token has expired")
return data
Decrypt the token in Node.js
const crypto = require('node:crypto');
function openContextToken(token, secret) {
const blob = Buffer.from(token, 'base64');
const nonce = blob.subarray(0, 12);
const tag = blob.subarray(blob.length - 16);
const encrypted = blob.subarray(12, blob.length - 16);
const decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(secret, 'ascii'), nonce);
decipher.setAuthTag(tag);
const text = Buffer.concat([decipher.update(encrypted), decipher.final()]).toString('utf8');
const data = JSON.parse(text);
if (data.exp < Date.now() / 1000) throw new Error('context link token has expired');
return data;
}
// In Express: const data = openContextToken(req.query.token, process.env.CONTEXT_LINK_SECRET);
Pause, edit or delete a context link
On Admin > Integrations > Context links, the menu at the end of each row has Edit, Disable (Enable for a paused link) and Delete. On the edit page, the Active checkbox pauses or resumes the link; click Save afterwards. A paused link disappears from the sidebar.
The saved Secret is shown masked. Leave it as it is to keep it, or type a new 32-character secret and update your application at the same time. Deleting a context link cannot be undone.