/** * 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;