Chatter API Documentation
Overview
The Chatter API allows developers to create custom channels and extend the platform's functionality. Custom channels are JavaScript-based modules that can be loaded directly into Chatter, providing new communication features and integrations.
Key Features
- Real-time message handling via Socket.IO
- File management with tmpweb integration
- User interaction and presence tracking
- Built-in commands for common operations
- Persistent storage and state management
Authentication
Custom channels inherit the authentication context from the main Chatter application. The current user is available through the global socket object and session data.
Getting Current User
// Get current username from session
const username = sessionStorage.getItem('username');
// Or via API
fetch('/api/whoami')
.then(r => r.json())
.then(data => console.log(data.username));
Custom Channels
Custom channels are self-contained modules that extend Chatter's functionality. They can be loaded from URLs and provide custom UI, commands, and integrations.
Channel Structure
A custom channel is a JavaScript object with the following structure:
{
name: "Channel Name",
version: "1.0.0",
description: "Channel description",
icon: "📦",
// Initialize the channel
init: function(container, socket, utils) {
// Setup UI and event listeners
},
// Handle incoming messages
onMessage: function(data) {
// Process messages
},
// Handle commands
onCommand: function(cmd, args) {
// Process commands
},
// Cleanup on unload
destroy: function() {
// Cleanup resources
}
}
Loading Custom Channels
Custom channels can be loaded in settings by providing a URL to the channel definition:
// Channel URL should return the channel object
// Example: https://example.com/my-channel.js
// The file should export: window.ChatterCustomChannel = { ... }
API Reference
Complete API documentation for all Chatter endpoints and services:
File Management API
Upload, manage, and delete files with tmpweb integration
User Management API
Manage users, authentication, and permissions
Settings API
User preferences and application settings
Public API
Public information and status endpoints
Admin API
Administrative functions and system management
Documents API
The Documents API provides functionality for creating, managing, and collaborating on documents with real-time editing and role-based permissions.
Document Management
The Documents API provides functionality for creating, managing, and collaborating on documents with real-time editing and role-based permissions.
Document Roles
- Viewer: Can read documents only
- Editor: Can read and edit documents
- Creator: Document owner who can manage members and permissions
/api/doc/create
Create a new document
| Parameter | Type | Description |
|---|---|---|
| name | string | Document name |
| content | string | Initial document content |
| members | array | List of members to add (username, role) |
POST /api/doc/create
Content-Type: application/json
{
"name": "Meeting Notes",
"content": "# Meeting Notes\n\n## Agenda\n- Project updates\n- Timeline review",
"members": [
{"username": "alice", "role": "editor"},
{"username": "bob", "role": "viewer"}
]
}
/api/doc/list
List all documents you have access to
{
"ok": true,
"documents": [
{
"id": 1,
"name": "Meeting Notes",
"created_by": "john_doe",
"created_at": "2025-01-15T10:30:00Z",
"last_edited_at": "2025-01-15T11:00:00Z",
"role": "creator"
}
]
}
/api/doc/:id
Get document details and content
| Parameter | Type | Description |
|---|---|---|
| id | integer | Document ID |
{
"id": 1,
"name": "My Document",
"content": "Document content here...",
"created_by": "username",
"created_at": "2025-01-15T10:30:00Z",
"last_edited_by": "username",
"last_edited_at": "2025-01-15T11:00:00Z"
}
/api/doc/:id/members
List all members of a document
{
"ok": true,
"members": [
{
"username": "user1",
"role": "editor",
"added_at": "2025-01-15T10:30:00Z"
},
{
"username": "user2",
"role": "viewer",
"added_at": "2025-01-15T10:35:00Z"
}
]
}
/api/doc/:id/add_member
Add a member to a document
| Parameter | Type | Description |
|---|---|---|
| username | string | Username to add |
| role | string | Role: "viewer" or "editor" |
POST /api/doc/1/add_member
Content-Type: application/json
{
"username": "newuser",
"role": "editor"
}
/api/doc/:id/remove_member
Remove a member from a document
| Parameter | Type | Description |
|---|---|---|
| username | string | Username to remove |
/api/doc/:id/update_member_role
Update a member's role
| Parameter | Type | Description |
|---|---|---|
| username | string | Username to update |
| role | string | New role: "viewer" or "editor" |
/api/doc/:id/delete
Delete a document (creator only)
{
"ok": true
}
Socket.IO Events
Documents use Socket.IO for real-time collaboration:
doc_join
Join a document room for real-time updates
{
"doc_id": 1
}
doc_edit
Send document edits to other users
{
"doc_id": 1,
"content": "Updated document content..."
}
doc_updated
Receive document updates from other users
{
"doc_id": 1,
"content": "Updated document content..."
}
doc_member_added
Notify when a member is added
doc_member_removed
Notify when a member is removed
doc_member_role_updated
Notify when a member's role is updated
doc_deleted
Notify when a document is deleted
{
"doc_id": 1
}
Messaging API
The Messaging API provides endpoints for managing Direct Messages (DMs) and Group Direct Messages (GDMs), including message history, logging, and real-time communication.
Message Logging Configuration
DM logging can be controlled via the GD_SAVE_DM_LOGS setting:
- Enabled (1): DM messages are logged and accessible via admin APIs
- Disabled (0): DM messages are not logged for privacy
Direct Messages (DMs)
/api/dm/peers
Get list of users you have DM conversations with
[
"user1",
"user2",
"admin"
]
/api/dm/messages
Get DM conversation history with a specific user
| Parameter | Type | Description |
|---|---|---|
| peer | string | Username to get conversation with |
[
{
"id": 123,
"from_user": "username",
"to_user": "peer",
"text": "Hello there!",
"attachment": null,
"created_at": "2025-01-15T10:30:00Z",
"reply_to": null
}
]
Group Direct Messages (GDMs)
/api/gdm/threads
Get GDM threads or create a new GDM
POST /api/gdm/threads
Content-Type: application/json
{
"name": "Project Team",
"members": ["user1", "user2", "user3"]
}
{
"ok": true,
"id": 456,
"name": "Project Team"
}
/api/gdm/messages
Get messages from a specific GDM thread
| Parameter | Type | Description |
|---|---|---|
| tid | integer | Thread ID |
[
{
"id": 789,
"username": "user1",
"text": "Hey team!",
"attachment": null,
"created_at": "2025-01-15T11:00:00Z",
"edited": 0,
"reply_to": null,
"reply_username": null,
"reply_snippet": null
}
]
/api/gdm/rename
Rename a GDM thread (creator only)
/api/gdm/add_member
Add members to a GDM (creator only)
/api/gdm/remove_member
Remove member from GDM (creator or admin)
/api/gdm/transfer
Transfer GDM ownership to another member
/api/gdm/thread_info
Get information about a GDM thread (members, lock status, etc.)
| Parameter | Type | Description |
|---|---|---|
| tid | integer | Thread ID |
/api/gdm/kick
Kick a member from GDM (owner only)
GDM Management (Admin Controls)
The following endpoints require admin permissions and respect toggle settings:
/api/gdm/lock
Lock a GDM (prevents new messages)
/api/gdm/unlock
Unlock a GDM
/api/gdm/delete
Delete a GDM permanently
Admin Message Logging
/api/admin/dm_logs
Get DM logs for a specific user (admin only, requires GD_SAVE_DM_LOGS enabled)
| Parameter | Type | Description |
|---|---|---|
| peer | string | Username to get logs for |
[
{
"id": 123,
"from_user": "user1",
"to_user": "user2",
"text": "Private message",
"created_at": "2025-01-15T10:30:00Z"
}
]
GD_SAVE_DM_LOGS setting. When disabled, this endpoint returns 403 and no DM messages are logged.
Socket.IO Events
Real-time messaging uses Socket.IO events:
dm_send
Send a direct message
{
"to": "username",
"text": "Hello!",
"attachment": null,
"reply_to": null
}
gdm_send
Send a message to a GDM
{
"thread_id": 456,
"text": "Hey team!",
"attachment": null,
"reply_to": null
}
dm_new
Receive new direct messages
gdm_new
Receive new GDM messages
gdm_threads_refresh
GDM thread updates (member changes, rename, etc.)
dm_typing
DM typing indicators
gdm_typing
GDM typing indicators
GDM Invite System
GDM invites allow users to join private groups through invite links or codes.
/api/gdm/invite/create
Create an invite for a GDM (creator only)
| Parameter | Type | Description |
|---|---|---|
| thread_id | integer | GDM thread ID |
| expires_in | integer | Invite expiry time in seconds (default: 24 hours) |
POST /api/gdm/invite/create
Content-Type: application/json
{
"thread_id": 123,
"expires_in": 86400
}
{
"ok": true,
"invite_code": "ABC123XYZ",
"invite_url": "https://chat.example.com/join/ABC123XYZ",
"expires_at": "2025-01-16T09:00:00Z"
}
/api/gdm/invite/join
Join a GDM using an invite code or link
| Parameter | Type | Description |
|---|---|---|
| code | string | Invite code (GET: query param, POST: body) |
GET /api/gdm/invite/join?code=ABC123XYZ
POST /api/gdm/invite/join
Content-Type: application/json
{
"code": "ABC123XYZ"
}
{
"ok": true,
"thread_id": 123,
"thread_name": "Project Team"
}
Channel API
The Channel API provides endpoints for managing custom channels and voice channels in Chatter.
Custom Channels
Custom channels are JavaScript-based modules that extend Chatter's functionality. They can be loaded from URLs and provide custom UI, commands, and integrations.
/api/channels/custom/register
Register a custom channel
| Parameter | Type | Description |
|---|---|---|
| url | string | URL to the custom channel definition |
| name | string | Display name for the channel |
| enabled | boolean | Whether to enable the channel (default: true) |
POST /api/channels/custom/register
Content-Type: application/json
{
"url": "https://example.com/my-channel.js",
"name": "My Custom Channel",
"enabled": true
}
{
"ok": true,
"id": 1
}
/api/channels/custom/list
List all registered custom channels
{
"ok": true,
"channels": [
{
"id": 1,
"name": "My Custom Channel",
"url": "https://example.com/my-channel.js",
"enabled": true,
"created_at": "2025-01-15T10:30:00Z"
}
]
}
/api/channels/custom/:id
Delete a custom channel (creator or admin only)
| Parameter | Type | Description |
|---|---|---|
| id | integer | Channel ID to delete |
/api/channels/custom/:id/toggle
Enable or disable a custom channel (creator or admin only)
| Parameter | Type | Description |
|---|---|---|
| id | integer | Channel ID to toggle |
| enabled | boolean | Whether to enable the channel |
Voice Channels
Voice channels provide real-time audio communication capabilities within Chatter.
/api/voice/channels
List active voice channels
{
"ok": true,
"channels": [
"general",
"gaming",
"music"
]
}
{
"ok": false,
"error": "Voice service unavailable",
"channels": []
}
Channel Structure
A custom channel is a JavaScript object with the following structure:
{
name: "Channel Name",
version: "1.0.0",
description: "Channel description",
icon: "📦",
// Initialize the channel
init: function(container, socket, utils) {
// Setup UI and event listeners
},
// Handle incoming messages
onMessage: function(data) {
// Process messages
},
// Handle commands
onCommand: function(cmd, args) {
// Process commands
},
// Cleanup on unload
destroy: function() {
// Cleanup resources
}
}
Loading Custom Channels
Custom channels can be loaded in settings by providing a URL to the channel definition:
// Channel URL should return the channel object
// Example: https://example.com/my-channel.js
// The file should export: window.ChatterCustomChannel = { ... }
Built-in Commands
Custom channels have access to built-in commands for common operations:
Upload a file from URL to tmpweb storage
List all uploaded files with expiry times
Delete a file by ID
Get detailed information about a file
Get information about a user
List all online users
Send a message to a channel
Get current channel information
Examples
Example 1: Simple Echo Channel
A basic channel that echoes messages back to the user:
window.ChatterCustomChannel = {
name: "Echo Channel",
version: "1.0.0",
description: "Echoes messages back to you",
icon: "🔊",
init: function(container, socket, utils) {
container.innerHTML = `
<div style="padding: 1rem;">
<h3>Echo Channel</h3>
<div id="echo-messages" style="margin-bottom: 1rem;"></div>
<input id="echo-input" type="text" placeholder="Type something..."
style="width: 100%; padding: 0.5rem;">
</div>
`;
const input = document.getElementById('echo-input');
const messages = document.getElementById('echo-messages');
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && input.value) {
const msg = document.createElement('div');
msg.textContent = '🔊 ' + input.value;
msg.style.padding = '0.5rem';
msg.style.margin = '0.25rem 0';
msg.style.background = 'rgba(59, 130, 246, 0.1)';
msg.style.borderRadius = '0.25rem';
messages.appendChild(msg);
input.value = '';
}
});
},
destroy: function() {
// Cleanup
}
};
Example 2: File Manager Channel
A channel for managing uploaded files:
window.ChatterCustomChannel = {
name: "File Manager",
version: "1.0.0",
description: "Manage uploaded files",
icon: "📁",
init: function(container, socket, utils) {
container.innerHTML = `
<div style="padding: 1rem;">
<h3>File Manager</h3>
<input type="file" id="file-input" style="margin-bottom: 1rem;">
<button id="upload-btn" style="padding: 0.5rem 1rem; cursor: pointer;">
Upload
</button>
<div id="file-list" style="margin-top: 1rem;"></div>
</div>
`;
document.getElementById('upload-btn').addEventListener('click', async () => {
const file = document.getElementById('file-input').files[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.ok) {
alert('File uploaded: ' + data.url);
this.loadFiles();
}
});
this.loadFiles();
},
loadFiles: function() {
fetch('/api/files/list')
.then(r => r.json())
.then(data => {
const list = document.getElementById('file-list');
list.innerHTML = data.files.map(f => `
<div style="padding: 0.5rem; margin: 0.25rem 0;
background: rgba(59, 130, 246, 0.1);
border-radius: 0.25rem;">
<strong>${f.name}</strong>
<small>Expires: ${new Date(f.expires_at).toLocaleString()}</small>
</div>
`).join('');
});
},
destroy: function() {}
};
Example 3: User Status Channel
A channel that displays online users:
window.ChatterCustomChannel = {
name: "User Status",
version: "1.0.0",
description: "View online users",
icon: "👥",
init: function(container, socket, utils) {
container.innerHTML = `
<div style="padding: 1rem;">
<h3>Online Users</h3>
<div id="user-list"></div>
</div>
`;
socket.on('user_list_refresh', () => this.loadUsers());
this.loadUsers();
},
loadUsers: function() {
fetch('/api/users/online')
.then(r => r.json())
.then(data => {
const list = document.getElementById('user-list');
list.innerHTML = data.users.map(u => `
<div style="padding: 0.5rem; margin: 0.25rem 0;
display: flex; align-items: center; gap: 0.5rem;">
<span style="width: 8px; height: 8px;
background: #10b981; border-radius: 50%;"></span>
<strong>${u.username}</strong>
</div>
`).join('');
});
},
destroy: function() {}
};
Best Practices
- Always clean up resources in the
destroymethod - Use Socket.IO events for real-time updates
- Handle errors gracefully with try-catch blocks
- Validate user input before processing
- Use HTTPS for custom channel URLs in production
- Test channels thoroughly before deployment
- Document your channel's API and commands