I am using google apps script for a project that automatically posts to Bluesky. It is correctly logging in and getting access. It is correctly creating posts. I have added in functionality to create replies by adding the reply block to the post, with the correct root and parent tags. And I have it posting images correctly (most of the time; I still have issues recognizing when an image is too large, but that’s a different problem). Because all of that works, I will not include any of that code here.
Now I am trying to add in functionality to correctly indicate facets, like mentions, links, and hashtags. Specifically, I’m look at hashtags right now. I suspect if I can get this to work, I can get links and mentions to work as well. However, despite multiple attempts, I’m not getting it to correctly format the hashtag.
I have logic in my script that recognizes that there is a hashtag present. It then sends both the post text and the hashtag text (substring of the post) to a function that is supposed to be returning the starting and ending indices of the hashtag text, so that I can include that in the facet block. Because Bluesky works in UTF-8 and apps script UTF-16, that function does some conversion, to get the UTF-8 indices. I suspect that function could be where some of my problem is, but I’m not sure.
function getUtf8Indices(text, substring) {
// 1. Convert the UTF-16 string to a byte array using UTF-8 encoding
var byteArray = Utilities.newBlob(text, 'text/plain; charset=UTF-8').getBytes();
// 2. Find the starting byte index of the substring
var byteStartIndex = byteArray.indexOf(Utilities.newBlob(substring, 'text/plain; charset=UTF-8').getBytes()[0]);
// 3. Calculate the ending byte index
var byteEndIndex = byteStartIndex + Utilities.newBlob(substring, 'text/plain; charset=UTF-8').getBytes().length - 1;
return { byteStart: byteStartIndex, byteEnd: byteEndIndex };
}
That function is called within my block to create the post initially. Here is the section specific to the facet / hashtag process.
if(iRow[7] != "" && iRow[7] != null) { //is there a hashtag value?
var indeces = getUtf8Indices(iRow[3], iRow[7]) //pass the whole post & the hashtag value (substring of the post text) to get the start / end indices of the substring
this.facets = [
{
index: {
byteStart: indeces.byteStart,
byteEnd: indeces.byteEnd,
},
features: [{
$type: 'app.bsky.richtext.facet#tag',
tag: iRow[7].replace(/^#/, ''),
}]
}
]
}
It does return the indices, and when I Log the characters at the start / end indices, it does identify the start / end of the hashtag string. But then when the post is created on Bluesky, it’s not formatted as a hashtag (string shaded blue), but just as plain text.
I suspect a couple different options.
- I could be missing something really obvious; a typo that I’m just overlooking for example. Or maybe I’m not sending the correct substring (I’ve done it both with and without the ‘#’ as part of the substring, and that doesn’t seem to make a difference).
- Or it could be something in the getUtf8Indices() function. Full disclosure, I didn’t write that function, but copied it from somewhere, so it’s entirely possible that isn’t actually doing what I need it to do.
- Or it could be something else entirely.
I’ve tried a bunch of different things, and nothing has worked. Any suggestions or guidance would be great.