JSPM

@budytalk/activity-server

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 7
  • Score
    100M100P100Q47518F
  • License MIT

NPM SDK suite for activity feeds, messaging, and notifications - similar to GetStream but built for Node.js applications with full social media features

Package Exports

  • @budytalk/activity-server
  • @budytalk/activity-server/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@budytalk/activity-server) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@budytalk/activity-server

A comprehensive NPM SDK suite for activity feeds, messaging, and notifications - similar to GetStream but built for Node.js applications with full social media features.

🌟 Features

Core Features

  • Activity Feeds: Flat, aggregated, and notification feeds with real-time updates
  • Social Features: Posts, reactions, comments, shares, bookmarks, polls
  • Timeline System: Personalized timelines with automatic following notifications
  • Messaging: 1-on-1 and group chat with threads, media support, and reactions
  • Real-time Communication: WebSocket support for instant messaging and live updates
  • Notifications: Push notifications, email alerts, and in-app notifications
  • Authentication: JWT-based authentication with role-based permissions
  • Multi-tenant: Workspace and team support for enterprise applications

Social Media Features

  • Posts: Text, image, video, audio, poll, and link posts
  • Reactions: Like, love, laugh, wow, sad, angry, and custom reactions
  • Comments: Nested comments with reactions and media support
  • Shares: Retweets, quote tweets, and direct shares
  • Bookmarks: Save posts to collections
  • Polls: Create polls with multiple options and voting
  • Following: Follow/unfollow users with automatic timeline updates
  • Timeline Notifications: Real-time notifications when followed users post
  • Media: Image, video, audio, and document attachments
  • Hashtags & Mentions: Tag content and mention users
  • Privacy: Public, friends-only, and private posts

šŸ“¦ Installation

npm install @budytalk/activity-server

šŸš€ Quick Start

Basic Server Setup

import { createServer } from '@budytalk/activity-server';

async function main() {
  const server = await createServer({
    port: 3000,
    jwtSecret: 'your-secret-key',
    database: {
      type: 'sqlite',
      url: './data/app.db'
    }
  });
  
  await server.start();
  console.log('Server running on http://localhost:3000');
}

main().catch(console.error);

GetStream-like API Usage

import { connect } from '@budytalk/activity-server';

// Initialize client
const client = connect('your-api-key', 'your-api-secret');

// Create user token
const userToken = client.createUserToken('chris');

// Get user feed
const chris = client.feed('user', 'chris', userToken);

// Create a post
await chris.addActivity({
  actor: 'chris',
  verb: 'posted',
  object: 'post:1',
  content: 'Beautiful bird!',
  postType: 'image',
  media: [{
    type: 'image',
    url: 'https://example.com/bird.jpg',
    filename: 'bird.jpg',
    size: 1024000
  }],
  hashtags: ['#nature', '#birds'],
  mentions: ['@alice']
});

// Add reactions
await client.reactions.add('like', 'post:1', {}, { userId: 'alice' });

// Create following relationship
const jack = client.feed('timeline', 'jack');
await jack.follow('user', 'chris');

// Read timeline with reactions
const results = await jack.get({ 
  limit: 10,
  reactions: { 
    own: true, 
    counts: true, 
    recent: true 
  }
});

🧪 Testing the Server

1. Using the CLI Tools

# Create users
npx budytalk create-user --username alice --email alice@example.com --password password123 --display-name "Alice Johnson"
npx budytalk create-user --username bob --email bob@example.com --password password123 --display-name "Bob Smith"
npx budytalk create-user --username charlie --email charlie@example.com --password password123 --display-name "Charlie Brown"

# Generate JWT tokens
npx budytalk generate-token --email alice@example.com
npx budytalk generate-token --email bob@example.com

# Seed database with sample data
npx budytalk seed-data --users 10 --channels 5 --messages 100

# Start development server
npx budytalk dev-server --port 3001

2. API Testing Examples

Authentication

# Register a new user
curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "email": "test@example.com",
    "password": "password123",
    "displayName": "Test User"
  }'

# Login
curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "password123"
  }'

Social Features Testing

# Create a text post
curl -X POST http://localhost:3000/api/social/posts \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hello world! This is my first post šŸŽ‰",
    "postType": "text",
    "hashtags": ["#hello", "#firstpost"],
    "mentions": ["@bob"],
    "privacy": "public"
  }'

# Create a poll
curl -X POST http://localhost:3000/api/social/posts \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "What is your favorite programming language?",
    "postType": "poll",
    "poll": {
      "question": "What is your favorite programming language?",
      "options": [
        {"text": "JavaScript"},
        {"text": "Python"},
        {"text": "TypeScript"},
        {"text": "Go"}
      ],
      "settings": {
        "allowMultipleChoices": false,
        "showResults": "after_vote",
        "duration": 24
      }
    }
  }'

# Follow a user
curl -X POST http://localhost:3000/api/social/users/USER_ID/follow \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

