Files
easystream-main/content_syndication_example.js
SamiAhmed7777 0b7e2d0a5b feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
2025-10-21 00:39:45 -07:00

282 lines
8.8 KiB
JavaScript

/**
* EasyStream Content Syndication - Node.js Example
* Extracts video metadata and reposts to other platforms
*/
const axios = require('axios');
class EasyStreamSyndicator {
constructor(apiBaseUrl, jwtToken) {
this.apiBaseUrl = apiBaseUrl.replace(/\/$/, '');
this.headers = {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
};
}
async getVideos(limit = 50, category = null, sinceDate = null) {
try {
const params = { limit };
if (category) params.category = category;
if (sinceDate) params.since = sinceDate;
const response = await axios.get(`${this.apiBaseUrl}/api/v1/videos`, {
headers: this.headers,
params
});
return response.data.data.videos;
} catch (error) {
console.error('Error fetching videos:', error.response?.status);
return [];
}
}
async getVideoDetails(videoId) {
try {
const response = await axios.get(`${this.apiBaseUrl}/api/v1/videos/${videoId}`, {
headers: this.headers
});
return response.data.data;
} catch (error) {
console.error(`Error fetching video ${videoId}:`, error.response?.status);
return null;
}
}
async postToYouTube(videoData) {
// YouTube API integration would go here
const youtubeData = {
title: videoData.title,
description: this.formatDescriptionForYouTube(videoData),
tags: videoData.tags || [],
category: this.mapCategoryToYouTube(videoData.category),
privacy: videoData.privacy === 'public' ? 'public' : 'unlisted'
};
console.log(`📺 Would post to YouTube: ${youtubeData.title}`);
// Example: Upload to YouTube using googleapis
/*
const youtube = google.youtube({ version: 'v3', auth: oauth2Client });
const result = await youtube.videos.insert({
part: 'snippet,status',
requestBody: {
snippet: {
title: youtubeData.title,
description: youtubeData.description,
tags: youtubeData.tags,
categoryId: youtubeData.category
},
status: {
privacyStatus: youtubeData.privacy
}
},
media: {
body: fs.createReadStream(videoPath)
}
});
*/
return youtubeData;
}
async postToTwitter(videoData) {
// Twitter API integration would go here
const tweetText = this.formatTweet(videoData);
console.log(`🐦 Would tweet: ${tweetText}`);
// Example: Post to Twitter using twitter-api-v2
/*
const twitterClient = new TwitterApi(bearerToken);
const tweet = await twitterClient.v2.tweet({
text: tweetText,
media: {
media_ids: [mediaId] // Upload thumbnail first
}
});
*/
return { text: tweetText };
}
async postToInstagram(videoData) {
// Instagram API integration would go here
const instagramData = {
caption: this.formatInstagramCaption(videoData),
media_url: `${this.apiBaseUrl}${videoData.video_url}`,
thumbnail_url: `${this.apiBaseUrl}${videoData.thumbnail_url}`
};
console.log(`📸 Would post to Instagram: ${videoData.title}`);
return instagramData;
}
async postToTikTok(videoData) {
// TikTok API integration would go here
const tiktokData = {
title: this.truncateTitleForTikTok(videoData.title),
description: this.formatDescriptionForTikTok(videoData),
hashtags: this.extractHashtags(videoData)
};
console.log(`🎵 Would post to TikTok: ${tiktokData.title}`);
return tiktokData;
}
async syndicateContent(platforms = ['youtube', 'twitter', 'instagram']) {
console.log('🚀 Starting content syndication...');
// Get recent videos (last 24 hours)
const sinceDate = new Date().toISOString().split('T')[0];
const videos = await this.getVideos(10, null, sinceDate);
console.log(`📹 Found ${videos.length} videos to syndicate`);
for (const video of videos) {
console.log(`\n📝 Processing: ${video.title}`);
// Get detailed video info
const videoDetails = await this.getVideoDetails(video.id);
if (!videoDetails) continue;
// Post to selected platforms
const promises = [];
if (platforms.includes('youtube')) {
promises.push(this.postToYouTube(videoDetails));
}
if (platforms.includes('twitter')) {
promises.push(this.postToTwitter(videoDetails));
}
if (platforms.includes('instagram')) {
promises.push(this.postToInstagram(videoDetails));
}
if (platforms.includes('tiktok')) {
promises.push(this.postToTikTok(videoDetails));
}
// Execute all platform posts concurrently
await Promise.all(promises);
// Rate limiting
await this.sleep(2000);
}
console.log('\n✅ Content syndication completed!');
}
// Helper methods
formatDescriptionForYouTube(videoData) {
let description = videoData.description;
// Add source attribution
description += `\n\n🎥 Originally posted on EasyStream`;
description += `\n👤 Creator: ${videoData.uploader.display_name}`;
description += `\n🔗 Watch original: ${this.apiBaseUrl}${videoData.video_url}`;
// Add hashtags
if (videoData.tags && videoData.tags.length > 0) {
const hashtags = videoData.tags.slice(0, 10).map(tag => `#${tag}`).join(' ');
description += `\n\n${hashtags}`;
}
return description;
}
formatTweet(videoData) {
const title = videoData.title.substring(0, 100);
const url = `${this.apiBaseUrl}${videoData.video_url}`;
// Calculate remaining space for hashtags
const baseText = `🎥 ${title}\n\n👀 Watch: ${url}`;
const remaining = 280 - baseText.length - 10; // Buffer
const hashtags = this.extractHashtags(videoData, remaining);
return `${baseText}\n\n${hashtags}`;
}
formatInstagramCaption(videoData) {
let caption = `🎥 ${videoData.title}\n\n`;
caption += `${videoData.description.substring(0, 300)}...\n\n`;
caption += `👤 By: ${videoData.uploader.display_name}\n`;
caption += `👀 ${videoData.views} views\n\n`;
// Add hashtags
const hashtags = this.extractHashtags(videoData, 200);
caption += hashtags;
return caption;
}
formatDescriptionForTikTok(videoData) {
const description = videoData.description.substring(0, 100) + '...';
const hashtags = this.extractHashtags(videoData, 50);
return `${description} ${hashtags}`;
}
extractHashtags(videoData, maxLength = 100) {
const tags = videoData.tags || [];
const category = videoData.category || '';
const hashtags = [];
if (category) {
hashtags.push(`#${category}`);
}
for (const tag of tags) {
const hashtag = `#${tag.replace(/\s+/g, '')}`;
if (hashtags.join(' ').length + hashtag.length <= maxLength) {
hashtags.push(hashtag);
} else {
break;
}
}
return hashtags.join(' ');
}
truncateTitleForTikTok(title) {
return title.length > 50 ? title.substring(0, 50) + '...' : title;
}
mapCategoryToYouTube(category) {
const categoryMap = {
'gaming': '20',
'music': '10',
'education': '27',
'entertainment': '24',
'sports': '17',
'tech': '28'
};
return categoryMap[category] || '24'; // Default to Entertainment
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage example
async function main() {
const API_BASE_URL = "https://yourdomain.com";
const JWT_TOKEN = "your_jwt_token_here";
const syndicator = new EasyStreamSyndicator(API_BASE_URL, JWT_TOKEN);
// Syndicate to selected platforms
await syndicator.syndicateContent(['youtube', 'twitter', 'instagram', 'tiktok']);
}
// Run if called directly
if (require.main === module) {
main().catch(console.error);
}
module.exports = EasyStreamSyndicator;