Context links are buttons in the conversation sidebar that open external URLs with contact and conversation details filled in. Agents click them to jump to a CRM, a billing system or an internal dashboard without copy-pasting identifiers.
URL template variables
These placeholders are replaced with the current contact's details when an agent clicks the link.
{{email}}- contact's email{{phone}}- contact's phone number{{phone_country_code}}- contact's phone country code{{external_user_id}}- contact's external user ID{{contact_id}}- contact's internal Libredesk ID{{first_name}}- contact's first name{{last_name}}- contact's last name{{conversation_uuid}}- UUID of the current conversation{{token}}- encrypted token containing all fields, needs a shared secret
All values except {{contact_id}} and {{conversation_uuid}} are URL-encoded automatically.
Examples
Simple lookup by email:
https://crm.example.com/contacts?email={{email}}
Multiple parameters:
https://billing.example.com/customer?ext_id={{external_user_id}}&email={{email}}
Internal dashboard with conversation context:
https://dashboard.internal/lookup?contact={{contact_id}}&conv={{conversation_uuid}}
Encrypted token:
https://api.example.com/auth/libredesk?token={{token}}
The encrypted token
When you use {{token}}, Libredesk generates an AES-256-GCM encrypted, time-limited token containing all the fields above plus agent_id, agent_email, iat and exp. The receiving system decrypts it with the shared secret, so nothing is exposed in the URL.
import base64, json, time
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def decrypt_context_token(token, secret):
raw = base64.b64decode(token)
nonce = raw[:12]
ciphertext = raw[12:]
aesgcm = AESGCM(secret.encode('utf-8'))
plaintext = aesgcm.decrypt(nonce, ciphertext, None)
return json.loads(plaintext)
secret = "your-32-character-shared-secret!" # exactly 32 characters
payload = decrypt_context_token(token_from_url, secret)
if payload["exp"] < time.time():
raise ValueError("Token has expired")
print(payload["email"], payload["conversation_uuid"])