# Add a reaction
curl -X POST http://localhost:3000/api/social/reactions \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "like",
    "activityId": "POST_ID"
  }'

# Add a comment
curl -X POST http://localhost:3000/api/social/activities/ACTIVITY_ID/comments \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Great post! I totally agree šŸ‘",
    "mentions": ["@alice"]
  }'

# Get personalized timeline
curl -X GET "http://localhost:3000/api/social/timeline?limit=20" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

# Get trending posts
curl -X GET "http://localhost:3000/api/social/trending?limit=10&timeframe=24" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

3. WebSocket Testing

import io from 'socket.io-client';

const socket = io('http://localhost:3000', {
  auth: {
    token: 'your-jwt-token'
  }
});

// Listen for timeline notifications
socket.on('notification', (notification) => {
  console.log('New notification:', notification);
});

// Listen for new activities
socket.on('new-activity', (activity) => {
  console.log('New activity:', activity);
});

// Join a channel
socket.emit('join-channel', 'channel-123');

// Listen for new messages
socket.on('new-message', (message) => {
  console.log('New message:', message);
});

4. Complete Testing Example

// examples/complete-test.js
const { createServer } = require('@budytalk/activity-server');

async function completeTest() {
  // Start server
  const server = await createServer({
    port: 3000,
    jwtSecret: 'test-secret',
    database: { type: 'sqlite', url: './test.db' }
  });
  
  await server.start();
  
  const { userService, socialService, timelineService } = server.getServices();
  
  // Create test users
  const alice = await userService.createUser({
    username: 'alice',
    email: 'alice@test.com',
    password: 'password123',
    displayName: 'Alice Johnson',
    workspaceId: 'test'
  });
  
  const bob = await userService.createUser({
    username: 'bob',
    email: 'bob@test.com',
    password: 'password123',
    displayName: 'Bob Smith',
    workspaceId: 'test'
  });
  
  console.log('āœ… Users created');
  
  // Bob follows Alice
  await socialService.followUser(bob.id, alice.id);
  console.log('āœ… Bob followed Alice');
  
  // Alice creates a post
  const post = await socialService.createPost({
    userId: alice.id,
    content: 'Hello everyone! Testing the timeline system šŸš€',
    postType: 'text',
    workspaceId: 'test',
    hashtags: ['#test', '#timeline'],
    mentions: ['@bob']
  });
  
  console.log('āœ… Alice created a post');
  
  // Wait for timeline processing
  await new Promise(resolve => setTimeout(resolve, 1000));
  
  // Check Bob's timeline
  const bobTimeline = await timelineService.getUserTimeline(bob.id, 10, 0);
  console.log(`āœ… Bob's timeline has ${bobTimeline.length} posts`);
  
  // Bob reacts to Alice's post
  await socialService.addReaction({
    userId: bob.id,
    type: 'like',
    activityId: post.id
  });
  
  console.log('āœ… Bob liked Alice\'s post');
  
  // Bob comments on Alice's post
  await socialService.addComment({
    userId: bob.id,
    activityId: post.id,
    content: 'Great post, Alice! The timeline system works perfectly! šŸ‘',
    mentions: ['@alice']
  });
  
  console.log('āœ… Bob commented on Alice\'s post');
  
  // Create a poll
  const pollPost = await socialService.createPost({
    userId: alice.id,
    content: 'Quick poll: What\'s your favorite feature?',
    postType: 'poll',
    workspaceId: 'test',
    poll: {
      question: 'What\'s your favorite feature?',
      options: [
        { text: 'Timeline System' },
        { text: 'Real-time Notifications' },
        { text: 'Reactions' },
        { text: 'Comments' }
      ],
      settings: {
        allowMultipleChoices: false,
        showResults: 'after_vote',
        duration: 24
      }
    }
  });
  
  console.log('āœ… Alice created a poll');
  
  // Bob votes on the poll
  const poll = await socialService.getPollById(pollPost.poll.id);
  const timelineOption = poll.options.find(opt => opt.text === 'Timeline System');
  
  await socialService.votePoll({
    userId: bob.id,
    pollId: poll.id,
    optionIds: [timelineOption.id]
  });
  
  console.log('āœ… Bob voted on Alice\'s poll');
  
  // Get final timeline
  const finalTimeline = await timelineService.getUserTimeline(bob.id, 20, 0);
  console.log(`šŸ“± Bob's final timeline: ${finalTimeline.length} activities`);
  
  // Get trending posts
  const trending = await timelineService.getTrendingPosts('test', 5, 24);
  console.log(`šŸ”„ Trending posts: ${trending.length} posts`);
  
  console.log('\nšŸŽ‰ Complete test finished successfully!');
  console.log('šŸŽÆ Features tested:');
  console.log('   āœ“ User creation and authentication');
  console.log('   āœ“ Following system');
  console.log('   āœ“ Post creation and timeline updates');
  console.log('   āœ“ Reactions and notifications');
  console.log('   āœ“ Comments and mentions');
  console.log('   āœ“ Polls and voting');
  console.log('   āœ“ Trending content');
  
  await server.stop();
}

