Contact timeline shows raw {contactfield=…} tokens for tracked-link clicks instead of resolved values
Summary
On a contact's Activity timeline (and in page_hits.url), tracked-link clicks display the literal token template rather than the value the contact actually received. For example a link such as mailto:{contactfield=account_manager_email} (or an http://… link containing a token) appears in the timeline verbatim as mailto:{contactfield=account_manager_email} / http://{contactfield=account_manager_email}.
Steps to reproduce
- Build an email containing a link whose href includes a contact (or primary-company) field token, e.g.
mailto:{contactfield=account_manager_email}. - Send it; have the recipient click the link.
- Open the contact → Activity timeline → the page-hit / clicked-link row shows the raw token string.
Expected
The resolved per-contact value, e.g. [email protected] — the same value the contact's mail client / browser was sent to at click time.
Actual
The literal, un-rendered token string is shown.
Root cause
Tracked links are stored once in page_redirects.url as the un-rendered template (a single row shared across all recipients; per-contact substitution happens only at redirect/click time). When the timeline event is built, app/bundles/PageBundle/EventListener/LeadSubscriber.php emits the stored URL verbatim:
'label' => $hit['urlTitle'] ?? $hit['url'],
'href' => $hit['url'],so the timeline renders the template, never the resolved value. The resolved per-contact value is not persisted anywhere, so the UI has nothing else to show.
Suggested fix
When building the timeline event, resolve $hit['url'] through TokenHelper::findLeadTokens() using the contact's profile fields merged with the primary company via PrimaryCompanyHelper::getProfileFieldsWithPrimaryCompany() — exactly as core already does at email-send time (TokenHelper::getTokenValue() already falls back to the primary company's fields). This would make the timeline display the value the contact actually received.
Version
Mautic 7.1.1
Care about this issue? Want to get it resolved sooner? If you are a member of Mautic, you can add some funds to the Bounties Project so that the person who completes this task can claim those funds once it is merged by a member of the core team! Read the docs here.
Source: mautic/mautic