Documentation Index Fetch the complete documentation index at: https://mintlify.com/Merkurcode/nauto-console/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Contacts represent customers or visitors who interact with your support channels. Chatwoot provides comprehensive contact management with profiles, custom attributes, and segmentation capabilities.
Contacts are classified into three types:
Visitor Anonymous users browsing your website
Lead Identified prospects with contact information
Customer Paying customers or registered users
contact. contact_type # => "visitor", "lead", or "customer"
# Change contact type
contact. update! ( contact_type: :customer )
Core Attributes
contact. name # Full name
contact. email # Email address (unique per account)
contact. phone_number # Phone number in E.164 format (+1234567890)
contact. identifier # Custom unique identifier
contact. blocked # Block status
contact. last_activity_at # Last interaction timestamp
Name Components
contact. name # "John Doe"
contact. middle_name # "Michael"
contact. last_name # "Doe"
Location Data
contact. location # "New York, NY"
contact. country_code # "US"
contact = account. contacts . create! (
name: "Jane Smith" ,
email: "jane@example.com" ,
phone_number: "+12125551234" ,
contact_type: :lead
)
With Additional Attributes
contact = account. contacts . create! (
name: "John Doe" ,
email: "john@example.com" ,
additional_attributes: {
company_name: "Acme Corp" ,
job_title: "CEO" ,
city: "New York" ,
country: "United States" ,
social_profiles: {
twitter: "johndoe" ,
linkedin: "johndoe"
}
}
)
Custom Attributes
Store custom data specific to your business:
# Set custom attributes
contact. custom_attributes = {
subscription_plan: "enterprise" ,
account_balance: 1500.00 ,
signup_date: "2024-01-15" ,
total_orders: 42 ,
vip_customer: true
}
contact. save!
# Access custom attributes
contact. custom_attributes [ "subscription_plan" ] # => "enterprise"
Custom attributes are stored as JSONB and support complex data types including strings, numbers, booleans, and nested objects.
Additional Attributes
System-managed attributes for enriched contact data:
contact. additional_attributes
# => {
# company_name: "Acme Corp",
# job_title: "Engineering Manager",
# city: "San Francisco",
# country: "United States",
# social_profiles: {
# twitter: "handle",
# linkedin: "profile",
# github: "username"
# },
# browser: "Chrome 120",
# browser_version: "120.0",
# platform: "macOS"
# }
Email-based Lookup
contact = Contact . from_email ( "jane@example.com" )
Multiple Identifiers
Contacts can be identified by:
Email - Unique per account, case-insensitive
Phone Number - Unique per account, E.164 format required
Identifier - Custom unique identifier for integrations
# Phone number validation (E.164 format)
contact. phone_number = "+12125551234" # Valid
contact. phone_number = "212-555-1234" # Invalid
Phone numbers must be in E.164 format: +[country code][number]. Example: +12125551234
Access all conversations for a contact:
# All conversations
contact. conversations
# Active conversations
contact. conversations . open
# Recent conversations
contact. conversations . order ( created_at: :desc ). limit ( 10 )
Contacts can interact through multiple channels:
# Get all inboxes where contact has interacted
contact. contact_inboxes
contact. inboxes
# Get source ID for specific inbox
source_id = contact. get_source_id (inbox. id )
Messages and Notes
# All messages from contact
contact. messages
# Internal notes about contact
contact. notes
Block spam or abusive contacts:
# Block contact
contact. update! ( blocked: true )
# Unblock contact
contact. update! ( blocked: false )
# Check if blocked
contact. blocked? # => true/false
When a contact is blocked, new conversations are automatically resolved.
Labels
Organize contacts with labels:
# Add labels
contact. add_labels ([ "vip" , "enterprise" , "priority" ])
# Remove labels
contact. remove_labels ([ "priority" ])
# Get labels
contact. label_list # => ["vip", "enterprise"]
CSAT Responses
Access customer satisfaction survey responses:
contact. csat_survey_responses
# Calculate average rating
average_csat = contact. csat_survey_responses . average ( :rating )
Multiple sorting options:
# Sort by name
Contact . order_on_name ( :asc )
Contact . order_on_name ( :desc )
# Sort by last activity
Contact . order_on_last_activity_at ( :desc )
# Sort by creation date
Contact . order_on_created_at ( :desc )
# Sort by company name
Contact . order_on_company_name ( :asc )
# Sort by location
Contact . order_on_city ( :asc )
Contact . order_on_country_name ( :asc )
Filter contacts with identification:
# Contacts with email, phone, or identifier
resolved_contacts = Contact . resolved_contacts
# CRM v2: Lead contacts
resolved_contacts = Contact . resolved_contacts ( use_crm_v2: true )
Find and remove inactive contacts:
# Find stale contacts (no identification, no conversations, older than 30 days)
stale_contacts = Contact . stale_without_conversations ( 30 . days . ago )
stale_contacts. destroy_all
IP Lookup Enhancement
Automatic location detection from IP:
# Enabled per account feature
if account. feature_enabled? ( 'ip_lookup' )
# Automatically enriches location data
# Triggered after contact creation
end
Avatar Management
Contacts inherit from Avatarable module:
# Get avatar URL
contact. avatar_url
# Upload custom avatar
contact. avatar . attach (avatar_file)
Contacts trigger events for integrations:
CONTACT_CREATED - New contact created
CONTACT_UPDATED - Contact attributes changed
CONTACT_DELETED - Contact deleted
# Webhook payload
contact. webhook_data
# => {
# account: {...},
# additional_attributes: {...},
# avatar: "https://...",
# custom_attributes: {...},
# email: "jane@example.com",
# id: 123,
# identifier: "USER-001",
# name: "Jane Smith",
# phone_number: "+12125551234",
# thumbnail: "https://...",
# blocked: false
# }
Best Practices
Email Validation
Emails are automatically downcased and validated against Devise.email_regexp.
contact. email = "Jane@EXAMPLE.COM"
contact. save!
contact. email # => "jane@example.com"
# Always use E.164 format
contact. phone_number = "+12125551234" # Correct
contact. phone_number = "+1 (212) 555-1234" # Will fail validation
Custom Attributes Schema
Define custom attribute definitions:
account. custom_attribute_definitions . create! (
attribute_key: "subscription_plan" ,
attribute_display_name: "Subscription Plan" ,
attribute_display_type: "text" ,
attribute_model: "contact_attribute"
)
Company Association
# Associate contact with company (Enterprise feature)
contact. update! ( company_id: company. id )
Availability Status
Track contact online status:
contact. online?
contact. offline?
contact. busy?
API Examples
# Search by name, email, phone, or identifier
results = account. contacts . where (
"name ILIKE ? OR email ILIKE ? OR phone_number ILIKE ?" ,
"% #{ query } %" , "% #{ query } %" , "% #{ query } %"
)
# Merge duplicate contacts
primary_contact = account. contacts . find (primary_id)
duplicate_contact = account. contacts . find (duplicate_id)
# Move all conversations to primary
duplicate_contact. conversations . update_all ( contact_id: primary_contact. id )
# Delete duplicate
duplicate_contact. destroy
Bulk Update
# Update multiple contacts
Contact . where ( id: contact_ids). update_all (
custom_attributes: { customer_tier: "gold" }
)
Conversations View contact conversations
Custom Attributes Define custom fields
Segments Create contact segments