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
| Platform | Capabilities | Notes |
|---|---|---|
| Facebook Pages | Publish, Schedule, Comments, Messages, Analytics, First Comment | Pages only, no personal profiles |
| Instagram Business | Publish, Schedule, Comments, Stories (Reminder), Analytics, Reels | Business accounts only |
| LinkedIn Pages | Publish, Schedule, Comments, Analytics | Company and Personal Pages |
| Twitter / X | Publish, Schedule, Comments, Analytics, Threads | |
| YouTube | Publish, Schedule, Comments, Analytics, Shorts | |
| TikTok Business | Publish, Analytics | Business accounts only |
| Publish, Schedule, Analytics, Boards | ||
| Google Business | Publish, Reviews, Analytics | |
| Threads | Publish, Comments | |
| Bluesky | Publish, Comments | |
| Mastodon | Publish, Comments | |
| Publish, 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) │
└─────────────────┘ └──────────────────┘2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Database Schema
UserSocialAccount
Stores OAuth credentials and connection details for each platform.
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])
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CompanyPost
Stores social media posts with publish tracking.
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
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Features
OAuth Authentication
Each platform requires specific OAuth scopes:
| Platform | Required Scopes |
|---|---|
w_member_social, r_liteprofile | |
tweet.write, users.read | |
instagram_basic, instagram_content_publish | |
pages_manage_posts, pages_read_engagement |
Flow:
- User clicks "Connect [Platform]"
- Redirect to platform OAuth page
- User grants permissions
- Platform redirects to callback URL with auth code
- Exchange code for access/refresh tokens
- 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 resultScheduled Publishing:
User schedules post → Create ScheduledPost → Cloud Tasks triggers at time → Publish → Update statusMedia 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:
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?
}2
3
4
5
6
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:
{
"content": "Check out our latest blog post!",
"platforms": ["linkedin", "twitter"],
"mediaUrls": ["https://cdn.example.com/image.png"],
"scheduledAt": "2025-12-01T10:00:00Z" // Optional
}2
3
4
5
6
Response:
{
"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"
}
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GET /api/social/accounts
List all connected social accounts.
Response:
{
"accounts": [
{
"id": "uuid",
"platform": "linkedin",
"profileType": "personal",
"isActive": true,
"lastUsedAt": "2025-11-28T12:00:00Z"
}
]
}2
3
4
5
6
7
8
9
10
11
DELETE /api/social/accounts/
Disconnect a social account.
Response:
{
"success": true
}2
3
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