A simple tool which lets you scrape twitter accounts and crosspost them to bluesky accounts! Comes with a CLI and a webapp for managing profiles! Works with images/videos/link embeds/threads.

fix: prioritize video and restore original upload limits

jack 435cc19b 1097567b

+7 -6
+7 -6
src/index.ts
··· 442 const videoUrl = mp4s[0].url; 443 try { 444 const { buffer, mimeType } = await downloadMedia(videoUrl); 445 - if (buffer.length > 50 * 1024 * 1024) { // Reduced limit to be safer 446 - throw new Error('Video too large'); 447 } 448 const blob = await uploadToBluesky(agent, buffer, mimeType); 449 videoBlob = blob; 450 videoAspectRatio = aspectRatio; 451 } catch (err) { 452 console.warn(`Failed to upload video ${videoUrl}, linking to tweet instead:`, (err as Error).message); 453 - // Link to the actual tweet so it unfurls with the video correctly 454 const tweetUrl = `https://twitter.com/${twitterUsername}/status/${tweetId}`; 455 - if (!text.includes(tweetUrl)) { 456 - text += `\n${tweetUrl}`; 457 - } 458 } 459 } 460 }
··· 442 const videoUrl = mp4s[0].url; 443 try { 444 const { buffer, mimeType } = await downloadMedia(videoUrl); 445 + if (buffer.length > 95 * 1024 * 1024) { 446 + console.warn('Video too large (>95MB). Linking to tweet.'); 447 + const tweetUrl = `https://twitter.com/${twitterUsername}/status/${tweetId}`; 448 + if (!text.includes(tweetUrl)) text += `\n${tweetUrl}`; 449 + continue; 450 } 451 const blob = await uploadToBluesky(agent, buffer, mimeType); 452 videoBlob = blob; 453 videoAspectRatio = aspectRatio; 454 + break; // Prioritize video and stop looking for other media 455 } catch (err) { 456 console.warn(`Failed to upload video ${videoUrl}, linking to tweet instead:`, (err as Error).message); 457 const tweetUrl = `https://twitter.com/${twitterUsername}/status/${tweetId}`; 458 + if (!text.includes(tweetUrl)) text += `\n${tweetUrl}`; 459 } 460 } 461 }