tangled
alpha
login
or
join now
indexx.dev
/
tweets2bsky
forked from
j4ck.xyz/tweets2bsky
0
fork
atom
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.
0
fork
atom
overview
issues
pulls
pipelines
fix: threading logic, video limits (90mb/3min)
jack
2 months ago
d292138b
677ab6a8
+12
-2
1 changed file
expand all
collapse all
unified
split
src
index.ts
+12
-2
src/index.ts
···
62
62
63
63
interface VideoInfo {
64
64
variants?: VideoVariant[];
65
65
+
duration_millis?: number;
65
66
}
66
67
67
68
interface MediaEntity {
···
705
706
let replyParentInfo: ProcessedTweetEntry | null = null;
706
707
707
708
if (isReply) {
708
708
-
if (replyStatusId && processedTweets[replyStatusId] && !processedTweets[replyStatusId]?.migrated) {
709
709
+
if (replyStatusId && processedTweets[replyStatusId]) {
709
710
console.log(`[${twitterUsername}] 🧵 Threading reply to post in ${bskyIdentifier}: ${replyStatusId}`);
710
711
replyParentInfo = processedTweets[replyStatusId] ?? null;
711
712
} else {
···
795
796
}
796
797
} else if (media.type === 'video' || media.type === 'animated_gif') {
797
798
const variants = media.video_info?.variants || [];
799
799
+
const duration = media.video_info?.duration_millis || 0;
800
800
+
801
801
+
if (duration > 180000) { // 3 minutes
802
802
+
console.warn(`[${twitterUsername}] ⚠️ Video too long (${(duration / 1000).toFixed(1)}s). Fallback to link.`);
803
803
+
const tweetUrl = `https://twitter.com/${twitterUsername}/status/${tweetId}`;
804
804
+
if (!text.includes(tweetUrl)) text += `\n\nVideo: ${tweetUrl}`;
805
805
+
continue;
806
806
+
}
807
807
+
798
808
const mp4s = variants
799
809
.filter((v) => v.content_type === 'video/mp4')
800
810
.sort((a, b) => (b.bitrate || 0) - (a.bitrate || 0));
···
808
818
updateAppStatus({ message: `Downloading video: ${path.basename(videoUrl)}` });
809
819
const { buffer, mimeType } = await downloadMedia(videoUrl);
810
820
811
811
-
if (buffer.length <= 100 * 1024 * 1024) {
821
821
+
if (buffer.length <= 90 * 1024 * 1024) {
812
822
const filename = videoUrl.split('/').pop() || 'video.mp4';
813
823
updateAppStatus({ message: `Uploading video to Bluesky...` });
814
824
videoBlob = await uploadVideoToBluesky(agent, buffer, filename);