Skip to content

Status: ✅ Implemented (Phase 2) Last Updated: November 28, 2025

Overview

TendSocial's social media publishing feature enables users to create, schedule, and publish content across multiple social platforms from a single interface. The system handles OAuth authentication, token management, media uploads, and provides detailed analytics.

Supported Platforms & Capabilities

PlatformCapabilitiesNotes
Facebook PagesPublish, Schedule, Comments, Messages, Analytics, First CommentPages only, no personal profiles
Instagram BusinessPublish, Schedule, Comments, Stories (Reminder), Analytics, ReelsBusiness accounts only
LinkedIn PagesPublish, Schedule, Comments, AnalyticsCompany and Personal Pages
Twitter / XPublish, Schedule, Comments, Analytics, Threads
YouTubePublish, Schedule, Comments, Analytics, Shorts
TikTok BusinessPublish, AnalyticsBusiness accounts only
PinterestPublish, Schedule, Analytics, Boards
Google BusinessPublish, Reviews, Analytics
ThreadsPublish, Comments
BlueskyPublish, Comments
MastodonPublish, Comments
RedditPublish, Comments, Subreddits

Architecture

Core Components

┌──────────────────────────────────────────────────────────┐
│                    Frontend (React App)                   │
│  - Platform authentication flows                          │
│  - Post composition interface                             │
│  - Scheduling UI                                          │
└────────────────┬──────────────────────────────────────────┘
                 │ HTTP/REST
┌────────────────▼──────────────────────────────────────────┐
│              Fastify API (Backend)                         │
├──────────────────────────────────────────────────────────┤
│  Routes:                                                  │
│  - POST /api/social/posts                                │
│  - GET  /api/social/accounts                             │
│  - DELETE /api/social/accounts/{id}                      │
└────────────────┬──────────────────────────────────────────┘

    ┌────────────┼────────────┐
    │            │            │
    ▼            ▼            ▼
┌─────────┐ ┌──────────┐ ┌──────────┐
│Platform │ │  Token   │ │Analytics │
│Services │ │ Refresh  │ │ Service  │
│(4x)     │ │ Worker   │ │          │
└─────────┘ └──────────┘ └──────────┘

    └────────────┬────────────────────────────┐
                 │                            │
                 ▼                            ▼
        ┌─────────────────┐        ┌──────────────────┐
        │ Prisma ORM /DB  │        │ Platform APIs    │
        │ (OAuth tokens,  │        │ (LinkedIn, X,    │
        │  posts, logs)   │        │  FB, IG)         │
        └─────────────────┘        └──────────────────┘

Database Schema

UserSocialAccount

Stores OAuth credentials and connection details for each platform.

prisma
model UserSocialAccount {
  id           String   @id @default(uuid())
  userId       String
  platform     Platform  // LINKEDIN, TWITTER, INSTAGRAM, FACEBOOK
  profileType  String   @default("personal") // "personal" or "business"

  accessToken  String   @db.Text  // Encrypted
  refreshToken String?  @db.Text  // Encrypted
  expiresAt    DateTime?

  scopes       String[]  // Granted OAuth scopes
  metadata     Json?     // Platform-specific data

  isActive     Boolean  @default(true)
  lastUsedAt   DateTime?
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt

  posts        CompanyPost[]

  @@unique([userId, platform, profileType])
}

CompanyPost

Stores social media posts with publish tracking.

prisma
model CompanyPost {
  id              String   @id @default(uuid())
  companyId       String
  userId          String
  platform        String
  content         String   @db.Text

  published       Boolean  @default(false)
  remoteId        String?  // Platform's post ID
  remoteUrl       String?  // Public URL
  publishedAt     DateTime?

  socialAccountId String?
  socialAccount   UserSocialAccount? @relation(...)

  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

Features

OAuth Authentication

Each platform requires specific OAuth scopes:

PlatformRequired Scopes
LinkedInw_member_social, r_liteprofile
Twittertweet.write, users.read
Instagraminstagram_basic, instagram_content_publish
Facebookpages_manage_posts, pages_read_engagement

Flow:

  1. User clicks "Connect [Platform]"
  2. Redirect to platform OAuth page
  3. User grants permissions
  4. Platform redirects to callback URL with auth code
  5. Exchange code for access/refresh tokens
  6. Store encrypted tokens in database

Token Management

Automatic Token Refresh:

  • Background worker checks token expiration every 6 hours
  • Refreshes tokens within 7 days of expiration
  • Logs refresh attempts and failures
  • Notifies user if manual re-authentication required

Security:

  • Tokens encrypted at rest using AES-256
  • Decrypted in-memory only for API calls
  • Never logged or exposed in responses

Post Creation & Publishing

Direct Publishing:

User creates post → Validate content → Call platform API → Store result

Scheduled Publishing:

User schedules post → Create ScheduledPost → Cloud Tasks triggers at time → Publish → Update status

Media Handling:

  • Images uploaded to platform's media library
  • Videos uploaded with platform-specific requirements
  • Media validated for format, size, dimensions

Error Handling

Standardized error responses across all platforms:

typescript
interface PlatformError {
  code: string;            // RATE_LIMITED, AUTH_FAILURE, etc.
  message: string;         // User-friendly message
  retryable: boolean;      // Should auto-retry?
  requiresUserAction?: boolean;  // Needs re-auth/config?
}

Retry Strategy:

  • Transient errors (rate limit, timeout): Exponential backoff
  • Permanent errors (invalid auth, scope issues): Notify user, don't retry
  • Max retries: 3 attempts per post per platform

API Reference

POST /api/social/posts

Create and publish a social media post.

Request:

json
{
  "content": "Check out our latest blog post!",
  "platforms": ["linkedin", "twitter"],
  "mediaUrls": ["https://cdn.example.com/image.png"],
  "scheduledAt": "2025-12-01T10:00:00Z" // Optional
}

Response:

json
{
  "posts": [
    {
      "platform": "linkedin",
      "status": "published",
      "remoteId": "urn:li:share:...",
      "remoteUrl": "https://linkedin.com/feed/update/..."
    },
    {
      "platform": "twitter",
      "status": "published",
      "remoteId": "1234567890",
      "remoteUrl": "https://twitter.com/user/status/1234567890"
    }
  ]
}

GET /api/social/accounts

List all connected social accounts.

Response:

json
{
  "accounts": [
    {
      "id": "uuid",
      "platform": "linkedin",
      "profileType": "personal",
      "isActive": true,
      "lastUsedAt": "2025-11-28T12:00:00Z"
    }
  ]
}

DELETE /api/social/accounts/

Disconnect a social account.

Response:

json
{
  "success": true
}

Analytics Integration

Social post metrics are stored in the unified CompanyContentMetrics model, enabling cross-platform comparison and trend analysis.

Tracked Metrics:

  • Impressions
  • Reach
  • Engagement (likes, comments, shares)
  • Clicks
  • Engagement rate

Sync Schedule:

  • New posts (<24h): Every 2 hours
  • Active posts (1-7 days): Every 6 hours
  • Older posts (7-30 days): Daily
  • Archive (>30 days): Weekly

See Analytics Foundation for details.

Future Enhancements

Phase 2 (Planned):

  • Advanced media handling (video transcoding, carousel posts)
  • Platform-specific analytics (beyond basic metrics)

Phase 3 (Under Consideration):

  • Multi-image carousel posts
  • Thread/story support
  • A/B testing
  • Best time to post recommendations

TendSocial Documentation