Contact card — template vars
For Admins

Contact card — template vars

The contact card on a ticket can show data from your API. Contact data is filled into the requests to it.

It's set up in “Settings → Operator tools → Contact Card” (owner and admins). Data sources hold the requests to your API: URL, HTTP method, headers and body (JSON, form, raw text or none). Card blocks decide what the operator sees: Data display, List, Action button or a VPN card. Each source is requested once when the card opens, with a 10-second timeout.

Contact variables

They are filled into the URL, headers and body of source and action-button requests:

VariableValue
{contact_id}The contact's ID in SupportHub (UUID)
{internal_id}The widget visitor ID; anonymous visitors get a vs_… one
{user_id}same as {internal_id}
{external_id}the contact's external ID, e.g. from your CRM (set through the contacts API)
{telegram_id}Telegram ID
{vk_id}VK ID
{whatsapp_id}WhatsApp ID (like 15551234567@s.whatsapp.net)
{phone}the number from the WhatsApp ID, without @s.whatsapp.net
{email}the contact's email
  • Action buttons also get {input.<id>} — the values of input fields the operator fills in — and item actions in a list get {item.<field>}, the fields of the chosen item.
  • The ID from a signed visitor token isn't available as a variable. For those customers, rely on {telegram_id}, {email} or {external_id}.

Syntax

SyntaxWhat it does
{field}the field's value; an empty string if it has none
{a|b|c}the first non-empty value of those listed
{?field}…{/?}the block stays only if the field isn't empty
{?!field}…{/?}the block stays only if the field is empty
{?a|b}…{/?}the block stays if at least one of the fields isn't empty

Conditional blocks can be nested. With a JSON body, the body must still be valid JSON after substitution, or the request isn't made.

Example 1 — conditional JSON with multiple identifiers

The request sends whichever identifier the contact has. The conditional blocks make sure only one field ends up in the JSON.

{
  "method": "user.get",
  "params": {
    {?external_id}"user_id": "{external_id}"{/?}{?!external_id}{?telegram_id}"telegram_id": {telegram_id}{/?}{?!telegram_id}{?vk_id}"vk_id": {vk_id}{/?}{?!vk_id}{?email}"email": "{email}"{/?}{/?}{/?}{/?}
  }
}
Check order: external_id → telegram_id → vk_id → email. Once the first non-empty value is found, the other blocks are skipped.

Example 2 — the first non-empty identifier

The {a|b|c} form fills in the first non-empty value. Handy when the API accepts any identifier in a single field.

{
  "query": "{telegram_id|vk_id|email|internal_id}",
  "source": "supporthub"
}
If none of the fields is filled in, an empty string goes in and the request is still made. Answer such a request with an error (a 404, for example) and set up Error handling on the source by HTTP code or a JSON field — the operator then sees a clear message instead of an empty card.

Link buttons

A link button's URL template takes values from your API's response: {field.path} is the dotted path to a field. The :b64 modifier encodes the value as URL-safe base64 without padding — for a Telegram deep link, for example. If any value is missing from the response, the button isn't shown.

Streamer mode

There's no knowing in advance which fields of your card are personal data, so every data block (Data display, List, VPN card) has a Streamer mode section. It decides what gets blurred for an operator who turned on streamer mode:

  • Hide the whole block blurs every value of the block, whatever it holds. Field labels stay readable.
  • Each field gets Auto, Hide or Show. Auto hides a field whose key or name looks like personal data: email, phone, Telegram, VK, WhatsApp, IDs, balance, IP, address, card, wallet, token, password, passport, tax and insurance numbers, name, date of birth, links. What Auto picks shows right in the list: “Auto: hidden” or “Auto: visible”.
  • The choice is tied to the field's path (user.email), not its label: renaming the label keeps it, and changing the path takes the choice along. In a list the path is inside an item, so name in the configs list is a config's name, not a person's.
  • A block with no field list shows the whole API response: its keys follow the Auto rules, and a key you want to decide for yourself is added by hand.
  • The VPN card lists its own fields: name, Telegram, ID, email, balance, payment and withdrawal amounts, withdrawal details, subscriptions, statistics and more.
In streamer mode, link buttons don't show their URL on hover — it often carries the client's ID (…?start=get_u_{user.id}). A click opens the link as usual.
Was this page helpful?