From 425b49033d7628c653fafe4431c4d24d6373d0f3 Mon Sep 17 00:00:00 2001 From: JBGruber Date: Tue, 8 Oct 2024 16:14:10 +0200 Subject: [PATCH] implement playlist endpoint (#20) --- NAMESPACE | 2 ++ R/api_research.r | 46 ++++++++++++++++++++++++++++++++++++++++++ man/tt_playlist_api.Rd | 23 +++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 man/tt_playlist_api.Rd diff --git a/NAMESPACE b/NAMESPACE index 54dbc17..56f06ac 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,7 @@ S3method(print,traktok_query) S3method(print,tt_results) +export(auth_check) export(auth_hidden) export(auth_research) export(last_comments) @@ -18,6 +19,7 @@ export(tt_get_following) export(tt_get_following_hidden) export(tt_get_liked) export(tt_json) +export(tt_playlist_api) export(tt_query_videos) export(tt_request_hidden) export(tt_search) diff --git a/R/api_research.r b/R/api_research.r index e39ec20..d5b6011 100644 --- a/R/api_research.r +++ b/R/api_research.r @@ -629,6 +629,52 @@ tt_comments_api <- function(video_id, } +#' Lookup TikTok playlist using the research API +#' +#' @description \ifelse{html}{\figure{api-research.svg}{options: alt='[Works on: +#' Research API]'}}{\strong{[Works on: Research API]}} +#' +#' @param playlist_id playlist ID or URL to a playlist. +#' @inheritParams tt_user_info_api +#' +#' @return A data.frame +#' @export +tt_playlist_api <- function(playlist_id, + verbose = TRUE, + token = NULL) { + + # the docs mention a cursor, but it's not implemented as far as I can tell + cursor <- NULL + + if (grepl("/", playlist_id)) { + playlist_id <- extract_regex( + playlist_id, + "(?<=-)([0-9]+?)(?=\\?|$|/)" + ) + } + + if (is.null(token)) token <- get_token() + + out <- httr2::request("https://open.tiktokapis.com/v2/research/playlist/info/") |> + httr2::req_method("POST") |> + httr2::req_headers("Content-Type" = "application/json") |> + httr2::req_auth_bearer_token(token$access_token) |> + httr2::req_body_json(data = list(playlist_id = playlist_id, + cursor = cursor)) |> + httr2::req_error(is_error = function(resp) + # API always seems to send 500, even when successful + !httr2::resp_status(resp) %in% c(100:399, 500), + body = api_error_handler) |> + httr2::req_retry(max_tries = 5) |> + httr2::req_perform() |> + httr2::resp_body_json(bigint_as_char = TRUE) |> + purrr::pluck("data") |> + tibble::as_tibble() + + return(out) +} + + api_error_handler <- function(resp) { # failsafe save already collected videos to disk diff --git a/man/tt_playlist_api.Rd b/man/tt_playlist_api.Rd new file mode 100644 index 0000000..98fe35f --- /dev/null +++ b/man/tt_playlist_api.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/api_research.r +\name{tt_playlist_api} +\alias{tt_playlist_api} +\title{Lookup TikTok playlist using the research API} +\usage{ +tt_playlist_api(playlist_id, verbose = TRUE, token = NULL) +} +\arguments{ +\item{playlist_id}{playlist ID or URL to a playlist.} + +\item{verbose}{should the function print status updates to the screen?} + +\item{token}{The authentication token (usually supplied automatically after +running auth_research once)} +} +\value{ +A data.frame +} +\description{ +\ifelse{html}{\figure{api-research.svg}{options: alt='[Works on: + Research API]'}}{\strong{[Works on: Research API]}} +}