Chat — Reference
The Chat surface is the visitor-facing live-chat plane for SGEN. It owns the chat widget rendered on the public frontend, the inbound conversation queue an operator works from, the per-conversation transcript that captures every message and operator action, the canned-response catalog that lets operators answer common questions consistently, the routing rules that decide which operator receives a new conversation, and the offline-message fallback for inbound chats that arrive outside staffed hours. Anything that asks "let a visitor talk to the team in-product" traces back to a record managed here.
This page is a reference for platform engineers and integrators who need to understand the surface before scripting against it, extending the routing model, or scoping a customer-support program. Customer-facing how-tos for working the queue live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.
Overview
Chat lives under the Chat module in SG-Admin. The module renders five primary views — the conversation queue (every inbound conversation with state, assignment, and unread-message indicator), the conversation view (the full transcript for a single conversation with the message-input bar and the canned-response picker), the canned-response catalog (the named library of pre-authored replies), the routing-rules editor (the conditions that assign new conversations to operators), and the transcript archive (concluded conversations searchable by visitor id, operator id, and date range).
The module is paired by convention with the Users, Notifications, and Activity Log surfaces. Operator assignment references user records by id; outbound notifications (new-conversation alerts, mention pings) hand off to the Notifications surface; every operator action writes an Activity Log entry. The Chat module owns the conversation and the queue; the consuming surfaces own the records the routing rules point at.
A second surface — the chat widget — is the public-facing read / write contract. The widget renders on configured public pages, opens on visitor click, captures the visitor's name and email (optional, configurable per site), surfaces the inbound message-input bar, displays operator replies as they arrive, and persists the conversation identifier in a long-lived cookie so a returning visitor reopens the same conversation. The widget also surfaces an offline-message form when no operator is available and an away-message banner when the site is configured as off-hours.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Chat
- URL prefix:
/sg-admin/chat/ - View templates:
application/views/Admin/Chat/
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Chat [12 in queue]│├──────────────────────────────────────────────────────────────────────┤│ Visitor Last message Assigned State ││ ───────────────── ──────────────────────────── ────────── ──────││ Maria Reyes "Hi, the export button…" Jerome Open ││ (no name) "How do I change the domain?" — Unass ││ James Compton "Quick question on pricing" Maria Open ││ Sandbox Operator "I think I broke something" Jerome Open ││ ││ [⋯ Open] [⋯ Assign] [⋯ Mark resolved] [⋯ Snooze] │└──────────────────────────────────────────────────────────────────────┘Actions
The Chat surface exposes the following operations. Each is described by what it does to the data and to the queue lifecycle, not by its internal method name.
List and filter queue
Returns the conversation records visible to the current operator, paginated, with visitor identifier, last-message preview, assignment, lifecycle state, and unread-message indicator columns. Supports filter by state (open, unassigned, snoozed, resolved), filter by assigned operator, free-text search across recent messages, and per-page count. The queue is the operator's primary working view — the list refreshes on inbound message arrival without requiring a manual reload.
Open conversation
Loads the full transcript for a single conversation into the conversation view. The view carries the ordered message history, the visitor's identifying fields (name, email, current page URL, user-agent summary), the assignment-control bar, and the message-input bar. Opening a conversation marks the operator-side unread indicator cleared.
Send message
Posts a new operator-side message into the conversation. The message is captured into the transcript, surfaced to the visitor's widget within seconds, and counted as a sent-message event on the operator's activity record. The surface validates message length and rejects empty messages.
Send canned response
A dedicated write path that posts a pre-authored reply from the canned-response catalog. The operator picks the response from a typeahead picker; the surface substitutes any per-conversation placeholders (visitor name, current page URL) and sends the resulting message. Canned responses count as sent messages for operator-activity tracking; they also increment a per-canned-response usage counter that the catalog view surfaces.
Assign conversation
Reassigns a conversation to another operator. Accepts a target operator id. The surface validates that the target operator has the chat-respond capability and is currently on-duty (per the operator's working-hours setting on their user record). On success, the conversation is added to the target operator's queue and removed from the current operator's queue.
Mark resolved
Transitions a conversation from open to resolved. The widget shows a "this conversation has been closed; reopen?" banner to the visitor on their next message attempt. Reopens transition back to open and notify the original assigned operator.
Snooze conversation
Suspends the conversation from the active queue without resolving it. Accepts a snooze-until timestamp. The conversation reappears in the queue when the timestamp is reached. Snooze is the fast path for an operator who needs to wait on a colleague or an external answer without losing the conversation.
Configure canned responses
Returns the catalog editor for the named library of pre-authored replies. Each entry carries a slug, a label, the response body (with placeholder syntax), and a per-team scope (catalog-wide, per-role, or per-operator). Operators see only the entries scoped to them.
Configure routing rules
Routing rules are an ordered list of conditions. Each rule pairs a match condition with an assignment outcome (target operator id, target operator role, or round-robin pool slug). Conditions cover: visitor's current page URL, time of day, visitor's identified-or-anonymous state, and a custom attribute set by an upstream module. The surface walks rules in order — the first matching rule decides the assignment; if no rule matches, the conversation enters the unassigned pool and any on-duty operator can claim it.
Search transcripts
Returns conversation records matching a search query. Supports search by visitor identifier, operator identifier, date range, free-text content of messages, and lifecycle state. Used by operators reviewing prior conversations and by team leads auditing the queue.
Export transcript
A dedicated read path that emits a single conversation's transcript as a downloadable file. Includes message history, operator actions (assignments, snoozes, resolutions), and visitor identifying fields. The surface logs the export to the Activity Log with the operator and target conversation.
Archive conversation
Marks the conversation record inactive without removing it from the database. Archived conversations disappear from the default queue and from default transcript-search results but remain queryable via the archive filter. The visitor-side cookie is preserved — a returning visitor reopens a new conversation rather than reopening the archived one.
Permanent delete
Hard-removes the conversation record. Available only after an archive. The transcript is removed with the record. This path is irreversible and should be wired behind a confirmation prompt in any integration that exposes it.
Data model
A conversation record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
visitor_cookie_id | string | The widget-side cookie value. Stable across visitor sessions on the same browser. |
visitor_name | string | Optional. Captured from the widget greeting. |
visitor_email | string | Optional. Captured from the widget greeting. |
assigned_operator_id | integer | Null while unassigned. |
lifecycle_state | enum | open, snoozed, resolved, archived. |
snoozed_until | timestamp | Set when snoozed. Null otherwise. |
entry_page_url | string | The page the visitor opened the widget from. |
last_message_at | timestamp | Updated on every new message in either direction. |
unread_for_operator | boolean | Cleared when the operator opens the conversation. |
created_at | timestamp | Set on first visitor message. |
updated_at | timestamp | Touched on any state transition. |
Canned-response shape: the catalog is keyed by slug, with a label, body (placeholder-supporting), per-team scope, and a usage counter that increments on every send.
CONVERSATION RECORD├── id integer primary key├── visitor_cookie_id string widget-side stable id├── visitor_name / email string optional, captured at greeting├── assigned_operator_id integer null = unassigned├── lifecycle_state enum open | snoozed | resolved | archived├── snoozed_until timestamp set when snoozed├── entry_page_url string page the widget opened from├── last_message_at timestamp recency for queue sort├── unread_for_operator boolean queue indicator└── timestamps created_at, updated_at↓ one per message (either direction)MESSAGE RECORDper (conversation_id, sequence): direction, operator_id,body, timestamp, canned_slug↓ catalogCANNED-RESPONSE RECORDper slug: label, body, scope, usage_countPermissions
Access to the Chat surface is gated at two layers.
Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Chat surface. The widget-side endpoints are public but rate-limited per visitor cookie.
Layer 2 — per-action capability. Within SG-Admin, each Chat action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:
| Capability | Administrator | Editor | Viewer |
|---|---|---|---|
| List queue | ✔ | ✔ | ✔ |
| Open conversation | ✔ | ✔ | ✔ |
| Send message | ✔ | ✔ | — |
| Send canned response | ✔ | ✔ | — |
| Assign conversation | ✔ | ✔ | — |
| Mark resolved | ✔ | ✔ | — |
| Snooze conversation | ✔ | ✔ | — |
| Configure canned responses | ✔ | — | — |
| Configure routing rules | ✔ | — | — |
| Search transcripts | ✔ | ✔ | ✔ |
| Export transcript | ✔ | — | — |
| Archive | ✔ | — | — |
| Permanent delete | ✔ | — | — |
Self-protection rules. An operator cannot assign a conversation to themselves through the assignment-control bar if they are not on-duty (the surface returns a structured rejection prompting them to mark on-duty first). A conversation cannot be marked resolved while it has unread visitor-side messages — the surface surfaces a soft warning prompting the operator to read the messages first.
Audit. Every operator-side write — message send, canned-response send, assignment, snooze, resolve, archive, export, delete — emits an Activity Log entry. Visitor-side messages are not Activity-Logged (they are the conversation content itself); the transcript serves as that record.
INBOUND VISITOR MESSAGE│ inputs: visitor_cookie_id, current_url, message_body▼┌───────────────────────────┐│ Resolve conversation │ existing cookie → load; new cookie → create└─────────────┬─────────────┘│▼┌───────────────────────────┐│ Append message record │ direction=visitor, timestamp now└─────────────┬─────────────┘│ first message in new conversation▼┌───────────────────────────┐│ Walk routing rules │ per-rule: condition matches?│ stop at first match │└─────────────┬─────────────┘│┌──────┴──────┐│ match │ no match▼ ▼assign to enter unassignedtarget op pool (any on-dutyoperator can claim)│ │└──────┬──────┘▼Notify assigned operator (or all on-duty if unassigned)│▼Surface in queue with unread indicatorRelated references
- Users — Reference. Operator assignment references user records by id. Soft-deleted operators still appear on historical transcripts but cannot receive new assignments. The on-duty / working-hours setting on a user record is read by the routing-rules engine.
- Notifications — Reference. New-conversation alerts, mention pings, and assignment notifications hand off to the Notifications surface. Routing-rule misses that result in unassigned conversations trigger an on-call notification to all operators with the chat-respond capability.
- Activity Log — Reference. Every operator-side write emits a one-line entry. Transcript exports carry the target conversation id on the audit entry.
- Pages — Reference. The chat widget is configured per page or per site under the Pages module. Widget visibility, greeting copy, and off-hours behavior are page-level settings.
- Settings — Reference. Owns the role definitions referenced by the capability map, the site-wide working-hours setting, and the Activity Log retention policy that governs audit-entry lifetime.
/docs/chat.