Skip to content

Properly link to @dslc.io #76

@jonthegeek

Description

@jonthegeek

Bluesky (and {bskyr}) doesn't automatically link @dslc.io to https://bsky.app/profile/dslc.io. It looks like it's possible to do so via bskyr::bs_create_record(), adding a "link" record to go with the post. This is a raw reply from Google Gemini about it, only partially confirmed:

library(bskyr)
library(stringi) # For accurate byte counting

create_mention_facet <- function(text, handle) {
  # 1. Resolve the handle to a DID (The internal ID Bluesky actually uses)
  # This requires an authenticated session.
  resolved <- bs_resolve_handle(handle)
  
  if (nrow(resolved) == 0) warning("Could not resolve handle: ", handle)
  user_did <- resolved$did[1]
  
  # 2. Find the byte positions (Critical: Bluesky counts bytes, not chars)
  # We use stringi to handle UTF-8 byte indices correctly
  pattern <- paste0("@", handle)
  loc <- stringi::stri_locate_first_fixed(text, pattern)
  
  if (is.na(loc[1])) stop("Handle not found in text")
  
  # Convert R's 1-based indexing to Bluesky's 0-based byte indexing
  # stri_locate returns byte indices by default for UTF-8? 
  # Actually, safer to convert text to raw to be 100% sure of byte offsets if special chars exist.
  # But stri_locate_first_fixed usually works on character index. 
  # Let's use a robust byte-counting method:
  
  utf8_text <- charToRaw(text)
  utf8_handle <- charToRaw(pattern)
  
  # Find the sequence of raw bytes
  # (Simple implementation for exact match)
  match_index <- NA
  len <- length(utf8_handle)
  for (i in 1:(length(utf8_text) - len + 1)) {
    if (all(utf8_text[i:(i + len - 1)] == utf8_handle)) {
      match_index <- i - 1 # 0-indexed start
      break
    }
  }
  
  if (is.na(match_index)) stop("Handle bytes not found in text")
  
  byte_start <- match_index
  byte_end <- match_index + len
  
  # 3. Construct the Facet Structure
  list(
    index = list(
      byteStart = byte_start,
      byteEnd = byte_end
    ),
    features = list(
      list(
        "$type" = "app.bsky.richtext.facet#mention",
        did = user_did
      )
    )
  )
}
# Your desired post
post_text <- "Hello @dslc.io testing API facets!"
handle_to_link <- "dslc.io"

# Create the facet
mention_facet <- create_mention_facet(post_text, handle_to_link)

# Create the record manually
bs_create_record(
  collection = "app.bsky.feed.post",
  record = list(
    "$type" = "app.bsky.feed.post",
    text = post_text,
    createdAt = bs_created_at(),
    facets = list(mention_facet) # Must be a list of facets
  )
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions