The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
The goal of atrrr1 is to wrap the AT Protocol (Authenticated Transfer Protocol) behind Bluesky. And we have actually already fulfilled this goal!.
The entire protocol is open and documented in so-called lexicons, from which we
autogenerated R
functions.
These are not exported, however, since dealing with them is a bit advanced. Rather we have some nice human-generated functions with documentation and examples.
You can install atrrr from CRAN with:
install.packages("atrrr")
You can install the development version of atrrr
like so
(install the remotes
package first, with
install.packages("remotes")
, if you don’t have that
yet):
# install.packages("remotes")
::install_github("JBGruber/atrrr") remotes
library(atrrr)
The first time you make a request, you will be prompted automatically
to enter your user handle and an app password to authenticate
atrrr
to communicate with BlueSky for you.
The page to generate app passwords is also automatically opened for you.
However, you can also trigger this process manually:
auth("jbgruber.bsky.social")
This can be useful if you want to replace an old token as it is permanently stored encrypted on disk.
get_skeets_authored_by
)To fetch all the skeets by a specific user, use the
get_skeets_authored_by
function. Note this also
includes quote skeets and reskeets. You can also opt not to parse
the result by setting parse = FALSE
, however it is
recommended to use the default parse option which results in a (more)
tidy tibble.
get_skeets_authored_by(actor = "benguinaudeau.bsky.social", parse = TRUE) |>
::glimpse()
dplyr#> Rows: 25
#> Columns: 21
#> $ uri <chr> "at://did:plc:ntd53albt5ffa4rgervvgibd/app.bsky.feed.pos…
#> $ cid <chr> "bafyreiconry2rc74zkunyalbhwsxa347gxjnhb7uza7y4njnecu3ek…
#> $ author_handle <chr> "jbgruber.bsky.social", "jacobmontgomery.bsky.social", "…
#> $ author_name <chr> "Johannes B. Gruber", "Jacob Montgomery", "Beatrice Magi…
#> $ text <chr> "I didn't even notice CRAN already approved it, but our …
#> $ author_data <list> ["did:plc:ntd53albt5ffa4rgervvgibd", "jbgruber.bsky.soc…
#> $ post_data <list> ["app.bsky.feed.post", "2024-10-04T12:43:04.752Z", ["ap…
#> $ embed_data <list> ["app.bsky.embed.record#view", ["app.bsky.embed.record#…
#> $ reply_count <int> 0, 0, 0, 1, 4, 0, 0, 4, 0, 1, 9, 0, 1, 0, 1, 0, 0, 0, 0,…
#> $ repost_count <int> 5, 3, 6, 6, 8, 0, 0, 15, 2, 1, 432, 3, 1, 5, 28, 0, 0, 0…
#> $ like_count <int> 11, 13, 13, 20, 13, 1, 1, 42, 6, 1, 606, 7, 3, 10, 35, 1…
#> $ indexed_at <dttm> 2024-10-04 12:43:04, 2024-03-18 21:09:28, 2024-02-16 17…
#> $ in_reply_to <chr> NA, NA, NA, NA, NA, NA, "at://did:plc:eotrvt2wp6mqooxjf3…
#> $ in_reply_root <chr> NA, NA, NA, NA, NA, NA, "at://did:plc:eotrvt2wp6mqooxjf3…
#> $ quotes <chr> "at://did:plc:vgvueqvmbqgoyxtcdebqdcgb/app.bsky.feed.pos…
#> $ tags <list> "rstats", <NULL>, <NULL>, "rstats", "rstats", <NULL>, <…
#> $ mentions <list> <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>,…
#> $ links <list> <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>,…
#> $ langs <list> ["en"], ["en"], ["it"], ["en"], ["en"], ["en"], ["en"],…
#> $ labels <list> [], [], [], [], [], [], [], [], [], [], [], [], [], [],…
#> $ is_reskeet <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, …
On Blue Sky users have the ability to create custom feeds based on
specific keywords. These feeds aggregate content, for instance, a user
might curate a feed around the hashtag #rstats
to gather
all relevant content about. Let’s delve into the dynamics of such
feeds.
Our starting point is to extract the posts from the
#rstats
feed created by “andrew.heiss.phd”.
# Fetching the feed posts
<- get_feeds_created_by(actor = "andrew.heiss.phd")
feeds
# Filtering for a specific keyword, for example "#rstats"
<- feeds |>
rstat_feed filter(displayName == "#rstats")
# Extracting posts from this curated feed
<- get_feed(rstat_feed$uri, limit = 200) |>
rstat_posts ::glimpse()
dplyr#> Rows: 292
#> Columns: 20
#> $ uri <chr> "at://did:plc:7crs3axm67jhrc57gi7ojyjn/app.bsky.feed.pos…
#> $ cid <chr> "bafyreicru2iryln3mqm6skdhym4illw2kn6z7qqig34trfvsp72zyi…
#> $ author_handle <chr> "timbulwidodostp.bsky.social", "bigbookofr.bsky.social",…
#> $ author_name <chr> "Timbul Widodo, S.TP", "Big Book of R", "Craig Hamilton"…
#> $ text <chr> "Sequential analysis poisson binomial data g estimation …
#> $ author_data <list> ["did:plc:7crs3axm67jhrc57gi7ojyjn", "timbulwidodostp.b…
#> $ post_data <list> ["app.bsky.feed.post", "2024-11-16T13:08:30.723Z", [[[[…
#> $ embed_data <list> <NULL>, <NULL>, <NULL>, ["app.bsky.embed.record#view", …
#> $ reply_count <int> 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 1, 0, 0, 3, 1, 0, 0, 0, 0,…
#> $ repost_count <int> 0, 0, 0, 3, 0, 19, 0, 1, 0, 2, 1, 4, 0, 11, 0, 0, 1, 0, …
#> $ like_count <int> 0, 0, 0, 3, 1, 37, 0, 3, 1, 4, 1, 14, 1, 21, 1, 1, 4, 5,…
#> $ indexed_at <dttm> 2024-11-16 13:08:30, 2024-11-16 12:31:26, 2024-11-16 12…
#> $ in_reply_to <chr> NA, NA, "at://did:plc:ntd53albt5ffa4rgervvgibd/app.bsky.…
#> $ in_reply_root <chr> NA, NA, "at://did:plc:ntd53albt5ffa4rgervvgibd/app.bsky.…
#> $ quotes <chr> NA, NA, NA, "at://did:plc:ntd53albt5ffa4rgervvgibd/app.b…
#> $ tags <list> <"RStats", "rstats", "rsoftware", "rstatistics">, <NULL…
#> $ mentions <list> <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>,…
#> $ links <list> <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>,…
#> $ langs <list> ["en"], <NULL>, ["en"], ["en"], ["en"], ["en"], <NULL>,…
#> $ labels <list> [], [], [], [], [], [], [], [], [], [], [], [], [], [],…
Start with the Basic Usage vignette to learn more.
You can help by creating an issue requesting new features or reporting bugs.
If you are a developer, we are happy to accept pull requests. It
should be fairly straightforward, as all endpoints are already covered
by automatically generated function. For example, the endpoint app.bsky.actor.getProfiles
is accessible via atrrr:::app_bsky_actor_get_profiles()
.
The function get_user_info()
is just a thin wrapper around
that and calls an optional parsing function:
get_user_info <- function(actor,
parse = TRUE,
.token = NULL) {
# we need to use do.call so objects are passed to the right environment
res <- do.call(
what = app_bsky_actor_get_profiles,
args = list(
actor,
.token = .token, # tokens are handled automatically under the hood
.return = "json"
)) |>
purrr::pluck("profiles")
if (parse) {
res <- parse_actors(res)
}
return(res)
}
If you find an endpoint at https://docs.bsky.app/docs/category/http-reference that interests you, you can write a similar wrapper and contribute it to the package (or build something new on top of it). But please open an issue first, so we don’t do duplicated work.
before 2024-01-04, this package was
called
atr
, meaning an R package for the AT protocol (similar
to httr, which is a package for the HTTProtocol). Unfortunatley, when we
wanted to release the package on CRAN, the name atr
was
rejected, as a package of the same name existed some time ago. So we
added two “r” to make the package go brrr anyway!↩︎
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.