This document explains how to retrieve data from public and private Trello boards using trelloR
.
NOTE. Right now, only GET requests are implemented. Support for POST and PUT may be added in later versions. Accessing the data in private boards requires authorization which you can read about in the Getting private data section.
The basic building block of the Trello workflow is a Board. It encapsulates a hierarchy of “models”, i.e. Members, Teams, Lists, Cards, Labels, Checklists and Actions. Each model has a parent model (e.g. a board is a parent model for cards on it) and child models (a card can include comments as child models). The models can be accessed recursively. This means that you can obtain the actions from all cards by addressing the whole board without going through specific cards one by one.
To access a particular model, you need to know its unique ID, or the ID of its parent model. In some cases (e.g. with boards or cards), you can use the model URL instead. This is useful because a URL can be found in your browser address bar (unlike ID). You can also obtain model ID by “searching”, which you can read more about later.
Here is an example how to get the data from Trello Development Roadmap. Since it’s a public board, no authentication is required:
library(trelloR)
#> R API for Trello
#> Disclaimer: trelloR is not affiliated, associated, authorized, endorsed by or in any way officially connected to Trello, Inc. (www.trello.com).
url = "https://trello.com/b/nC8QJJoZ/trello-development-roadmap"
idb = get_id_board(url = url)
#> Sending request...
#> Request URL:
#> https://api.trello.com/1/board/nC8QJJoZ?fields=name&limit=1000
#> Received 1 results
#> Returning tbl_df tbl data.frame
#> Converted into character vector of length 1 with name "Trello Development Roadmap"
cards = get_board_cards(idb, limit = 5)
#> Sending request...
#> Request URL:
#> https://api.trello.com/1/board/4d5ea62fd76aa1136000000c/cards?limit=5
#> Received 5 results
#> Returning tbl_df tbl data.frame
The above example uses get_id_board()
to get the board ID based on its URL. Board ID is then supplied to get_board_cards()
which fetches card-related data. The limit = 5
parameter just means that only the 5 newest cards will be returned.
If there are no complaints from the server, a JSON response is received and converted into a data.frame
. It will look something like this:
cards
#> Source: local data frame [5 x 32]
#>
#> id checkItemStates closed dateLastActivity
#> <chr> <lgl> <lgl> <chr>
#> 1 57bc9cdff5ceb056e765b915 NA FALSE 2016-09-09T03:47:55.480Z
#> 2 57bc991ee084b9a0d3dc1be6 NA FALSE 2016-08-23T18:50:58.882Z
#> 3 57bc99a9f265c7c5f76ca4dc NA FALSE 2016-08-23T18:51:10.636Z
#> 4 57bc9a601c9a74dc1d63cdf4 NA FALSE 2016-08-23T18:51:04.104Z
#> 5 576afe49c8854e12d1279e32 NA FALSE 2016-08-23T18:51:25.042Z
#> Variables not shown: desc <chr>, idBoard <chr>, idList <chr>,
#> idMembersVoted <list>, idShort <int>, idAttachmentCover <chr>,
#> manualCoverAttachment <lgl>, idLabels <list>, name <chr>, pos <dbl>,
#> shortLink <chr>, due <lgl>, idChecklists <list>, idMembers <list>,
#> labels <list>, shortUrl <chr>, subscribed <lgl>, url <chr>, badges.votes
#> <int>, badges.viewingMemberVoted <lgl>, badges.subscribed <lgl>,
#> badges.fogbugz <chr>, badges.checkItems <int>, badges.checkItemsChecked
#> <int>, badges.comments <int>, badges.attachments <int>,
#> badges.description <lgl>, badges.due <lgl>.
Typically, the response will contain multiple columns including model ID, name and other data, such as attachments or preferences. Because the ID of child elements is included in the response, you can use it to work your way down the hierarchy until you reach the desired model.
trelloR
includes a number of data-fetching functions each of which targets one single model. This puts certain limits on what you can ask for; on the other hand, it eliminates most of the effort (and makes the code easier to read). It also means that the functions can have predictable names which are easy to guess. For example:
get_board_cards()
to obtain cards from a particular boardget_card_members()
to obtain the list of people assigned to a cardBasically, the parent model is always followed by the child model with the get_
prefix in the beginning. For an overview of the available functions, call ?get_board
, ?get_card
, ?get_team
, ?get_member
, get_list
or ?get_id
.
Sometimes you don’t know the model ID but you have other information, such as name, description or other text. In such cases, you can call trello_search()
, which is equivalent to the search field in Trello web app. To limit your search to specific models (e.g. only members), call the appropriately named version of the search function:
captain = trello_search_members("Captain America", token = my_token)
Searches need to be authorized; hence, the token argument is needed (see Getting private data).
trello_get()
Most of the functions in this package are wrappers for trello_get()
. You can call it directly if you lack a particular data-fetching option, or you can define a new function by wrapping trello_get()
and providing some default values.
The following example creates a function that fetches all updates made in a given card (it uses a filter because updates are a type of action, and there’s no need to retrieve all actions):
get_card_updates = function(id, ...) {
trello_get(parent = "card", child = "actions", id = id, filter = "updateCard", ...)
}
Such functions can be called the usual way by supplying a card ID:
idc = cards$id[1]
card_updates = get_card_updates(idc, limit = 5)
#> Sending request...
#> Request URL:
#> https://api.trello.com/1/card/57bc9cdff5ceb056e765b915/actions?filter=updateCard&limit=5
#> Received 2 results
#> Returning tbl_df tbl data.frame
For a detailed list of all possible queries, consult the Trello API reference.
trello_get()
token
is necessary for accessing private boards (see Getting private data); defaults to NULL
limit
defaults to 1000 results; this is also the maximum number of results for a single requestquery
is useful if you need to provide a list of key-value pairs, such as query = list(key1 = "value1", key2 = "value2")
; these will get appended to the URL request. Setting filter = "updateCard"
and limit=10
is equivalent to query = list(filter = "updateCard", limit = 10)
; if you need more information about keys and values are available, refer to Trello API referencepaging
is useful for requests that return more than 1000 results; it breaks the request down into smaller pieces, each of which returns no more than 1000 results. Defaults to FALSE
, but if the request returns 1000 results, paging is suggested by a message in the consolebind.rows
binds all pages into a single data.frame
; defaults to TRUE
If bind.rows = FALSE
, the result will be a list
with as many elements as there are pages. This is also a fallback option for the rare occasion when the responses are not perfectly formatted and make dplyr::bind_rows
fail.
When calling trello_get()
directly, you have an option to either specify parent
and child
or provide the whole URL as a character vector of length 1.
board_comments = trello_get(parent = "board", child = "actions", id = idb,
filter = "commentCard", limit = 5)
#> Sending request...
#> Request URL:
#> https://api.trello.com/1/board/4d5ea62fd76aa1136000000c/actions?filter=commentCard&limit=5
#> Received 5 results
#> Returning tbl_df tbl data.frame
If a request fails because of the client-side or server-side error, the error code is reprinted in the console. Additional server messages are also included to make debugging easier. See the example with invalid card ID below:
tryCatch(
expr = get_card_actions(id = "I_have_a_bad_feeling_about_this"),
error = function(e) {
print(e$message)})
#> Sending request...
#> Request URL:
#> https://api.trello.com/1/card/I_have_a_bad_feeling_about_this/actions?limit=1000
#> [1] "Client error: (400) Bad Request : invalid id"
In case of a server-side error, the request will be re-send two more times, with 1.5s delay before each attempt. If it fails for the 3rd time, the error message is printed in the console.
Access to private boards requires authorization. This is done by registering an “app” that uses a secure token to communicate with the Trello API. Supplying the token to data-fetching functions will allow you to retrieve data from private boards under the condition that the user who authorized the app has the right to access them.
To create a token, login to Trello and visit the Developer Start Page. There you can get your developer credentials, i.e. your “key” and “secret”. Then, call the trello_get_token()
function to create a token for your project. This will also trigger first-time authorization in the browser (you only have to do it once):
my_token = trello_get_token(your_key, your_secret)
You will also be offered an option to store the authentication data in your working directory, in a hidden '.httr-oauth'
file.
NOTE. Make sure you keep your credentials in a safe, non-shared location.
One thing you can do immediately after obtaining the token is call get_my_boards()
to get an overview of your boards. It accepts the token as its only argument and returns a data.frame
with the board names and IDs related to the user who authorized the app.
my_boards = get_my_boards(my_token)
trelloR
is not affiliated, associated, authorized, endorsed by or in any way officially connected to Trello, Inc. (www.trello.com).
sessionInfo()
#> R version 3.3.1 (2016-06-21)
#> Platform: x86_64-pc-linux-gnu (64-bit)
#> Running under: elementary OS Freya
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=cs_CZ.UTF-8 LC_COLLATE=C
#> [5] LC_MONETARY=cs_CZ.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=cs_CZ.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=cs_CZ.UTF-8 LC_IDENTIFICATION=C
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] trelloR_0.1.0 httr_1.2.1
#>
#> loaded via a namespace (and not attached):
#> [1] Rcpp_0.12.6 digest_0.6.10 dplyr_0.5.0 assertthat_0.1
#> [5] R6_2.1.3 jsonlite_1.1 DBI_0.4-1 formatR_1.4
#> [9] magrittr_1.5 evaluate_0.9 stringi_1.1.1 curl_2.0
#> [13] rmarkdown_1.0 tools_3.3.1 stringr_1.0.0 yaml_2.1.13
#> [17] htmltools_0.3.5 knitr_1.13 tibble_1.0