Get Started
Quickstart
Get started with the ProductFlo API and WebSockets
ProductFlo API Quickstart
This guide will help you get started with the ProductFlo API, focusing on the real-time WebSocket functionality. You’ll learn how to connect, authenticate, send messages, and handle responses.
Authentication
Before using the API, you need to authenticate:
Copy
// Get an authentication token
const response = await fetch('https://api.productflo.io/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'your-email@example.com',
password: 'your-password',
}),
});
const { token } = await response.json();
WebSocket Connection
Connect to the WebSocket API
Copy
// Connect with authentication token
const socket = new WebSocket(`wss://api.productflo.io/ws?token=${token}`);
// For anonymous connections (no authentication)
const socket = new WebSocket('wss://api.productflo.io/ws');
// Handle connection events
socket.onopen = () => {
console.log('Connected to ProductFlo WebSocket API');
};
socket.onclose = (event) => {
console.log('Disconnected from ProductFlo WebSocket API', event.code, event.reason);
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
Handle Messages
Copy
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
// Handle different message types
switch(message.type) {
case 'chat':
handleChatMessage(message);
break;
case 'system':
handleSystemMessage(message);
break;
case 'error':
handleErrorMessage(message);
break;
case 'presence':
handlePresenceUpdate(message);
break;
default:
console.log('Received message:', message);
}
};
function handleChatMessage(message) {
console.log(`${message.data.sender}: ${message.data.message}`);
}
function handleSystemMessage(message) {
console.log(`System: ${message.data.message}`);
}
function handleErrorMessage(message) {
console.error(`Error (${message.data.code}): ${message.data.message}`);
}
function handlePresenceUpdate(message) {
console.log(`User ${message.data.user_id} is now ${message.data.status}`);
}
Send Messages
Join a Room
Copy
socket.send(JSON.stringify({
type: 'join',
room_id: 'product-123'
}));
Send a Chat Message
Copy
socket.send(JSON.stringify({
type: 'chat',
room_id: 'product-123',
task: 'direct_chat',
data: {
message: 'Hello team!',
sender: 'user-456'
}
}));
Request AI-Generated Content
Copy
socket.send(JSON.stringify({
type: 'chat',
task: 'image_generation',
data: {
message: 'Generate a 3D model of a smartphone with a foldable display',
sender: 'user-456',
product_id: 'product-123'
}
}));
Advanced Usage
Room-Based Communication
ProductFlo uses rooms for efficient message routing:
Copy
// Join a room
socket.send(JSON.stringify({
type: 'join',
room_id: 'product-123'
}));
// Send a message to the room
socket.send(JSON.stringify({
type: 'chat',
room_id: 'product-123',
data: {
message: 'Let\'s discuss the new design',
sender: 'user-456'
}
}));
// Leave a room
socket.send(JSON.stringify({
type: 'leave',
room_id: 'product-123'
}));
Presence Updates
Track when users come online or go offline:
Copy
// Update your status
socket.send(JSON.stringify({
type: 'presence',
data: {
status: 'online', // 'online', 'away', 'busy', 'offline'
last_active: new Date().toISOString()
}
}));
Error Handling
Handle errors from the WebSocket API:
Copy
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'error') {
const { code, message: errorMessage, details } = message.data;
switch (code) {
case 'INVALID_FORMAT':
console.error('The message format is invalid:', errorMessage);
break;
case 'VALIDATION_ERROR':
console.error('Message validation failed:', details.errors);
break;
case 'PROCESSING_ERROR':
console.error('Server failed to process the message:', errorMessage);
break;
default:
console.error(`Error (${code}):`, errorMessage);
}
}
};
Framework-Specific Examples
Copy
import { useEffect, useState } from 'react';
function WebSocketComponent() {
const [socket, setSocket] = useState(null);
const [messages, setMessages] = useState([]);
useEffect(() => {
// Create WebSocket connection
const ws = new WebSocket('wss://api.productflo.io/ws');
ws.onopen = () => {
console.log('Connected to WebSocket');
setSocket(ws);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
setMessages((prev) => [...prev, message]);
};
ws.onclose = () => {
console.log('Disconnected from WebSocket');
};
// Clean up on unmount
return () => {
ws.close();
};
}, []);
const sendMessage = (text) => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'chat',
room_id: 'react-room',
data: {
message: text,
sender: 'react-user'
}
}));
}
};
return (
<div>
<h1>ProductFlo WebSocket Chat</h1>
<div>
{messages.map((msg, index) => (
<div key={index}>
{msg.data?.sender}: {msg.data?.message}
</div>
))}
</div>
<button onClick={() => sendMessage('Hello from React!')}>
Send Message
</button>
</div>
);
}
Copy
import { useEffect, useState } from 'react';
function WebSocketComponent() {
const [socket, setSocket] = useState(null);
const [messages, setMessages] = useState([]);
useEffect(() => {
// Create WebSocket connection
const ws = new WebSocket('wss://api.productflo.io/ws');
ws.onopen = () => {
console.log('Connected to WebSocket');
setSocket(ws);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
setMessages((prev) => [...prev, message]);
};
ws.onclose = () => {
console.log('Disconnected from WebSocket');
};
// Clean up on unmount
return () => {
ws.close();
};
}, []);
const sendMessage = (text) => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'chat',
room_id: 'react-room',
data: {
message: text,
sender: 'react-user'
}
}));
}
};
return (
<div>
<h1>ProductFlo WebSocket Chat</h1>
<div>
{messages.map((msg, index) => (
<div key={index}>
{msg.data?.sender}: {msg.data?.message}
</div>
))}
</div>
<button onClick={() => sendMessage('Hello from React!')}>
Send Message
</button>
</div>
);
}
Copy
<template>
<div>
<h1>ProductFlo WebSocket Chat</h1>
<div>
<div v-for="(msg, index) in messages" :key="index">
{{ msg.data?.sender }}: {{ msg.data?.message }}
</div>
</div>
<button @click="sendMessage('Hello from Vue!')">
Send Message
</button>
</div>
</template>
<script>
export default {
data() {
return {
socket: null,
messages: []
};
},
mounted() {
this.socket = new WebSocket('wss://api.productflo.io/ws');
this.socket.onopen = () => {
console.log('Connected to WebSocket');
};
this.socket.onmessage = (event) => {
const message = JSON.parse(event.data);
this.messages.push(message);
};
this.socket.onclose = () => {
console.log('Disconnected from WebSocket');
};
},
beforeUnmount() {
if (this.socket) {
this.socket.close();
}
},
methods: {
sendMessage(text) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({
type: 'chat',
room_id: 'vue-room',
data: {
message: text,
sender: 'vue-user'
}
}));
}
}
}
};
</script>
Copy
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-websocket',
template: `
<h1>ProductFlo WebSocket Chat</h1>
<div>
<div *ngFor="let msg of messages">
{{ msg.data?.sender }}: {{ msg.data?.message }}
</div>
</div>
<button (click)="sendMessage('Hello from Angular!')">
Send Message
</button>
`
})
export class WebSocketComponent implements OnInit, OnDestroy {
socket: WebSocket | null = null;
messages: any[] = [];
ngOnInit() {
this.socket = new WebSocket('wss://api.productflo.io/ws');
this.socket.onopen = () => {
console.log('Connected to WebSocket');
};
this.socket.onmessage = (event) => {
const message = JSON.parse(event.data);
this.messages.push(message);
};
this.socket.onclose = () => {
console.log('Disconnected from WebSocket');
};
}
ngOnDestroy() {
if (this.socket) {
this.socket.close();
}
}
sendMessage(text: string) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({
type: 'chat',
room_id: 'angular-room',
data: {
message: text,
sender: 'angular-user'
}
}));
}
}
}
Next Steps
- Explore the WebSocket API for more details on message types and endpoints
- Learn about AI communication for integrating AI features
- Check out the real-time communication architecture to understand the underlying technology
Assistant
Responses are generated using AI and may contain mistakes.