@budytalk/activity-server
A simplified content management server for social media features - handles posts, likes, comments, retweets, bookmarks, and timelines. Database initialization is handled automatically - just import and use!
🌟 Features
Core Content Management
- Posts: Text, image, video, and poll posts with rich metadata
- Reactions: Like, love, laugh, wow, sad, angry reactions with unlike functionality
- Comments: Nested comments with mentions, replies, and deletion
- Retweets: Simple retweets and retweets with comments, plus unretweet functionality
- Bookmarks: Save posts to organized collections with notes
- Timeline System: Personalized timelines based on following relationships
- Trending Algorithm: Discover popular content based on engagement
- Real-time Updates: WebSocket support for live updates
Key Benefits
- No Database Setup: Automatically connects to Neon PostgreSQL - no configuration needed!
- No User Management: Focuses only on content, works with your existing user system
- Simple Integration: Easy-to-use REST API and JavaScript SDK
- Real-time: WebSocket support for instant updates
- Scalable: Built-in PostgreSQL support for production use
- Lightweight: Minimal dependencies, focused functionality
- Production Ready: Built with TypeScript, comprehensive error handling
📦 Installation
npm install @budytalk/activity-server
🚀 Quick Start
Instant Setup (No Database Configuration!)
const { BudyTalkContent } = require('@budytalk/activity-server');
async function main() {
const budytalk = new BudyTalkContent();
await budytalk.start();
console.log('✅ Server running with PostgreSQL!');
const user = await budytalk.syncUserAccount({
userId: 'user_123',
username: 'alice',
displayName: 'Alice Johnson'
});
const post = await budytalk.createPost({
userId: user.userId,
content: 'Hello world! 🎉',
postType: 'text'
});
console.log('🎉 Ready to use!');
}
main().catch(console.error);
Custom Database (Optional)
const { BudyTalkContent } = require('@budytalk/activity-server');
const budytalk = new BudyTalkContent({
database: {
type: 'postgres',
url: 'your-database-url'
}
});
await budytalk.start();
📱 Complete Example
const { BudyTalkContent } = require('@budytalk/activity-server');
async function socialMediaExample() {
const budytalk = new BudyTalkContent();
await budytalk.start();
const alice = await budytalk.syncUserAccount({
userId: 'user_123',
username: 'alice',
displayName: 'Alice Johnson',
avatar: 'https://example.com/alice.jpg'
});
const bob = await budytalk.syncUserAccount({
userId: 'user_456',
username: 'bob',
displayName: 'Bob Smith'
});
await budytalk.followUser(bob.userId, alice.userId);
const textPost = await budytalk.createPost({
userId: alice.userId,
content: 'Hello everyone! 🎉',
postType: 'text',
hashtags: ['#hello', '#social'],
mentions: ['@bob']
});
const pollPost = await budytalk.createPost({
userId: alice.userId,
content: 'What\'s your favorite feature?',
postType: 'poll',
poll: {
question: 'What\'s your favorite feature?',
options: [
{ text: 'Timeline' },
{ text: 'Reactions' },
{ text: 'Comments' },
{ text: 'Polls' }
],
settings: {
allowMultipleChoices: false,
showResults: 'after_vote',
duration: 24
}
}
});
await budytalk.likePost(bob.userId, textPost.id);
await budytalk.commentOnPost({
userId: bob.userId,
postId: textPost.id,
content: 'Great post! 👏',
mentions: ['@alice']
});
if (pollPost.poll) {
const timelineOption = pollPost.poll.options.find(opt => opt.text === 'Timeline');
await budytalk.voteOnPoll({
userId: bob.userId,
pollId: pollPost.poll.id,
optionIds: [timelineOption.id]
});
}
await budytalk.bookmarkPost({
userId: bob.userId,
postId: textPost.id,
collectionName: 'Favorites',
notes: 'Great inspiration!'
});
const timeline = await budytalk.getTimeline(bob.userId);
console.log(`Bob's timeline: ${timeline.length} posts`);
const trending = await budytalk.getTrendingPosts(10, 24);
console.log(`Trending: ${trending.length} posts`);
}
socialMediaExample().catch(console.error);
🌐 REST API
The server automatically provides a complete REST API:
Posts
POST /api/content/posts
{
"userId": "user_123",
"content": "Hello world!",
"postType": "text",
"hashtags": ["#hello"]
}
POST /api/content/posts
{
"userId": "user_123",
"content": "What's your favorite?",
"postType": "poll",
"poll": {
"question": "What's your favorite?",
"options": [{"text": "Option 1"}, {"text": "Option 2"}]
}
}
Reactions
POST /api/content/reactions
{
"userId": "user_456",
"type": "like",
"postId": "post_123"
}
DELETE /api/content/reactions/{reactionId}
{
"userId": "user_456"
}
POST /api/content/comments
{
"userId": "user_456",
"postId": "post_123",
"content": "Great post!",
"mentions": ["@alice"]
}
DELETE /api/content/comments/{commentId}
{
"userId": "user_456"
}
Bookmarks
POST /api/content/bookmarks
{
"userId": "user_456",
"postId": "post_123",
"collectionName": "Favorites",
"notes": "Great inspiration"
}
GET /api/content/users/{userId}/bookmarks?collection=Favorites
Timelines
GET /api/content/users/{userId}/timeline?limit=20
GET /api/content/users/{userId}/feed?limit=20
GET /api/content/trending?limit=20&timeframe=24
🔌 Real-time WebSocket
const io = require('socket.io-client');
const socket = io('http://localhost:3000', {
query: { userId: 'user_123' }
});
socket.on('new-post', (post) => {
console.log('New post:', post);
});
socket.on('new-reaction', (reaction) => {
console.log('New reaction:', reaction);
});
socket.on('new-comment', (comment) => {
console.log('New comment:', comment);
});
socket.emit('join-topic', 'javascript');
socket.on('new-post-in-topic', (data) => {
console.log(`New #${data.topic} post:`, data.post);
});
⚙️ Configuration (Optional)
const budytalk = new BudyTalkContent({
port: 3000,
database: {
type: 'postgres',
url: 'your-custom-database-url'
},
websocket: {
enabled: true,
cors: {
origin: ['http://localhost:3000'],
credentials: true
}
},
cors: {
origin: ['http://localhost:3000'],
credentials: true
},
logging: {
level: 'info',
format: 'simple'
}
});
🧪 Testing
Quick Test
node -e "
const { BudyTalkContent } = require('@budytalk/activity-server');
const budytalk = new BudyTalkContent();
budytalk.start().then(() => console.log('✅ Server running!'));
"
curl -X POST http://localhost:3000/api/content/users \
-H "Content-Type: application/json" \
-d '{"userId":"test","username":"test","displayName":"Test User"}'
Run Examples
npm run test:simple
npm run test:postgres
npm run test:api
npm run test:bookmarks
🏗️ Integration with Your App
1. Sync User Accounts
async function onUserRegistered(user) {
await budytalk.syncUserAccount({
userId: user.id,
username: user.username,
displayName: user.displayName,
avatar: user.avatar
});
}
2. Frontend Integration
import { useState, useEffect } from 'react';
import io from 'socket.io-client';
function Timeline({ userId }) {
const [posts, setPosts] = useState([]);
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io('http://localhost:3000', {
query: { userId }
});
newSocket.on('new-post', (post) => {
setPosts(prev => [post, ...prev]);
});
newSocket.on('new-reaction', (reaction) => {
setPosts(prev => prev.map(post =>
post.id === reaction.postId
? { ...post, reactionCounts: { ...post.reactionCounts, [reaction.type]: (post.reactionCounts[reaction.type] || 0) + 1 } }
: post
));
});
setSocket(newSocket);
fetch(`/api/content/users/${userId}/timeline`)
.then(res => res.json())
.then(setPosts);
return () => newSocket.close();
}, [userId]);
const handleLike = async (postId) => {
await fetch('/api/content/reactions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId,
type: 'like',
postId
})
});
};
return (
<div>
{posts.map(post => (
<PostComponent
key={post.id}
post={post}
onLike={() => handleLike(post.id)}
/>
))}
</div>
);
}
📊 Database Schema
The package automatically creates these tables in PostgreSQL:
- user_accounts: Synced user information
- posts: All posts with metadata
- reactions: Likes, loves, etc.
- comments: Comments and replies
- bookmarks: User bookmarks with collections
- polls: Poll questions and votes
- follows: Following relationships
- timeline_entries: Personalized timelines
🚀 Production Deployment
Docker
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "initialize-neon.js"]
Environment Variables (Optional)
PORT=3000
LOG_LEVEL=info
CORS_ORIGIN=https://yourapp.com
WEBSOCKET_ENABLED=true
🎯 Why Choose BudyTalkContent?
✅ Zero Setup: No database configuration required - works out of the box
✅ Focused: Only handles content, not user management
✅ Simple: Easy REST API and JavaScript SDK
✅ Real-time: WebSocket support for live updates
✅ Scalable: Built-in PostgreSQL for production use
✅ Feature-rich: Posts, reactions, comments, retweets, bookmarks, polls
✅ Production-ready: TypeScript, error handling, logging
✅ Flexible: Works with any user management system
✅ Complete CRUD: Full create, read, update, delete operations
✅ Automatic: Database tables created automatically
Perfect for adding social features to existing applications without any database setup complexity!
📄 License
MIT License - see LICENSE file for details
Ready to add powerful social features to your app? Get started with BudyTalkContent today! 🚀
No Database Setup Required!
Just install, import, and start using - the database connection and table creation is handled automatically by the package. Perfect for rapid prototyping and production use!