Algolia Search Integration
Algolia replaces osTicket's built-in search with faceted, real-time full-text search. It powers the "My Queue" page and the global ticket search.
Overview
| Component | Details |
|---|---|
| Client Library | algoliasearch (npm) + PHP API client |
| Index Name | rhinotickets_index_dev |
| Key Files | include/custom/trait-algolia.php, include/custom/class.algolia.php |
| Frontend | instantsearch.js (Algolia UI widgets) |
| Maintenance Cron | cron-algolia.php |
Architecture
Ticket Created/Updated
→ Algolia trait indexes ticket data
→ Ticket record pushed to Algolia index
Staff opens My Queue / Search
→ InstantSearch.js sends query to Algolia
→ Faceted results returned (department, status, priority, assignee)
→ Results displayed with hit highlighting
Index Configuration
Searchable Attributes
| Attribute | Source |
|---|---|
subject | Ticket subject line |
ticket_number | Display number |
user_name | Client name |
user_email | Client email |
organization | Client organization name |
thread_content | Combined thread text (messages + responses) |
ai_summary | AI-generated ticket summary |
Facets (Filterable Attributes)
| Facet | Purpose |
|---|---|
department | Filter by department |
status | Filter by ticket status |
priority | Filter by priority level |
assigned_to | Filter by assigned staff |
ai_urgency | Filter by AI urgency level |
created_at | Date-based filtering |
Ranking
Custom ranking uses:
- AI urgency percentage (descending)
- Last updated timestamp (descending)
- Priority level (descending)
PHP Integration
Trait: trait-algolia.php
Used by Suma\Ticket to index ticket data on create/update:
trait AlgoliaTrait
{
/**
* Push ticket data to Algolia index.
*
* @return void
*/
public function indexToAlgolia(): void
{
$record = [
'objectID' => $this->getId(),
'ticket_number' => $this->getNumber(),
'subject' => $this->getSubject(),
'status' => $this->getStatus()->getName(),
'department' => $this->getDeptName(),
'assigned_to' => $this->getAssignee(),
'ai_urgency' => $this->getAIUrgency(),
'created_at' => $this->getCreateDate(),
'updated_at' => $this->getLastUpdated(),
// ... additional fields
];
$index = $this->getAlgoliaIndex();
$index->saveObject($record);
}
}
Class: class.algolia.php
Manages the Algolia client connection and bulk operations:
// Initialize client
$client = Algolia\AlgoliaSearch\SearchClient::create(
ALGOLIA_APP_ID,
ALGOLIA_ADMIN_KEY
);
$index = $client->initIndex(ALGOLIA_INDEX);
Frontend Integration
My Queue Page (scp/my-queue.php)
Uses InstantSearch.js for real-time faceted search:
import { instantsearch, searchBox, hits, refinementList } from 'instantsearch.js';
const search = instantsearch({
indexName: 'rhinotickets_index_dev',
searchClient: algoliasearch(APP_ID, SEARCH_KEY),
});
search.addWidgets([
searchBox({ container: '#searchbox' }),
refinementList({ container: '#department-filter', attribute: 'department' }),
refinementList({ container: '#status-filter', attribute: 'status' }),
hits({ container: '#hits', templates: { item: hitTemplate } }),
]);
search.start();
Search Key (Frontend)
The frontend uses the Search-Only API Key (ALGOLIA_SEARCH_KEY) which has read-only access. The Admin Key is never exposed to the client.
Index Maintenance
Cron Job (cron-algolia.php)
Runs periodically to ensure index consistency:
- Re-indexes tickets modified since last run
- Removes deleted tickets from the index
- Updates status/assignment changes that may have bypassed the trait
Manual Reindex
// Full reindex (use sparingly — resource intensive)
php cron-algolia.php --full
// Reindex a specific ticket
php cron-algolia.php --ticket=108749
Configuration
Settings in include/ost-config.php:
define('ALGOLIA_APP_ID', 'your_application_id');
define('ALGOLIA_ADMIN_KEY', 'your_admin_api_key');
define('ALGOLIA_SEARCH_KEY', 'your_search_only_key');
define('ALGOLIA_INDEX', 'rhinotickets_index_dev');
Troubleshooting
| Issue | Solution |
|---|---|
| Search returns no results | Run php cron-algolia.php to rebuild index |
| Stale results (old status) | Check that Algolia trait fires on status change |
| "Invalid API Key" error | Verify keys in ost-config.php match Algolia dashboard |
| Facets not filtering | Check attribute is configured as facet in Algolia dashboard |
| My Queue blank | Check browser console for JS errors; verify search key |
Key Files
| File | Purpose |
|---|---|
include/custom/trait-algolia.php | Algolia indexing trait for Suma\Ticket |
include/custom/class.algolia.php | Algolia client management and bulk operations |
cron-algolia.php | Index maintenance cron job |
scp/my-queue.php | Staff My Queue page (InstantSearch frontend) |
custom/src/js/algolia.js | Frontend InstantSearch module |