Adds option for custom bskyPost text rather than just title, desc, and url. Also removes url from post text to save graphemes.
+18
-39
Diff
round #0
+1
packages/cli/src/commands/publish.ts
+1
packages/cli/src/commands/publish.ts
+16
-39
packages/cli/src/lib/atproto.ts
+16
-39
packages/cli/src/lib/atproto.ts
···
569
569
export interface CreateBlueskyPostOptions {
570
570
title: string;
571
571
description?: string;
572
+
bskyPost?: string;
572
573
canonicalUrl: string;
573
574
coverImage?: BlobObject;
574
575
publishedAt: string; // Used as createdAt for the post
···
612
613
agent: Agent,
613
614
options: CreateBlueskyPostOptions,
614
615
): Promise<StrongRef> {
615
-
const { title, description, canonicalUrl, coverImage, publishedAt } = options;
616
+
const { title, description, bskyPost, canonicalUrl, coverImage, publishedAt } = options;
616
617
617
-
// Build post text: title + description + URL
618
+
// Build post text: title + description
618
619
// Max 300 graphemes for Bluesky posts
619
620
const MAX_GRAPHEMES = 300;
620
621
621
622
let postText: string;
622
-
const urlPart = `\n\n${canonicalUrl}`;
623
-
const urlGraphemes = countGraphemes(urlPart);
624
623
625
-
if (description) {
626
-
// Try: title + description + URL
627
-
const fullText = `${title}\n\n${description}${urlPart}`;
624
+
if (bskyPost) {
625
+
// Custom bsky post overrides any default behavior
626
+
postText = bskyPost;
627
+
}
628
+
else if (description) {
629
+
// Try: title + description
630
+
const fullText = `${title}\n\n${description}`;
628
631
if (countGraphemes(fullText) <= MAX_GRAPHEMES) {
629
632
postText = fullText;
630
633
} else {
···
632
635
const availableForDesc =
633
636
MAX_GRAPHEMES -
634
637
countGraphemes(title) -
635
-
countGraphemes("\n\n") -
636
-
urlGraphemes -
637
638
countGraphemes("\n\n");
638
639
if (availableForDesc > 10) {
639
640
const truncatedDesc = truncateToGraphemes(
640
641
description,
641
642
availableForDesc,
642
643
);
643
-
postText = `${title}\n\n${truncatedDesc}${urlPart}`;
644
+
postText = `${title}\n\n${truncatedDesc}`;
644
645
} else {
645
-
// Just title + URL
646
-
postText = `${title}${urlPart}`;
646
+
// Just title
647
+
postText = `${title}`;
647
648
}
648
649
}
649
650
} else {
650
-
// Just title + URL
651
-
postText = `${title}${urlPart}`;
651
+
// Just title
652
+
postText = `${title}`;
652
653
}
653
654
654
-
// Final truncation if still too long (shouldn't happen but safety check)
655
+
// Final truncation in case title or bskyPost are longer than expected
655
656
if (countGraphemes(postText) > MAX_GRAPHEMES) {
656
657
postText = truncateToGraphemes(postText, MAX_GRAPHEMES);
657
658
}
658
659
659
-
// Calculate byte indices for the URL facet
660
-
const encoder = new TextEncoder();
661
-
const urlStartInText = postText.lastIndexOf(canonicalUrl);
662
-
const beforeUrl = postText.substring(0, urlStartInText);
663
-
const byteStart = encoder.encode(beforeUrl).length;
664
-
const byteEnd = byteStart + encoder.encode(canonicalUrl).length;
665
-
666
-
// Build facets for the URL link
667
-
const facets = [
668
-
{
669
-
index: {
670
-
byteStart,
671
-
byteEnd,
672
-
},
673
-
features: [
674
-
{
675
-
$type: "app.bsky.richtext.facet#link",
676
-
uri: canonicalUrl,
677
-
},
678
-
],
679
-
},
680
-
];
681
-
682
660
// Build external embed
683
661
const embed: Record<string, unknown> = {
684
662
$type: "app.bsky.embed.external",
···
698
676
const record: Record<string, unknown> = {
699
677
$type: "app.bsky.feed.post",
700
678
text: postText,
701
-
facets,
702
679
embed,
703
680
createdAt: new Date(publishedAt).toISOString(),
704
681
};
History
1 round
2 comments
quillmatiq.com
submitted
#0
1 commit
expand
collapse
Adds option for custom bskyPost text rather than just title, desc, and url. Also removes url from post text to save graphemes.
Looks good! Thank you @quillmatiq.com!