- Notifications
You must be signed in to change notification settings - Fork8
AT Protocol (Authenticated Transfer Protocol behind Bluesky) R package
License
Unknown, MIT licenses found
Licenses found
JBGruber/atrrr
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
The goal of atrrr1 is to wrap the AT Protocol (Authenticated TransferProtocol) behind Bluesky.And we have actually already fulfilled thisgoal!.
The entire protocol is open and documented in so-calledlexicons, from which weautogeneratedR functions.
These are not exported, however, since dealing with them is a bitadvanced. Rather we have some nice human-generated functions withdocumentation and examples.
You can install atrrr from CRAN with:
install.packages("atrrr")You can install the development version ofatrrr like so (install theremotes package first, withinstall.packages("remotes"), if youdon’t have that yet):
# install.packages("remotes")remotes::install_github("JBGruber/atrrr")
library(atrrr)The first time you make a request, you will be prompted automatically toenter your user handle and an app password to authenticateatrrr tocommunicate with BlueSky for you.
The page to generate app passwords is also automatically opened for you.
page to create new apppasswordsHowever, 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 ispermanently stored encrypted on disk.
To fetch all the skeets by a specific user, use theget_skeets_authored_by function.Note this also includes quote skeetsand reskeets. You can also opt not to parse the result by settingparse = FALSE, however it is recommended to use the default parseoption which results in a (more) tidy tibble.
get_skeets_authored_by(actor="benguinaudeau.bsky.social",parse=TRUE)|>dplyr::glimpse()#> 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 onspecific keywords. These feeds aggregate content, for instance, a usermight curate a feed around the hashtag#rstats to gather all relevantcontent about. Let’s delve into the dynamics of such feeds.
Our starting point is to extract the posts from the#rstats feedcreated by “andrew.heiss.phd”.
# Fetching the feed postsfeeds<- get_feeds_created_by(actor="andrew.heiss.phd")# Filtering for a specific keyword, for example "#rstats"rstat_feed<-feeds|> filter(displayName=="#rstats")# Extracting posts from this curated feedrstat_posts<- get_feed(rstat_feed$uri,limit=200)|>dplyr::glimpse()#> 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 theBasicUsagevignette to learn more.
You can help by creating anissue requestingnew features or reporting bugs.
If you are a developer, we are happy to accept pull requests. It shouldbe fairly straightforward, as all endpoints are already covered byautomatically generated function. For example, the endpointapp.bsky.actor.getProfilesis accessible viaatrrr:::app_bsky_actor_get_profiles(). The functionget_user_info() is just a thin wrapper around that and calls anoptional 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 athttps://docs.bsky.app/docs/category/http-reference that interests you,you can write a similar wrapper and contribute it to the package (orbuild something new on top of it). But please open anissue first, so we don’t doduplicated work.
Footnotes
before 2024-01-04, this package wascalled
atr, meaning an Rpackage for the AT protocol (similar to httr, which is a package forthe HTTProtocol). Unfortunatley, when we wanted to release thepackage on CRAN, the nameatrwas rejected, as a package of thesame name existed some time ago. So we added two “r” to make thepackage go brrr anyway!↩
About
AT Protocol (Authenticated Transfer Protocol behind Bluesky) R package
Topics
Resources
License
Unknown, MIT licenses found
Licenses found
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors8
Uh oh!
There was an error while loading.Please reload this page.


