ws://api.qsocial.net/ws/posts/views/wss://api.qsocial.net/ws/posts/views/
Authentication is handled via JWT token in the WebSocket connection. Include the token in the connection URL:
ws://api.qsocial.net/ws/posts/views/?token=YOUR_JWT_TOKEN
Send this event when a user views a post.
{
"type": "view_post",
"post_id": 123
}
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Must be "view_post" |
post_id |
integer | Yes | ID of the post being viewed |
"recorded": false and a message indicating the view was not recorded.
Sent immediately after successful WebSocket connection.
{
"type": "connection_success",
"message": "Connected to post view tracking",
"user_id": 456
}
Sent after successfully processing a view event.
{
"type": "view_recorded",
"post_id": 123,
"recorded": true,
"message": "View recorded successfully"
}
Sent when user views their own post (not recorded).
{
"type": "view_recorded",
"post_id": 123,
"recorded": false,
"message": "View not recorded for own posts"
}
Sent when an error occurs.
{
"type": "error",
"message": "Error message here"
}
View recording is handled asynchronously using Celery tasks. This means:
F() expressions for thread-safe view_count incrementsThe view_count field on the Post model is automatically updated when views are recorded.
This field is returned in all post-related API endpoints.
// Connect to WebSocket
final token = await getAuthToken(); // Get JWT token
final wsUrl = 'wss://api.qsocial.net/ws/posts/views/?token=$token';
final channel = IOWebSocketChannel.connect(Uri.parse(wsUrl));
// Listen for messages
channel.stream.listen(
(message) {
final data = jsonDecode(message);
if (data['type'] == 'connection_success') {
print('Connected to post view tracking');
} else if (data['type'] == 'view_recorded') {
print('View recorded: ${data['post_id']}');
}
},
onError: (error) => print('WebSocket error: $error'),
);
// Send view event when user views a post
void recordPostView(int postId) {
channel.sink.add(jsonEncode({
'type': 'view_post',
'post_id': postId,
}));
}
// Using react-native-websocket or similar library
import WebSocket from 'react-native-websocket';
const token = await getAuthToken();
const ws = new WebSocket(`wss://api.qsocial.net/ws/posts/views/?token=${token}`);
ws.onopen = () => {
console.log('Connected to post view tracking');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'view_recorded') {
console.log('View recorded:', data.post_id);
}
};
// Send view event
const recordPostView = (postId) => {
ws.send(JSON.stringify({
type: 'view_post',
post_id: postId,
}));
};
All post-related endpoints return the view_count field:
GET /api/posts/ - List all postsGET /api/posts/{post_id} - Get post detailsGET /api/posts/users/{user_id} - Get user's postsGET /api/posts/liked/ - Get liked postsGET /api/posts/commented/ - Get commented postsGET /api/posts/bookmarks - Get bookmarked posts{
"id": 123,
"author": { ... },
"content": "Post content here",
"like_count": 10,
"comment_count": 5,
"view_count": 150, â View count
"created_at": "2024-11-30T10:00:00Z"
}
| Code | Description |
|---|---|
| 4001 | Unauthorized - User not authenticated |
| 4003 | Forbidden - Post not accessible |
| 1011 | Internal Server Error |