feat: Add id as reserved field in templates, campaigns and workflows

This commit is contained in:
Dries Augustyns
2026-01-07 17:49:36 +01:00
parent 718251c67c
commit 7386441e61
7 changed files with 15 additions and 2 deletions
+1
View File
@@ -275,6 +275,7 @@ export class Actions {
// These are always available for template rendering
const dataWithSystemVars = {
...mergedData,
id: contact.id,
email: contact.email,
data: mergedData, // Also available as nested data for {{data.fieldName}} syntax
unsubscribeUrl: `${DASHBOARD_URI}/unsubscribe/${contact.id}`,
+1
View File
@@ -451,6 +451,7 @@ export class CampaignService {
const contactData =
contact.data && typeof contact.data === 'object' && !Array.isArray(contact.data) ? contact.data : {};
const variables = {
id: contact.id,
email: contact.email,
...contactData,
data: contactData,
+9 -1
View File
@@ -221,7 +221,15 @@ export class ContactService {
for (const [key, value] of Object.entries(data)) {
// Skip reserved system-generated fields
// These fields are dynamically added during template rendering and cannot be overridden
const reservedFields = ['plunk_id', 'plunk_email', 'email', 'unsubscribeUrl', 'subscribeUrl', 'manageUrl'];
const reservedFields = [
'plunk_id',
'plunk_email',
'id',
'email',
'unsubscribeUrl',
'subscribeUrl',
'manageUrl',
];
if (reservedFields.includes(key)) {
continue;
}
+1
View File
@@ -333,6 +333,7 @@ export class EmailService {
subject: email.subject,
body: email.body,
data: {
id: email.contact.id,
email: email.contact.email,
...contactData,
data: contactData,
@@ -545,6 +545,7 @@ export class WorkflowExecutionService {
: {};
const variables = {
id: contact.id,
email: contact.email,
...contactData,
...executionContext,
@@ -44,6 +44,7 @@ interface EmailEditorProps {
}
const commonVariables = [
{name: 'id', description: 'Contact ID'},
{name: 'email', description: 'Recipient email address'},
{name: 'unsubscribeUrl', description: 'Unsubscribe link'},
{name: 'subscribeUrl', description: 'Subscribe link'},
@@ -117,7 +117,7 @@ export const VariableMention = Mention.configure({
items: ({query}) => {
const safeVariables = Array.isArray(availableVariables) ? availableVariables : [];
const allVariables = ['email', 'unsubscribeUrl', 'subscribeUrl', 'manageUrl', 'locale', ...safeVariables];
const allVariables = ['id', 'email', 'unsubscribeUrl', 'subscribeUrl', 'manageUrl', 'locale', ...safeVariables];
const uniqueVariables = Array.from(new Set(allVariables)).filter(v => typeof v === 'string');
if (!query) {