-
Notifications
You must be signed in to change notification settings - Fork 3
/
README.Rmd
279 lines (203 loc) · 7.6 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
---
output:
md_document:
variant: gfm
---
```{r, echo=FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "README-"
)
```
# clickrup <img src="https://raw.githubusercontent.com/psolymos/clickrup/master/inst/images/clickrup.jpg" align="right" style="padding-left:10px;background-color:white;" width="200px" />
[![clickrup status badge](https://psolymos.r-universe.dev/badges/clickrup)](https://psolymos.r-universe.dev)
> Interacting with the ClickUp v2 API from R
[ClickUp](https://clickup.com/?noRedirect=true) is a cloud-based collaboration and project management tool.
Features include tasks, docs, chat, goals, and [more](https://clickup.com/features).
The {clickrup} R package wraps the ClickUp [API v2](https://clickup.com/api).
See the [roadmap](https://github.com/psolymos/clickrup/issues/1) for what is currently included in the package.
## Setup
Install the {clickrup} package:
```{r eval=FALSE}
## using remotes
remotes::install_github("psolymos/clickrup")
## with r-universe
options(repos = c(
psolymos = "https://psolymos.r-universe.dev",
CRAN = "https://cloud.r-project.org"))
install.packages('clickrup')
```
Follow this [tutorial](https://docs.clickup.com/en/articles/1367130-getting-started-with-the-clickup-api):
- sign up for ClickUp (you can use this referral [link](https://clickup.com?fp_ref=peter51) to do so, it's free),
- navigate to your personal *Settings*,
- click *Apps* in the left sidebar,
- click *Generate* to create your API token,
- click *Copy* to copy the token to your clipboard.
Now add your ClickUp token as an environment variable:
- open the file `.Renviron`: `file.edit("~/.Renviron")`,
- add a line with `CU_PAT="your_token"` to the `.Renviron` file and save it,
- check with `Sys.getenv("CU_PAT")`, it should return the token.
The ClickUp token will look something like
`pk_4753994_EXP7MPOJ7XQM5UJDV2M45MPF0YHH5YHO`.
The `cu_set_pat` function uses `Sys.setenv` to set
the `CU_PAT` environment variable for other processes called from within R or future calls to `Sys.getenv` from the same R process.
## API endpoints
The first step you want to do is to get the IDs for your workspaces (teams is the legacy term for this in the API).
If your setup was successful, `cu_get_teams()` should return a list with the workspace IDs and names.
The easiest way to get going with the various endpoints is to browse the [API v2 documentation](https://clickup.com/api).
Once you found what you are after, just look at the API heading. For example, for **Get Teams**, the R function
is prepended with `cu_` (to facilitate RStudio code completion),
then comes the heading in lower case and spaces replaced by underscores.
Similarly, **Get Filtered Team Tasks** will be `cu_get_filtered_team_tasks()`.
Articles (a, an, the) are dropped (e.g. **Create a Time Entry**)
will be `cu_create_time_entry()`.
Function arguments are the *Parameters* listed on the API page, `...` passes optional parameters, query parameters,
or elements for the body.
## Examples
Load the package and set the access token if it is not already set.
`cu_get_pat()` returns the token invisibly, so it doesn't
end up in logs.
```{r}
library(clickrup)
cu_get_pat() # returns PAT invisibly
```
### ClickUp hierarchy
The [ClickUp hierarchy](https://docs.clickup.com/en/articles/1045623-how-does-the-hierarchy-structure-work-in-clickup) includes the following levels:
- Workspaces (teams is the legacy term for this in the API)
- Spaces
- Folders
- Lists
- Tasks
- Subtasks
- Checklists
We can list Workspaces that we have access to using the `cu_get_teams()`
function. It takes no arguments, it only passes the access token
behind the scenes, so it is a good way to test if things are
working as expected
```{r}
Teams <- cu_get_teams()
str(Teams, 3)
```
Spaces within a specific Workspace defined by its `team_id`
```{r}
team_id <- Teams$teams[[2]]$id
Spaces <- cu_get_spaces(team_id)
str(Spaces, 3)
```
Folders within a specific Space defined by its `space_id`
```{r}
space_id <- Spaces$spaces[[2]]$id
Folders <- cu_get_folders(space_id)
str(Folders, 3)
```
Lists within a specific Folder defined by its `folder_id`
(or Folderless Lists based on `space_id`)
```{r}
folder_id <- Folders$folders[[1]]$id
Lists <- cu_get_lists(folder_id)
str(Lists, 3)
cu_get_lists_folderless(space_id)
```
The functions `cu_get_spaces`, `cu_get_folders`, and `cu_get_lists`
accept the argument `archived` to return archived spaces/folders/lists
```{r}
str(cu_get_lists(folder_id, archived=TRUE), 3)
```
### Tasks
We can list Tasks within a specific List defined by its `list_id`
```{r}
list_id <- Lists$lists[[1]]$id
Tasks <- cu_get_tasks(list_id)
str(Tasks, 2)
```
Notice that we have `r length(Tasks$tasks)` tasks in the list.
We can include Subtasks too
```{r}
subTasks <- cu_get_tasks(list_id, subtasks=TRUE)
length(subTasks$tasks)
```
Getting all the tasks (possibly filtered) in a Workspace
is done via the `cu_get_filtered_team_tasks` function.
This function returns tasks in batches of 100.
If you don't want to deal with paging, use the
wrapper function `cu_get_all_team_tasks`
The list of tasks returned does not include closed tasks,
to get those as well we need to pass the `include_closed`
query parameter
```{r}
## without closed tasks
length(cu_get_all_team_tasks(team_id, subtasks=TRUE)$tasks)
## with closed tasks
allSubTasks <- cu_get_all_team_tasks(team_id, subtasks=TRUE,
include_closed=TRUE)
length(allSubTasks$tasks)
Status <- sapply(allSubTasks$tasks, function(z) z$status$status)
data.frame(table(Status))
```
Let's inspect the first few elements of a Task object
```{r}
str(Tasks$tasks[[1]][1:10])
```
Dates are given as Unix time (in milliseconds),
`cu_date_from` and `cu_date_to` is there to convert back and forth
```{r}
Tasks$tasks[[1]]$date_created
cu_date_from(Tasks$tasks[[1]]$date_created)
cu_date_to(cu_date_from(Tasks$tasks[[1]]$date_created))
```
A single task can be accessed through the task ID
(note: copying the task ID from the ClickUp GUI will prepend
the task ID by a hash, `"#8ckjp5"`, but the API expects
ID without the hash `"8ckjp5"`). Use the `cu_task_id` function to get
rid of the leading hash (all API call use this function to
normalize task IDs).
The `$parent` property is `NULL` for Tasks, and
it contains the parent Task ID for Subtasks
```{r}
x1 <- cu_get_task(cu_task_id("#8ckjp5")) # task
x1$parent
x2 <- cu_get_task("8ckjru") # subtask
x2$parent
```
Dependencies are stored in the `$dependencies` property
```{r}
str(x1$dependencies)
```
### Helper functions
`cu_options` stores the API settings
```{r}
str(cu_options())
```
`cu_response` allows inspecting the response object
```{r}
cu_response(Teams)
```
Check rate limits and remaining requests (rate is limited by the minute)
```{r}
cu_ratelimit(subTasks)
```
### Formatting the request body
`PUSH` and `PUT` requests often require to send data as part of the
request body. Check the API examples and use `I()` when the API expects an
array as part of the body. For example when passing data to
`cu_create_task`, `assignees` is an array of the assignees'
userids to be added. Adding a single userid without `I()` will
drop the brackets, but
`list(name = "New Task Name", assignees = I(183))` will result in
the expected JSON object:
`{ "name": "New Task Name", "assignees": [183] }`.
### Attachments
We can upload files as attachments to tasks:
```{r eval=FALSE}
f <- file.path(tempdir(), "example.png")
png(f)
hist(rnorm(10^6), col=2, main="Example")
dev.off()
cu_post_task_attachment("8ach57", f)
unlink(f) # delete file
```
## Issues
https://github.com/psolymos/clickrup/issues
## License
[MIT](LICENSE) © 2020 Peter Solymos