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

Multi-tenancy
Isolated data per tenant
Real-time Messaging
WebSocket support for instant messaging
Role-Based Access Control
Fine-grained permissions
User Management
Complete CRUD operations
Group Chats
Create and manage group conversations
Message Features
Edit, delete, pin, reactions, read receipts
File Attachments
Support for file attachments in messages
OAuth Support
Google and GitHub OAuth integration
RESTful API
Clean REST API design
Swagger Documentation
Interactive API documentation

🚀 Quick Start

Prerequisites

Installation

  1. Clone the repository:
    git clone <repository-url>
    cd wonksknow-chat
  2. Install dependencies:
    go mod download
  3. Configure environment variables:
    cp env.example .env
    # Edit .env with your configuration
  4. 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."
}
âš ī¸ IMPORTANT: Save both the id and api_key securely. You'll need:
  • id (Tenant ID) for all authenticated requests
  • api_key to 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
}
â„šī¸ Note: Tokens expire after 24 hours. You'll need to regenerate them periodically.

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 token
  • X-Tenant-ID: {tenant_id} - Your tenant ID
  • X-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:

🔐 Authentication

API Key Authentication

Used for generating tenant authentication tokens.

Header:

X-API-Key: your-api-key-here

Used in:

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:

🔗 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:

Actions:

Wildcard:

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
💡 Integration Tips:
  • 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):

âš ī¸ Error Handling

The API returns standard HTTP status codes:

Error Response Format:

{
  "error": "Error message description"
}