Have you ever wanted to see your favourite social media posts in your command line? No? Me neither, but at least hrbrmstr has a few months ago. Or to be honest, I don’t know which social media site he prefers, but Bluesky is currently my favourite. With the ease of use and algorithmic curation that I loved about Twitter before its demise and the super interesting and easy to work with AT protocol, which should make Bluesky “billionaire-proof”1, I’m hopeful that this social network it here to stay.
Recently, I have published the atrrr
package with a few friends, so I thought I could remove the pesky Python part from hrbrmstr’s command line interface.
Along the way, I also looked into how one can write a command line tool with R.
I really love using command line tools2 and was always a bit disappointed that people don’t seem to write them in R.
After spending some time on this, I have to say: it’s not that bad, especially given the packages docopt
and cli
, but it’s definitly a bit more manual than in Python.
But let’s have a look at the result first:
And here is of course the commented source code (also available as a GitHub Gist):
#!/usr/bin/Rscript
# Command line application Bluesky feed reader based on atrrr.
#
# Make executable with `chmod u+x rbsky`.
#
# If you are on macOS, you should replace the first line with:
#
# #!/usr/local/bin/Rscript
#
# Not sure how to make it work in Windows ¯\_(ツ)_/¯
#
# based on https://rud.is/b/2023/07/07/poor-dudes-janky-bluesky-feed-reader-cli-via-r-python/
library(atrrr)
library(cli)
library(lubridate, include.only = c("as.period", "interval"),
quietly = TRUE, warn.conflicts = FALSE)
if (!require("docopt", quietly = TRUE)) install.packages("docopt")
library(docopt)
# function to displace time since a post was made
ago <- function(t) {
as.period(Sys.time() - t) |>
as.character() |>
tolower() |>
gsub("\\d+\\.\\d+s", "ago", x = _)
}
# docopt can produce some documentation when you run `rbsky -h`
doc <- "Usage: rbsky [-a ALGO] [-n NUM] [-t S] [-h]
-a --algorithm ALGO algorithm used to sort the posts [e.g., \"reverse-chronological\"]
-n --n_posts NUM Maximum number of records to return [default: 25]
-t --timeout S Time to wait before displaying the next post [default. 0.5 seconds]
-h --help show this help text"
# this line parses the arguments passed from the command line and makes sure the
# documentation is shown when `rbsky -h` is run
args <- docopt(doc)
if (is.null(args$n_posts)) args$n_posts <- 25L
if (is.null(args$timeout)) args$timeout <- 0.5
# get feed
feed <- get_own_timeline(algorithm = args$algorithm,
limit = as.integer(args$n_posts),
verbose = FALSE)
# print feed
for (i in seq_along(feed$uri)) {
item <- feed[i, ]
cli({
# headline from author • time since post
cli_h1(c(col_blue(item$author_name), " • ",
col_silver(ago(item$indexed_at))))
# text of post in italic (not all terminals support it)
cli_text(style_italic("{item$text}"))
# print quoted text if available
quote <- purrr::pluck(item, "embed_data", 1, "external")
if (!is.null(quote)) {
cli_blockquote("{quote$title}\n{quote$text}", citation = quote$uri)
}
# display that posts contains image(s)
imgs <- length(purrr::pluck(item, "embed_data", 1, "images"))
if (imgs > 0) {
cli_text(col_green("[{imgs} IMAGE{?S}]"))
}
# new line before next post
cli_text("\n")
})
# wait a little before showing the next post
Sys.sleep(args$timeout)
}
I added the location of the file to my PATH3 with export PATH="/home/johannes/bin/:$PATH"
to make it run without typing e.g., Rscript rbsky
or ./rbsky
.
And there you go.
If you want to explore how to search and analyse posts from Bluesky and then post the results via R
, have a look at the atrrr
-pkgdown
site: https://jbgruber.github.io/atrrr/.
Once the protocol fulfils its vision that one can always take their follower network and posts to a different site using the protocol.↩︎
I liked this summary of reasons to use them https://youtu.be/Q1dwzi5DKio.↩︎
The PATH environment variable is the location of one or several directories that your system searches for executables.↩︎