completeTest().catch(console.error);

šŸ“š Advanced Usage

Custom Service Integration

import { ActivityServer } from '@budytalk/activity-server';

const server = new ActivityServer(config);
await server.initialize();

const { 
  userService, 
  feedService, 
  messageService, 
  socialService,
  timelineService 
} = server.getServices();

// Create a post programmatically
const post = await socialService.createPost({
  userId: 'user-123',
  content: 'Hello from the API!',
  postType: 'text',
  workspaceId: 'workspace-123'
});

// Add a reaction
const reaction = await socialService.addReaction({
  userId: 'user-456',
  type: 'like',
  activityId: post.id
});

// Follow a user (automatically updates timelines)
await socialService.followUser('user-123', 'user-456');

// Get user's personalized timeline
const timeline = await timelineService.getUserTimeline('user-123', 20, 0);

Stream-like Client Usage

const client = server.getStreamClient();
client.connect('api-key', 'api-secret');

// Create user feed
const userFeed = client.feed('user', 'john');

// Add activity
await userFeed.addActivity({
  actor: 'john',
  verb: 'posted',
  object: 'photo:1',
  content: 'Check out this photo!',
  media: [{ type: 'image', url: 'photo.jpg' }]
});

// Get timeline
const timeline = client.feed('timeline', 'john');
const activities = await timeline.get({ limit: 20 });

šŸ—ļø Creating an NPM Package

1. Package Structure

your-app/
ā”œā”€ā”€ package.json
ā”œā”€ā”€ src/
│   └── index.js
ā”œā”€ā”€ README.md
└── .gitignore

2. Package.json Setup

{
  "name": "your-social-app",
  "version": "1.0.0",
  "description": "Social media app powered by BudyTalk Activity Server",
  "main": "src/index.js",
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "test": "node test/complete-test.js"
  },
  "dependencies": {
    "@budytalk/activity-server": "^1.0.0"
  },
  "devDependencies": {
    "nodemon": "^3.0.0"
  },
  "keywords": ["social", "feeds", "activity", "timeline", "budytalk"],
  "author": "Your Name",
  "license": "MIT"
}

3. Main Application File

// src/index.js
const { createServer } = require('@budytalk/activity-server');

async function startApp() {
  const server = await createServer({
    port: process.env.PORT || 3000,
    jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
    database: {
      type: 'sqlite',
      url: process.env.DATABASE_URL || './data/app.db'
    },
    websocket: {
      enabled: true
    }
  });
  
  await server.start();
  console.log(`šŸš€ Social app running on port ${server.config.port}`);
}

startApp().catch(console.error);

4. Publishing to NPM

# Initialize your package
npm init

# Install BudyTalk Activity Server
npm install @budytalk/activity-server

# Test your package
npm test

# Login to NPM
npm login

# Publish your package
npm publish

5. Environment Variables

# .env
PORT=3000
JWT_SECRET=your-super-secret-jwt-key
DATABASE_URL=./data/app.db
REDIS_URL=redis://localhost:6379
REDIS_ENABLED=false
WEBSOCKET_ENABLED=true
LOG_LEVEL=info

🐳 Docker Deployment

# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=./data/app.db
      - JWT_SECRET=your-secret-key
    volumes:
      - ./data:/app/data

šŸ“– API Documentation

Timeline Endpoints

  • GET /api/social/timeline - Get personalized timeline
  • GET /api/social/feed - Get user's own posts
  • GET /api/social/trending - Get trending posts

Social Endpoints

  • POST /api/social/posts - Create post
  • POST /api/social/reactions - Add reaction
  • POST /api/social/activities/:id/comments - Add comment
  • POST /api/social/activities/:id/share - Share post
  • POST /api/social/users/:id/follow - Follow user
  • DELETE /api/social/users/:id/follow - Unfollow user

Real-time Events

  • notification - New notification received
  • new-activity - New activity in timeline
  • new-message - New chat message
  • reaction-added - New reaction added
  • user-typing - User typing indicator

šŸ”§ Configuration Options

interface Config {
  port: number;
  jwtSecret: string;
  database: {
    type: 'sqlite' | 'postgres' | 'mysql';
    url: string;
  };
  websocket: {
    enabled: boolean;
  };
  notifications: {
    push: { enabled: boolean };
    email: { enabled: boolean };
  };
  logging: {
    level: 'error' | 'warn' | 'info' | 'debug';
  };
}

šŸ¤ Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Make changes and add tests
  4. Run tests: npm test
  5. Commit changes: git commit -am 'Add new feature'
  6. Push to branch: git push origin feature/new-feature
  7. Submit a pull request

šŸ“„ License

MIT License - see LICENSE file for details

šŸ†˜ Support


Ready to build the next great social platform? Get started with BudyTalk Activity Server today! šŸš€