@postacksolutions/flux-relay-sdk
v1.2.0
Published
Official JavaScript/TypeScript SDK for Flux Relay - Real-time messaging platform
Maintainers
Readme
Flux Relay SDK
Official JavaScript/TypeScript SDK for Flux Relay - Real-time messaging platform.
Installation
npm install @postacksolutions/flux-relay-sdk
# or
yarn add @postacksolutions/flux-relay-sdk
# or
bun add @postacksolutions/flux-relay-sdkQuick Start
import { FluxRelay } from '@postacksolutions/flux-relay-sdk';
// Initialize the client
const client = new FluxRelay({
apiUrl: 'https://flux.postacksolutions.com',
serverId: 'YOUR_SERVER_ID',
apiKey: 'YOUR_API_KEY',
});
// Authenticate a user
const auth = await client.authenticateUser({
externalUserId: 'user_123', // Your app's user ID
username: 'john_doe',
metadata: {
email: '[email protected]',
},
});
// Store the access token
client.setAccessToken(auth.accessToken);
// Now you can use the SDK
const conversations = await client.getConversations();Configuration
Basic Configuration
const client = new FluxRelay({
apiUrl: 'https://flux.postacksolutions.com', // Required
serverId: 'YOUR_SERVER_ID', // Optional when using access tokens
apiKey: 'YOUR_API_KEY', // Optional when using access tokens
timeout: 30000, // Optional: Request timeout in ms (default: 30000)
enforceHttps: true, // Optional: Enforce HTTPS in production (default: true)
});Using Access Tokens
Once you have an access token (from authenticateUser), you can use it for all subsequent requests:
// After authentication
client.setAccessToken(auth.accessToken);
// Now serverId and apiKey are optional
// The SDK will use the access token for authenticationAPI Reference
Authentication
authenticateUser(params)
Authenticate or create a user. If the user doesn't exist, it will be created automatically.
const auth = await client.authenticateUser({
externalUserId: 'user_123', // Required: Your app's unique user ID
username: 'john_doe', // Required: Display name
metadata: { // Optional: Additional user data
email: '[email protected]',
phoneNumber: '+1234567890',
avatar: 'https://example.com/avatar.jpg',
},
});
// Returns:
// {
// userId: string;
// accessToken: string;
// refreshToken: string;
// user: {
// id: string;
// username: string;
// metadata?: Record<string, any>;
// };
// }Contacts
getContacts()
Get all contacts (users in the same project/server).
const contacts = await client.getContacts();
// Returns: Contact[]
// [
// {
// userId: string;
// username: string;
// externalUserId: string;
// metadata?: Record<string, any>;
// createdAt: string;
// },
// ...
// ]Conversations
getConversations()
List all conversations for the authenticated user.
const conversations = await client.getConversations();
// Returns: Conversation[]
// [
// {
// id: string;
// name?: string;
// isGroup: boolean;
// participantIds: string[];
// createdAt: string;
// updatedAt: string;
// lastMessage?: Message | null;
// unreadCount?: number;
// },
// ...
// ]createConversation(params)
Create a new conversation.
const conversation = await client.createConversation({
participantIds: ['user_456'], // Required: Array of user IDs
name: 'Chat with Jane', // Optional: Conversation name (for groups)
isGroup: false, // Optional: Whether it's a group chat (default: false)
});
// Returns: ConversationgetConversationDetails(conversationId)
Get details of a specific conversation.
const conversation = await client.getConversationDetails('conv_123');
// Returns: ConversationupdateConversationName(conversationId, name)
Update the name of a conversation (typically for group chats).
const conversation = await client.updateConversationName('conv_123', 'New Group Name');
// Returns: ConversationdeleteConversation(conversationId)
Delete a conversation.
await client.deleteConversation('conv_123');Messages
getMessages(conversationId, options?)
Get messages from a conversation.
const messages = await client.getMessages('conv_123', {
limit: 50, // Optional: Number of messages (1-100, default: 50)
before: '2024-01-01T00:00:00Z', // Optional: Get messages before this timestamp
});
// Returns: Message[]
// [
// {
// id: string;
// conversationId: string;
// senderId: string;
// content: string;
// type: string;
// attachments?: Array<{
// id: string;
// filename: string;
// mimeType: string;
// size: number;
// }>;
// createdAt: string;
// },
// ...
// ]sendMessage(conversationId, params)
Send a message to a conversation.
const message = await client.sendMessage('conv_123', {
content: 'Hello, world!', // Required: Message content
type: 'text', // Optional: Message type (default: 'text')
attachments: [ // Optional: File attachments
{
id: 'file_123',
filename: 'document.pdf',
mimeType: 'application/pdf',
size: 1024,
},
],
});
// Returns: MessageFile Uploads
uploadFile(file)
Upload a file and get a file ID for use in messages.
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const uploadResult = await client.uploadFile(file);
// Returns: { fileId: string; url: string }
// Use the fileId in message attachments
await client.sendMessage('conv_123', {
content: 'Check out this file!',
type: 'text',
attachments: [{
id: uploadResult.fileId,
filename: file.name,
mimeType: file.type,
size: file.size,
}],
});File Upload Limits:
- Maximum file size: 10MB
- Allowed types: Images, documents, videos, audio files
getFile(fileId)
Retrieve file data by file ID. Returns the file with base64-encoded data.
const file = await client.getFile('file_123');
// Returns:
// {
// id: string;
// filename: string;
// mimeType: string;
// size: number;
// data: string; // Base64 encoded
// uploadedAt: string;
// }
// Example: Download file
const file = await client.getFile('file_123');
const byteCharacters = atob(file.data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: file.mimeType });
// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = file.filename;
a.click();
URL.revokeObjectURL(url);Token Management
setAccessToken(token)
Set the access token manually (useful for token refresh or restoring sessions).
client.setAccessToken('your-access-token');getAccessToken()
Get the current access token.
const token = client.getAccessToken();
// Returns: string | null⚠️ Security Warning: Only use this for token refresh or secure server-side operations. Never expose tokens in client-side code, logs, or error messages.
clearAccessToken()
Clear the access token (useful for logout).
client.clearAccessToken();Error Handling
The SDK throws FluxRelayError for all errors. Always wrap SDK calls in try-catch blocks:
import { FluxRelay, FluxRelayError } from '@postacksolutions/flux-relay-sdk';
try {
const conversations = await client.getConversations();
} catch (error) {
if (error instanceof FluxRelayError) {
console.error('Flux Relay error:', error.message);
console.error('Status code:', error.statusCode);
console.error('Error code:', error.errorCode);
} else {
console.error('Unexpected error:', error);
}
}Common Error Codes
MISSING_API_URL- API URL is requiredMISSING_CREDENTIALS- Server ID and API Key are requiredINVALID_TOKEN- Invalid access token formatNOT_AUTHENTICATED- User is not authenticatedINVALID_ID- Invalid ID formatREQUEST_TIMEOUT- Request timed outHTTPS_REQUIRED- HTTPS is required in production
Real-time Updates with WebSocket
For real-time message delivery, use Socket.io alongside the SDK:
import { io } from 'socket.io-client';
// Connect to WebSocket
const socket = io('https://flux.postacksolutions.com', {
auth: {
token: auth.accessToken, // From authenticateUser
},
path: '/socket.io',
});
// Listen for new messages
socket.on('new_message', (message) => {
console.log('New message:', message);
// Update your UI
});
// Join a conversation room
socket.emit('join_conversation', {
conversationId: 'conv_123',
});
// Send message via WebSocket (optional, can also use REST API)
socket.emit('send_message', {
conversationId: 'conv_123',
content: 'Hello!',
type: 'text',
});Install Socket.io client:
npm install socket.io-clientTypeScript Support
The SDK is written in TypeScript and includes full type definitions:
import { FluxRelay, User, Conversation, Message, Contact } from '@postacksolutions/flux-relay-sdk';
const client: FluxRelay = new FluxRelay({ ... });
const user: User = auth.user;
const conversations: Conversation[] = await client.getConversations();Security Features
- ✅ HTTPS enforcement in production
- ✅ Input validation and sanitization
- ✅ Path injection prevention
- ✅ Request timeouts
- ✅ Secure token handling
- ✅ XSS prevention
Examples
Complete Integration Example
import { FluxRelay } from '@postacksolutions/flux-relay-sdk';
import { io } from 'socket.io-client';
// Initialize client
const client = new FluxRelay({
apiUrl: 'https://flux.postacksolutions.com',
serverId: 'YOUR_SERVER_ID',
apiKey: 'YOUR_API_KEY',
});
// Authenticate user
async function initializeMessaging(userId: string, username: string) {
// Authenticate
const auth = await client.authenticateUser({
externalUserId: userId,
username: username,
});
// Set access token
client.setAccessToken(auth.accessToken);
// Connect WebSocket
const socket = io('https://flux.postacksolutions.com', {
auth: { token: auth.accessToken },
path: '/socket.io',
});
// Load conversations
const conversations = await client.getConversations();
// Listen for new messages
socket.on('new_message', (message) => {
console.log('New message:', message);
});
return { client, socket, conversations };
}
// Usage
const { client, socket, conversations } = await initializeMessaging(
'user_123',
'john_doe'
);React Hook Example
import { useState, useEffect } from 'react';
import { FluxRelay } from '@postacksolutions/flux-relay-sdk';
function useFluxRelay(serverId: string, apiKey: string) {
const [client, setClient] = useState<FluxRelay | null>(null);
const [conversations, setConversations] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fluxClient = new FluxRelay({
apiUrl: 'https://flux.postacksolutions.com',
serverId,
apiKey,
});
setClient(fluxClient);
setLoading(false);
}, [serverId, apiKey]);
const authenticate = async (userId: string, username: string) => {
if (!client) return;
const auth = await client.authenticateUser({ externalUserId: userId, username });
client.setAccessToken(auth.accessToken);
const convs = await client.getConversations();
setConversations(convs);
return auth;
};
return { client, conversations, authenticate, loading };
}Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Node.js Support
- Node.js 16.0.0 or higher
Resources
License
MIT
Support
For support, email [email protected] or visit flux.postacksolutions.com.
