Wonksknow Chat API
A production-ready microservice chat application built with Go, supporting real-time messaging via WebSockets, multi-tenancy, and role-based access control (RBAC).
⨠Features
Isolated data per tenant
WebSocket support for instant messaging
Fine-grained permissions
Complete CRUD operations
Create and manage group conversations
Edit, delete, pin, reactions, read receipts
Support for file attachments in messages
Google and GitHub OAuth integration
Clean REST API design
Interactive API documentation
đ Quick Start
Prerequisites
- Go 1.21 or higher
- MongoDB (local or MongoDB Atlas)
- Environment variables configured (see
.env.example)
Installation
- Clone the repository:
git clone <repository-url> cd wonksknow-chat - Install dependencies:
go mod download - Configure environment variables:
cp env.example .env # Edit .env with your configuration - Run the application:
go run main.go
The server will start on http://localhost:8080 (or the port specified in SERVER_PORT).
đĨ Tenant Onboarding Guide
This guide will walk you through the process of signing up as a tenant, generating tokens, and using all the APIs.
Step 1: Create a Tenant
Create a new tenant account. This is your organization's entry point to the chat service.
Endpoint: POST /api/v1/tenants
Request:
curl -X POST http://localhost:8080/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{
"name": "My Company"
}'
Response:
{
"id": "tenant-uuid-here",
"name": "My Company",
"api_key": "api-key-uuid-here",
"is_active": true,
"message": "Tenant created successfully. Please save the API key securely."
}
id and api_key securely. You'll need:
id(Tenant ID) for all authenticated requestsapi_keyto generate authentication tokens
Step 2: Generate an Authentication Token
Use your API key to generate an authentication token. This token is required for all API requests.
Endpoint: POST /api/v1/tenant/{tenant_id}/auth/token
Request:
curl -X POST http://localhost:8080/api/v1/tenant/{tenant_id}/auth/token \
-H "X-API-Key: your-api-key-here"
Response:
{
"token": "generated-token-here",
"tenant_id": "tenant-uuid-here",
"expires_at": "2024-11-20T10:29:07Z",
"expires_in": 86400
}
Step 3: Create Users
Create users in your tenant. Users can send messages, join groups, and have roles assigned.
Endpoint: POST /api/v1/users
Request:
curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "X-Tenant-ID: your-tenant-id-here" \
-H "X-User-ID: admin-user-id-here" \
-d '{
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890"
}'
Response:
{
"id": "user-uuid-here",
"tenant_id": "tenant-uuid-here",
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890",
"is_active": true,
"created_at": "2024-11-19T10:29:07Z",
"updated_at": "2024-11-19T10:29:07Z"
}
Required Headers:
Authorization: Bearer {token}- Your authentication tokenX-Tenant-ID: {tenant_id}- Your tenant IDX-User-ID: {user_id}- The user ID performing the action (for RBAC)
Step 4: Create Groups (Optional)
Create group chat rooms where multiple users can communicate.
Endpoint: POST /api/v1/groups
Request:
curl -X POST http://localhost:8080/api/v1/groups \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "X-Tenant-ID: your-tenant-id-here" \
-H "X-User-ID: admin-user-id-here" \
-d '{
"name": "Team Chat",
"description": "Team discussion room",
"user_ids": ["user-id-1", "user-id-2", "user-id-3"]
}'
Step 5: Send Messages
Send messages to users or groups.
Endpoint: POST /api/v1/chats
Direct Message:
curl -X POST http://localhost:8080/api/v1/chats \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "X-Tenant-ID: your-tenant-id-here" \
-H "X-User-ID: sender-user-id-here" \
-d '{
"receiver_id": "receiver-user-id-here",
"message_body": "Hello! How are you?",
"message_type": "text"
}'
Group Message:
curl -X POST http://localhost:8080/api/v1/chats \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "X-Tenant-ID: your-tenant-id-here" \
-H "X-User-ID: sender-user-id-here" \
-d '{
"group_id": "group-id-here",
"message_body": "Hello team!",
"message_type": "text"
}'
Step 6: Connect via WebSocket
Connect to the WebSocket endpoint for real-time messaging.
WebSocket Endpoint: ws://localhost:8080/api/v1/ws
JavaScript Example:
const token = 'your-token-here';
const ws = new WebSocket(`ws://localhost:8080/api/v1/ws?token=${token}`);
ws.onopen = () => {
console.log('WebSocket connected');
// Send a message
ws.send(JSON.stringify({
type: 'message',
tenant_id: 'your-tenant-id',
chat_id: 'message-id-here',
sender_id: 'sender-user-id',
data: {
receiver_id: 'receiver-user-id',
message_body: 'Hello via WebSocket!'
},
timestamp: new Date().toISOString()
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Received message:', message);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('WebSocket disconnected');
};
đ API Documentation
Interactive Swagger documentation is available at:
- Swagger UI: http://localhost:8080/swagger/index.html
- Swagger JSON: http://localhost:8080/swagger/doc.json
- Swagger YAML: http://localhost:8080/swagger/doc.yaml
đ Authentication
API Key Authentication
Used for generating tenant authentication tokens.
Header:
X-API-Key: your-api-key-here
Used in:
POST /api/v1/tenant/{tenant_id}/auth/token
Bearer Token Authentication
Used for all authenticated API endpoints.
Headers:
Authorization: Bearer your-token-here
X-Tenant-ID: your-tenant-id-here
X-User-ID: your-user-id-here (optional, for RBAC)
Used in:
- All
/api/v1/users,/api/v1/groups,/api/v1/chats, and/api/v1/rbacendpoints
đ API Endpoints
Tenants
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/v1/tenants |
Create a new tenant | None |
GET |
/api/v1/tenants/{id} |
Get tenant information | None |
PUT |
/api/v1/tenants/{id} |
Update tenant | None |
POST |
/api/v1/tenants/{id}/regenerate-api-key |
Regenerate API key | None |
Authentication
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/v1/tenant/{tenant_id}/auth/token |
Generate authentication token | API Key |
Users
| Method | Endpoint | Description | Auth | Permission |
|---|---|---|---|---|
POST |
/api/v1/users |
Create a user | Bearer | users:create |
GET |
/api/v1/users |
List all users | Bearer | users:read |
GET |
/api/v1/users/{id} |
Get user by ID | Bearer | users:read |
PUT |
/api/v1/users/{id} |
Update user | Bearer | users:update |
DELETE |
/api/v1/users/{id} |
Delete user | Bearer | users:delete |
Groups
| Method | Endpoint | Description | Auth | Permission |
|---|---|---|---|---|
POST |
/api/v1/groups |
Create a group | Bearer | groups:create |
GET |
/api/v1/groups |
List all groups | Bearer | groups:read |
GET |
/api/v1/groups/{id} |
Get group by ID | Bearer | groups:read |
PUT |
/api/v1/groups/{id} |
Update group | Bearer | groups:update |
DELETE |
/api/v1/groups/{id} |
Delete group | Bearer | groups:delete |
Chats
| Method | Endpoint | Description | Auth | Permission |
|---|---|---|---|---|
POST |
/api/v1/chats |
Send a message | Bearer | chats:create |
GET |
/api/v1/chats |
Get messages | Bearer | chats:read |
PUT |
/api/v1/chats/{id} |
Update message | Bearer | chats:update |
DELETE |
/api/v1/chats/{id} |
Delete message | Bearer | chats:delete |
POST |
/api/v1/chats/{id}/pin |
Pin message | Bearer | chats:update |
POST |
/api/v1/chats/{id}/unpin |
Unpin message | Bearer | chats:update |
POST |
/api/v1/chats/{id}/reactions |
Add reaction | Bearer | chats:update |
POST |
/api/v1/chats/read |
Mark as read | Bearer | chats:read |
RBAC
| Method | Endpoint | Description | Auth | Permission |
|---|---|---|---|---|
POST |
/api/v1/rbac/roles |
Create a role | Bearer | rbac:create |
GET |
/api/v1/rbac/roles |
List all roles | Bearer | rbac:read |
GET |
/api/v1/rbac/roles/{id} |
Get role by ID | Bearer | rbac:read |
PUT |
/api/v1/rbac/roles/{id} |
Update role | Bearer | rbac:update |
POST |
/api/v1/rbac/users/{user_id}/roles |
Assign role to user | Bearer | rbac:update |
WebSocket
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/api/v1/ws |
WebSocket connection | Bearer Token (query param or header) |
đ WebSocket API
Connection
Connect to ws://localhost:8080/api/v1/ws?token={your-token} or use Bearer token in Authorization header.
Message Types
Send Message
{
"type": "message",
"tenant_id": "tenant-id",
"sender_id": "user-id",
"data": {
"receiver_id": "receiver-id",
"message_body": "Hello!",
"message_type": "text"
},
"timestamp": "2024-11-19T10:29:07Z"
}
Typing Indicator
{
"type": "typing",
"tenant_id": "tenant-id",
"sender_id": "user-id",
"data": {
"receiver_id": "receiver-id",
"is_typing": true
},
"timestamp": "2024-11-19T10:29:07Z"
}
Read Receipt
{
"type": "read_receipt",
"tenant_id": "tenant-id",
"sender_id": "user-id",
"data": {
"chat_ids": ["msg-id-1", "msg-id-2"]
},
"timestamp": "2024-11-19T10:29:07Z"
}
đĄī¸ Permissions and RBAC
Default Permissions
Permissions follow the format: {resource}:{action}
Resources:
users- User managementgroups- Group managementchats- Chat/message operationsrbac- Role and permission management
Actions:
create- Create new resourcesread- Read/list resourcesupdate- Update existing resourcesdelete- Delete resources
Wildcard:
*- All actions (e.g.,users:*= all user permissions)
Creating Roles
Example: Admin Role
curl -X POST http://localhost:8080/api/v1/rbac/roles \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "X-Tenant-ID: your-tenant-id-here" \
-H "X-User-ID: admin-user-id-here" \
-d '{
"name": "Admin",
"description": "Full access to all resources",
"permissions": [
"users:*",
"groups:*",
"chats:*",
"rbac:*"
]
}'
đ¨ UI Components
Ready-to-use UI components for easy integration into your application. All components support WebSocket for real-time messaging and customizable theming.
1. Chat Window Component
A complete chat window with WebSocket integration, message history, typing indicators, and connection status.
Endpoint: GET /ui/chat-window
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tenant_id |
string | Yes | Tenant ID |
user_id |
string | No* | Current user ID (will show login form if not provided) |
token |
string | Yes | Authentication token |
receiver_id |
string | No* | Receiver User ID (for direct messages) |
group_id |
string | No* | Group ID (for group messages) |
primary_color |
string | No | Primary theme color (default: #4F46E5) |
secondary_color |
string | No | Secondary theme color (default: #7C3AED) |
*Either receiver_id or group_id must be provided.
Example - Direct Message:
<iframe
src="http://localhost:8080/ui/chat-window?tenant_id=xxx&user_id=yyy&token=zzz&receiver_id=aaa&primary_color=%234F46E5&secondary_color=%237C3AED"
width="100%"
height="700px"
style="border: none;">
</iframe>
Example - Group Chat:
<iframe
src="http://localhost:8080/ui/chat-window?tenant_id=xxx&user_id=yyy&token=zzz&group_id=ggg"
width="100%"
height="700px"
style="border: none;">
</iframe>
2. Roster Component
A contact and group list component with search functionality. Click on contacts or groups to open the chat window.
Endpoint: GET /ui/roster
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tenant_id |
string | Yes | Tenant ID |
user_id |
string | Yes | Current user ID |
token |
string | Yes | Authentication token |
primary_color |
string | No | Primary theme color (default: #4F46E5) |
secondary_color |
string | No | Secondary theme color (default: #7C3AED) |
Example:
<iframe
src="http://localhost:8080/ui/roster?tenant_id=xxx&user_id=yyy&token=zzz&primary_color=%23FF5733&secondary_color=%23FFC300"
width="400"
height="600"
style="border: 1px solid #ddd; border-radius: 8px;">
</iframe>
3. Participant List Component
Display all participants in a group with their names and emails.
Endpoint: GET /ui/participants
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tenant_id |
string | Yes | Tenant ID |
group_id |
string | Yes | Group ID |
token |
string | Yes | Authentication token |
primary_color |
string | No | Primary theme color (default: #4F46E5) |
secondary_color |
string | No | Secondary theme color (default: #7C3AED) |
Example:
<iframe
src="http://localhost:8080/ui/participants?tenant_id=xxx&group_id=ggg&token=zzz"
width="100%"
height="500px"
style="border: none;">
</iframe>
Demo Page
Test all UI components interactively:
http://localhost:8080/demo?api_key=YOUR_API_KEY
Or with custom colors:
http://localhost:8080/demo?api_key=YOUR_API_KEY&primary_color=%234F46E5&secondary_color=%237C3AED
- All components can be embedded as iframes
- Components support custom theming via URL parameters
- Chat window includes WebSocket for real-time messaging
- All components require authentication token
đĄ Examples
Complete Flow Example
# 1. Create tenant
TENANT_RESPONSE=$(curl -X POST http://localhost:8080/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{"name": "My Company"}')
TENANT_ID=$(echo $TENANT_RESPONSE | jq -r '.id')
API_KEY=$(echo $TENANT_RESPONSE | jq -r '.api_key')
# 2. Generate token
TOKEN_RESPONSE=$(curl -X POST http://localhost:8080/api/v1/tenant/$TENANT_ID/auth/token \
-H "X-API-Key: $API_KEY")
TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.token')
# 3. Create user
USER_RESPONSE=$(curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-ID: $TENANT_ID" \
-H "X-User-ID: admin-user-id" \
-d '{"name": "John Doe", "email": "john@example.com", "phone": "+1234567890"}')
USER_ID=$(echo $USER_RESPONSE | jq -r '.id')
# 4. Send message
curl -X POST http://localhost:8080/api/v1/chats \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-ID: $TENANT_ID" \
-H "X-User-ID: $USER_ID" \
-d '{
"receiver_id": "another-user-id",
"message_body": "Hello!",
"message_type": "text"
}'
âī¸ Configuration
Environment variables (see .env.example):
SERVER_PORT- Server port (default: 8080)MONGO_URI- MongoDB connection stringJWT_SECRET- Secret key for JWT tokensJWT_EXPIRY_HOURS- Token expiry in hours (default: 24)ENVIRONMENT- Environment (development/production)GOOGLE_CLIENT_ID- Google OAuth client ID (optional)GOOGLE_CLIENT_SECRET- Google OAuth client secret (optional)GITHUB_CLIENT_ID- GitHub OAuth client ID (optional)GITHUB_CLIENT_SECRET- GitHub OAuth client secret (optional)
â ī¸ Error Handling
The API returns standard HTTP status codes:
200- Success201- Created400- Bad Request401- Unauthorized403- Forbidden (Insufficient permissions)404- Not Found500- Internal Server Error
Error Response Format:
{
"error": "Error message description"
}