Overview
Conversations are at the heart of Chatwoot. Each conversation represents an interaction with a contact across any channel, containing messages, metadata, and tracking information.
Conversation States
Conversations can be in one of four states:
Open
Resolved
Pending
Snoozed
Active conversations requiring attention from agents. conversation. open!
conversation. status # => "open"
Conversations marked as complete. conversation. resolved!
conversation. status # => "resolved"
Conversations awaiting customer response or handled by bots. conversation. pending!
conversation. status # => "pending"
Conversations temporarily hidden until a specific time. conversation. snoozed!
conversation. update! ( snoozed_until: 2 . days . from_now )
Priority Levels
Set conversation priorities to help agents focus on urgent issues:
conversation. priority = :urgent # urgent, high, medium, low
conversation. save!
# Toggle priority
conversation. toggle_priority ( :high )
Priority levels: Urgent > High > Medium > Low
Conversation Attributes
Core Attributes
conversation. display_id # User-friendly conversation ID
conversation. status # open, resolved, pending, snoozed
conversation. priority # urgent, high, medium, low
conversation. assignee # Assigned agent
conversation. team # Assigned team
conversation. inbox # Source inbox/channel
conversation. contact # Associated contact
conversation. created_at # Creation timestamp
conversation. last_activity_at # Last message or activity
conversation. first_reply_created_at # Agent's first response time
conversation. waiting_since # Time since last customer message
Custom Attributes
Store additional metadata:
conversation. custom_attributes = {
order_id: "ORD-12345" ,
customer_tier: "premium" ,
source: "mobile_app"
}
conversation. save!
Additional Attributes
System-managed attributes:
conversation. additional_attributes
# => {
# referer: "https://example.com/pricing",
# browser: "Chrome 120",
# browser_language: "en-US",
# conversation_language: "en"
# }
Assignment Management
Assign to Agent
# Assign to a specific agent
service = Conversations :: AssignmentService . new (
conversation: conversation,
assignee_id: agent. id ,
assignee_type: 'User'
)
service. perform
# Unassign
conversation. update! ( assignee_id: nil )
Assign to Team
conversation. update! ( team: team)
# Team-based filtering
team_conversations = account. conversations . where ( team_id: team. id )
Auto-Assignment
Enable on Inbox
inbox. update! ( enable_auto_assignment: true )
Configure Assignment Rules
Set max assignment limits per agent: inbox. auto_assignment_config = {
max_assignment_limit: 10
}
Assignment Triggers
Conversations are auto-assigned when:
New conversation is created
Conversation status changes to open
Agent becomes available
Conversation Scopes
Common Filters
# Unassigned conversations
Conversation . unassigned
# Assigned conversations
Conversation . assigned
# Conversations assigned to specific agent
Conversation . assigned_to (agent)
# Unattended conversations (no first reply or waiting for agent)
Conversation . unattended
# By status
Conversation . open
Conversation . resolved
Conversation . pending
Conversation . snoozed
Advanced Filtering
# Find conversations ready for auto-resolve
Conversation . resolvable_not_waiting ( auto_resolve_after: 48 . hours )
# Sort by last user message
Conversation . last_user_message_at
Messages
Accessing Messages
# All messages in conversation
conversation. messages
# Last incoming message
conversation. last_incoming_message
# Recent messages (last 5)
conversation. recent_messages
# Unread messages
conversation. unread_messages
conversation. unread_incoming_messages
Read/Unread Tracking
# Track agent's last seen time
conversation. update! ( agent_last_seen_at: Time . current )
# Track assignee's last seen time
conversation. update! ( assignee_last_seen_at: Time . current )
# Contact's last seen time
conversation. update! ( contact_last_seen_at: Time . current )
Conversation Actions
Toggle Status
# Toggle between open and resolved
conversation. toggle_status
# Open conversation changes to resolved
# Resolved/pending/snoozed changes to open
Bot Handoff
Transfer from bot to human agent:
conversation. bot_handoff!
# Sets status to open and triggers CONVERSATION_BOT_HANDOFF event
Mute Conversation
conversation. mute!
conversation. unmute!
Check Reply Capability
Some channels have messaging windows:
if conversation. can_reply?
# Send message
else
# Show error: messaging window closed
end
Labels
Organize conversations with labels:
# Add labels
conversation. add_labels ([ "bug" , "urgent" , "billing" ])
# Remove labels
conversation. remove_labels ([ "billing" ])
# Get labels
conversation. label_list # => ["bug", "urgent"]
conversation. cached_label_list_array # => ["bug", "urgent"]
Participants
Track conversation participants:
conversation. conversation_participants
# => [#<ConversationParticipant>, ...]
Attachments
Access all attachments in a conversation:
attachments = conversation. attachments
. includes ( :message )
. order ( created_at: :desc )
. page ( 1 )
. per ( 100 )
Advanced Features
Conversation Language
Automatic language detection:
conversation. language # => "en", "es", "fr", etc.
Identifiers
Unique identifiers for integrations:
conversation. identifier # Custom identifier
conversation. uuid # System-generated UUID
Activity Tracking
# Last activity timestamp
conversation. last_activity_at
# Waiting time (since last customer message)
conversation. waiting_since
# First response time
conversation. first_reply_created_at
API Examples
Create Conversation
conversation = ConversationBuilder . new (
params: {
contact_id: contact. id ,
inbox_id: inbox. id ,
status: :open ,
additional_attributes: {
referer: "https://example.com"
}
},
contact_inbox: contact_inbox
). perform
Update Conversation
conversation. update! (
status: :resolved ,
assignee: agent,
team: team,
priority: :high ,
custom_attributes: {
resolution_type: "solved"
}
)
Filter Conversations
result = Conversations :: FilterService . new (
params: {
status: "open" ,
assignee_type: "me" ,
inbox_id: inbox. id ,
team_id: team. id ,
labels: [ "bug" , "urgent" ]
},
user: current_user,
account: current_account
). perform
conversations = result[ :conversations ]
count = result[ :count ]
Events
Conversations trigger various events:
CONVERSATION_CREATED - New conversation created
CONVERSATION_UPDATED - Conversation attributes changed
CONVERSATION_OPENED - Status changed to open
CONVERSATION_RESOLVED - Status changed to resolved
CONVERSATION_STATUS_CHANGED - Any status change
CONVERSATION_READ - Marked as read
CONVERSATION_CONTACT_CHANGED - Contact changed
CONVERSATION_BOT_HANDOFF - Bot transferred to agent
Best Practices
Always check can_reply? before sending messages on channels with messaging windows (WhatsApp, Instagram).
Use custom attributes to store integration-specific data like order IDs, subscription status, or custom metadata.
The last_activity_at timestamp updates on any message or activity. Use waiting_since to track time since last customer message.
Contacts Manage contact profiles
Teams Team-based assignment
Automation Automate conversation workflows
Reports Conversation analytics