Contact Lists allow you to organize your contacts into segments for targeted email campaigns, reporting, and automation workflows.
List Structure
Lists are lightweight organizational containers (types.ts:260-266):
export interface ContactList {
id : string ;
name : string ;
description : string ;
createdAt : string ;
contactCount ?: number ;
}
Accessing List Management
Open CRM
Navigate to Admin → Gestión de Contactos
Click Listas / Segmentos
Button in the top toolbar opens the lists panel
View All Lists
See all existing lists with contact counts
Create or Edit
Add new lists or modify existing ones
Creating a List
Click New List
Press ”+ Nueva Lista” in the lists panel
Enter Name
Choose a descriptive name (e.g., “Newsletter Subscribers”)
Add Description
Describe the list’s purpose and target audience
Save
The list is created and available immediately
List Naming Conventions
✅ Good Names :
“Newsletter - Bienestar y Meditación”
“Retiro Santiago 2024”
“Miembros Activos”
“Leads - Website Footer”
❌ Poor Names :
“Lista 1”
“Test”
“Contactos”
Common List Types
Newsletter Subscribers All contacts who signed up for email updates
Event Attendees Participants in specific events or retreats
Active Members Current community members with high engagement
Leads New contacts not yet fully onboarded
Inactive Contacts with low engagement scores
VIP High-value contacts (donors, coordinators)
Individual Assignment
Open Contact Panel
Click a contact in the CRM table
View Lists Section
Scroll to “Listas & Segmentos” in the panel
Add to List
Click ”+” button to select lists
Save
Contact is immediately added to selected lists
Bulk Assignment
Add multiple contacts at once (AdminViews.tsx:1050-1064):
Select Contacts
Check boxes for contacts to add
Click Agregar a Lista
Button appears in bulk action toolbar
Choose List
Select destination list from dropdown
Confirm
All selected contacts are added to the list
// Bulk add to list implementation
handleBulkAddToList = () => {
if ( ! bulkListId ) return ;
selectedIds . forEach ( id => {
const contact = contacts . find ( x => x . id === id );
if ( ! contact ) return ;
const listIds = Array . from ( new Set ([ ... ( contact . listIds || []), bulkListId ]));
db . crm . save ({ ... contact , listIds });
});
}
List Management Functions
Programmatic list operations (storage.ts:666-709):
Create List
const newList = db . crm . addList ({
name: "Newsletter - Meditación" ,
description: "Suscriptores interesados en contenido de meditación"
});
// Returns: ContactList with generated id and createdAt
Update List
db . crm . updateList ({
id: "list_abc123" ,
name: "Newsletter - Meditación y Bienestar" ,
description: "Actualizado para incluir bienestar general" ,
createdAt: "2024-01-15" ,
contactCount: 245
});
Delete List
db . crm . deleteList ( "list_abc123" );
// Removes list and removes list ID from all contacts
Deleting a list removes it from all contacts. This action is permanent and cannot be undone.
Filtering by List
Use list filters to view specific segments:
Open CRM Table
View the main contacts table
Select List Filter
Choose a list from the “Todas las listas” dropdown
View Filtered Contacts
Table shows only contacts in that list
Perform Actions
Bulk actions apply only to filtered contacts
Combined Filters
You can combine list filters with:
Status filters (Subscribed, Pending, etc.)
Tag filters
Search queries
List-Based Metrics
View email performance by list (AdminViews.tsx:727-755):
Enable Metrics View
Click “Ver Métricas” in the CRM toolbar
Select List
Choose a list from the metrics dropdown
View Analytics
See open rates, click rates, and engagement for that list
Calculated Metrics
const contactsInList = contacts . filter ( c => c . listIds ?. includes ( listId ));
const logsForList = emailLogs . filter ( l =>
contactsInList . some ( c => c . id === l . contactId )
);
const openRate = logsForList . length > 0
? Math . round (( openedCount / logsForList . length ) * 100 )
: 0 ;
Campaign Targeting
Lists are used to target email campaigns (storage.ts:859-906):
Campaign Recipient Options
Type Description Use Case All Every contact in CRM Rare, system announcements only Subscribed All subscribed contacts General newsletters List Specific contact list Targeted campaigns Tag Contacts with specific tag Interest-based campaigns
Example: Campaign to List
const campaign = {
name: "Newsletter Julio 2024" ,
subject: "Nuevos recursos de meditación" ,
recipientType: "list" ,
listId: "list_newsletter_meditacion" ,
content: "<html>...</html>" ,
status: "Draft"
};
db . campaigns . create ( campaign );
Automation Triggers
Lists can trigger automation workflows (types.ts:383-400):
const automation = {
name: "Welcome Series" ,
trigger: {
type: "contact_added_to_list" ,
listId: "list_new_subscribers"
},
nodes: [
{
type: "send_email" ,
subject: "Bienvenido a Cafh" ,
content: "<p>Gracias por unirte...</p>"
},
{
type: "wait" ,
amount: 3 ,
unit: "days"
},
{
type: "send_email" ,
subject: "Recursos para comenzar" ,
content: "<p>Te compartimos...</p>"
}
]
};
Use list-based automation to create onboarding sequences, nurture campaigns, and re-engagement workflows.
When to Use Lists
Campaigns : Targeting specific email campaigns
Automation : Triggering workflows
Reporting : Analyzing segment performance
Organization : Grouping by acquisition source
Interests : User interests (“meditación”, “retiros”)
Behavior : Actions taken (“downloaded-guide”, “attended-event”)
Attributes : Characteristics (“beginner”, “advanced”)
Flexible Filtering : Ad-hoc segmentation
A contact can be in multiple lists and have multiple tags. Use both for powerful segmentation.
Track how many contacts are in each list:
const list = db . crm . getLists (). find ( l => l . id === listId );
const contactsInList = db . crm . getAll (). filter ( c =>
c . listIds ?. includes ( listId )
). length ;
// Update count
list . contactCount = contactsInList ;
db . crm . updateList ( list );
Contact counts update automatically when contacts are added or removed from lists.
List Hygiene
Maintain clean, effective lists:
Monthly Tasks
Search for duplicate emails
Merge contact records
Keep most complete record
Identify completed event lists
Archive or delete if no longer needed
Document for historical reference
Check average engagement scores per list
Segment low-engagement contacts
Create re-engagement campaigns
GDPR and Compliance
Best Practices
Consent : Only add contacts who opted in
Unsubscribe : Honor unsubscribe requests immediately
Data Retention : Remove inactive contacts after 2 years
Transparency : Document list purposes
Never purchase or import lists without explicit consent. This violates GDPR and anti-spam laws.
List Export
Export contacts from a list for external use:
const listId = "list_newsletter" ;
const contactsInList = db . crm . getAll (). filter ( c =>
c . listIds ?. includes ( listId )
);
// Convert to CSV
const csv = [
"name,email,status,phone" ,
... contactsInList . map ( c =>
` ${ c . name } , ${ c . email } , ${ c . status } , ${ c . phone } `
)
]. join ( " \n " );
// Download
const blob = new Blob ([ csv ], { type: "text/csv" });
const url = URL . createObjectURL ( blob );
CRM Overview Complete CRM system documentation
User Roles Manage admin permissions