diff --git a/.gitignore b/.gitignore index 8feec7f..e02a896 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ _test .Rapp.history credentials.dta creating-credentials.r +.Rproj.user diff --git a/README.md b/README.md index dae9120..02b2800 100644 --- a/README.md +++ b/README.md @@ -1,232 +1,7 @@ Rfacebook: Access to Facebook API via R --------- -This package provides a series of functions that allow R users to access Facebook's API to get information about public pages, groups, and posts, as well as some of the authenticated user's private data. +Due to recent changes in Facebook's Graph API, all functions of the package now require a working app that has undergone App Review. More details are [available here](https://developers.facebook.com/docs/pages/). -Current CRAN release is 0.6.3. To install the most updated version (0.6.6) from GitHub using devtools, type: - -```r -library(devtools) -install_github("pablobarbera/Rfacebook/Rfacebook") -``` - -Click here to read the documentation. - -

Installation and authentication

- -Rfacebook can be installed directly from CRAN, but the most updated version will always be on GitHub. The code below shows how to install from both sources. - -```r -install.packages("Rfacebook") # from CRAN -library(devtools) -install_github("pablobarbera/Rfacebook/Rfacebook") # from GitHub - -``` - -Most API requests require the use of an access token. There are two ways of making authenticated requests with Rfacebook. One option is to generate a temporary token on the Graph API Explorer. Then just copy and paste the code into the R console and save it as a string vector to be passed as an argument to any Rfacebook function, as I show below. However, note that this access token will only be valid for two hours. It is possible to generate a 'long-lived' token (valid for two months) using the `fbOAuth` function, but the process is a bit more complicated. For a step-by-step tutorial, check this fantastic blog post by JulianHi. - -```r -# token generated here: https://developers.facebook.com/tools/explorer -token <- 'XXXXXXXX' -me <- getUsers("me", token, private_info=TRUE) -me$name # my name -# [1] "Pablo Barberá" -me$hometown # my hometown -# [1] "Cáceres, Spain" - -``` - -The example above shows how to retrieve information about a Facebook user. Note that this can be applied to obtain information about any user (or vector of users) with public profiles -- that is, pages. Both user screen names or IDs can be used as arguments, e.g.: - -```r -getUsers(c("barackobama", "donaldtrump"), token) - -``` - -This function cannot be used to obtain profile information for users with private profiles, with the exception of those profiles who are using the application created by the authenticated user. When using a temporary token, only the information of profiles who have ever created a temporary token in the authenticated user's network of friends will be returned. - -

Analyzing your network of friends

- -The function `getFriends` allows the user to capture information about their Facebook friends, as long as they are using the application created to authenticate with the API. Since user IDs are assigned in consecutive order, it's possible to find out which of our friends was the first one to open a Facebook account. - -```r -my_friends <- getFriends(token, simplify = TRUE) -head(my_friends$id, n = 1) # get lowest user ID - -``` - -To access additional information about a list of friends using the token application, you can use the `getUsers` function, which will return a data frame with users' Facebook data. Some of the variables that are available for all users are: gender, language, and country. It is also possible to obtain relationship status, hometown, birthday, and location for our friends if we set `private_info=TRUE`. (Note that language and country are extracted from the `locale` codes.) - -```r -my_friends_info <- getUsers(my_friends$id, token, private_info = TRUE) -table(my_friends_info$gender) # gender -table(substr(my_friends_info$locale, 1, 2)) # language -table(substr(my_friends_info$locale, 4, 5)) # country -table(my_friends_info$relationship_status) # relationship status -``` - -Finally, the function `getNetwork` extracts a list of all the mutual friendships among the friends using the application with which the token was created. This list can be then used to analyze and visualize a Facebook ego network. The first step is to use the `getNetwork` function. If the `format` option is set equal to `edgelist`, it will return a list of all the edges of that network. If `format=adj.matrix`, then it will return an adjacency matrix of dimensions (n x n), with n being the number of friends, and 0 or 1 indicating whether the user in row 'i' is also friends with user in column 'j'. - -```r -mat <- getNetwork(token, format = "adj.matrix") -dim(mat) # dimension of matrix -``` - -This adjacency matrix can then be converted into an igraph object, which facilitates the task of computing measures of centrality, discovering communities, or visualizing the structure of the network. As an illustration, the plot below displays my Facebook ego network, where the colors represent clusters discovered with a community detection algorithm, which clearly overlap with membership in offline communities. This was one of the examples from my workshop on data visualization with R and ggplot2. The code to replicate it with your own Facebook data is available here. David Smith has also posted code to generate a similar network plot. - -
Facebook ego network
- -Note that since version 2.0 of the Graph API, only the friends using the application with which the authenticated token was created are returned by this application. Old versions of the API are no longer available. - - -

Searching public Facebook posts

- -Prior to version 2.0 of the Graph API, it was possible to collect public Facebook posts mentioning specific keywords, using the `searchFacebook` function. This option is no longer available through the public API. - -

Analyzing data from a Facebook page

- -Facebook pages are probably the best source of information about how individuals use this social networking site, since all posts, likes, and comments can be collected combining the `getPage` and `getPost` functions. For example, assume that we're interested in learning about how the Facebook page Humans of New York has become popular, and what type of audience it has. The first step would be to retrieve a data frame with information about all of its posts using the code below. To make sure I collect every single post, I set `n` to a very high number, and the function will stop automatically when it reaches the total number of available posts (3,674). - -```r -page <- getPage("humansofnewyork", token, n = 5000) -page[which.max(page$likes_count), ] -## from_id from_name -## 1915 102099916530784 Humans of New York - message -## 1915 Today I met an NYU student named Stella. I took a photo of her. (...) -## created_time type -## 1915 2012-10-19T00:27:36+0000 photo -## link -## 1915 https://www.facebook.com/photo.php?fbid=375691212504985&set=a.102107073196735.4429.102099916530784&type=1&relevant_count=1 -## id likes_count comments_count -## 1915 102099916530784_375691225838317 894583 117337 -## shares_count -## 1915 60528 -``` - -The most popular post ever received almost 900,000 likes and 120,000 comments, and was shared over 60,000 times. As we can see, the variables returned for each post are the same as when we search for Facebook posts: information about the content of the post, its author, and its popularity and reach. Using this data frame, it is relatively straightforward to visualize how the popularity of Humans of New York has grown exponentially over time. The code below illustrates how to aggregate the metrics by month in order to compute the median count of likes/comments/shares per post: for example, in November 2013 the average post received around 40,000 likes. - -```r -## convert Facebook date format to R date format -format.facebook.date <- function(datestring) { - date <- as.POSIXct(datestring, format = "%Y-%m-%dT%H:%M:%S+0000", tz = "GMT") -} -## aggregate metric counts over month -aggregate.metric <- function(metric) { - m <- aggregate(page[[paste0(metric, "_count")]], list(month = page$month), - mean) - m$month <- as.Date(paste0(m$month, "-15")) - m$metric <- metric - return(m) -} -# create data frame with average metric counts per month -page$datetime <- format.facebook.date(page$created_time) -page$month <- format(page$datetime, "%Y-%m") -df.list <- lapply(c("likes", "comments", "shares"), aggregate.metric) -df <- do.call(rbind, df.list) -# visualize evolution in metric -library(ggplot2) -library(scales) -ggplot(df, aes(x = month, y = x, group = metric)) + geom_line(aes(color = metric)) + - scale_x_date(breaks = "years", labels = date_format("%Y")) + scale_y_log10("Average count per post", - breaks = c(10, 100, 1000, 10000, 50000)) + theme_bw() + theme(axis.title.x = element_blank()) -``` - -
- -It is also possible to subset posts by date. For example, imagine we want to get only posts posted during 2015: - -```r -page <- getPage("humansofnewyork", token, n = 5000, since='2015/01/01', until='2015/12/31') -``` - -To retrieve more information about each individual post, you can use the `getPost` function, which will return the same variables as above, as well as a list of comments and likes. Continuing with my example, the code below shows how to collect a list of 1,000 users who liked the most recent post, for which we will also gather information in order to analyze the audience of this page in terms of gender, language, and country. - -```r -post_id <- head(page$id, n = 1) ## ID of most recent post -post <- getPost(post_id, token, n = 1000, likes = TRUE, comments = FALSE) -``` - -

Analyzing data from a Facebook group

- -Just like public Facebook pages, the data from public groups can also be easily downloaded with the `getGroup` function. Note that this will only work for groups that the authenticated user is a member of. - -```r -group <- getGroup("150048245063649", token, n=50) -``` - - -

Extracting personal information

- -Rfacebook also allows to read personal information about the authenticated user, such as the list of likes and the content from the Newsfeed. Private information about the user's friends is no longer available through the API. - -```r -getLikes('me', token)[1,] -## id names -## 1 687958677914631 FiveThirtyEight -## website -## 1 http://www.fivethirtyeight.com/ -``` -```r -getNewsfeed(token, n=1) -## 1 51191684997 Rob DenBleyker -## message -## 1 Sorry for the late comic, it's up now!\n\nhttp://explosm.net/comics/3512/ -## created_time type link -## 1 2014-04-02T12:38:46+0000 link http://explosm.net/comics/3512/ -## id likes_count comments_count shares_count -## 1 51191684997_10152084439949998 6942 110 497 -``` - -

Executing other API calls

- -To facilitate making API queries not implemented in the current version of the package, I have added the `callAPI` function, which will return an R list with the result of the query. A trivial example: - -```r -callAPI("https://graph.facebook.com/v2.0/barackobama?fields=id", token) -``` - -

Page insights

- -Rfacebook provides some limited access to the insights features, available admin accounts of public pages. See the documentation of `getInsights` for more information. - - -

Updating your Facebook status from R

- -Finally, yes: - -```r -updateStatus("You can also update your Facebook status from R", token) -## Success! Link to status update: -## http://www.facebook.com/557698085_10152090718708086 -``` - -However, to make this work you will need to get a long-lived OAuth token first, setting `private_info=TRUE` in the `fbOAUth` function. - -

Frequently Asked Questions

- -- How can I search public Facebook posts? Can I get any information from users' private profiles? How can I extract my entire network of friends? - -All these features used to be available through the API, but unfortunately that's not the case anymore. There's no fix to Rfacebook that could bring back these features. - -- I get the following error when I run `getUsers`: `username is deprecated for versions v2.0 and higher` - -This is related to the previous question. It is no longer possible to query users by their user names. If the user is a public page, try with the page ID number. - -- For any other questions, feature requests, or bugs, please open an issue in this repository. - - - +__NOTE:__ This package is currently not being maintained and issues are not monitored. diff --git a/Rfacebook/ChangeLog b/Rfacebook/ChangeLog index a01dc72..429f25a 100644 --- a/Rfacebook/ChangeLog +++ b/Rfacebook/ChangeLog @@ -58,3 +58,30 @@ - other minor fixes 2016-07-12 - version 0.6.7 - added getCommentReplies function to scrape nested comments +2016-07-26 - version 0.6.8 + - getGroup function now has feed option to return only admin posts +2016-08-16 - version 0.6.9 + - added story field to getPage +2016-10-23 - version 0.6.10 + - fixed bug in getPage with reactions=T in posts with no reactions +2016-12-28 - version 0.6.11 + - added verbose option to getPage +2017-01-21 - version 0.6.12 + - added support for reactions in getPost + - added support for multiple API versions in callAPI +2017-02-17 - version 0.6.13 + - fixes in getInsights +2017-04-21 - version 0.6.14 + - fixes in fbOAuth +2017-05-24 - version 0.6.15 + - adds getEvents + - updates in searchPages + - minor fixes +2017-06-01 - version 0.6.16 + - documentation updates + - searchGroups now returns 25+ results +2017-07-11 - version 0.6.17 + - getUsers now works with recent versions of API + - getMembers function added (thanks Yan Turgeon) +2018-02-08 - version 0.6.18 + - getCommentReplies() returns NA for from field when API does not return it diff --git a/Rfacebook/DESCRIPTION b/Rfacebook/DESCRIPTION index 2e3e31d..0503df6 100644 --- a/Rfacebook/DESCRIPTION +++ b/Rfacebook/DESCRIPTION @@ -1,10 +1,10 @@ Package: Rfacebook Title: Access to Facebook API via R Description: Provides an interface to the Facebook API. -Version: 0.6.7 -Date: 2016-07-12 +Version: 0.6.18 +Date: 2018-02-08 Author: Pablo Barbera , Michael Piccirilli - , Andrew Geisler + , Andrew Geisler, Wouter van Atteveldt, Yan Turgeon Maintainer: Pablo Barbera URL: https://github.com/pablobarbera/Rfacebook BugReports: https://github.com/pablobarbera/Rfacebook/issues @@ -14,4 +14,4 @@ Depends: rjson, httpuv License: GPL-2 -RoxygenNote: 5.0.1 +RoxygenNote: 6.0.1 diff --git a/Rfacebook/NAMESPACE b/Rfacebook/NAMESPACE index e057bf6..3c9bab1 100644 --- a/Rfacebook/NAMESPACE +++ b/Rfacebook/NAMESPACE @@ -4,14 +4,17 @@ export(callAPI) export(fbOAuth) export(getCheckins) export(getCommentReplies) +export(getEvents) export(getFQL) export(getFriends) export(getGroup) export(getInsights) export(getLikes) +export(getMembers) export(getNetwork) export(getNewsfeed) export(getPage) +export(getPageToken) export(getPost) export(getReactions) export(getShares) @@ -23,4 +26,7 @@ export(updateStatus) import(httpuv) import(httr) import(rjson) -importFrom("utils", "URLencode", "packageVersion", "setTxtProgressBar", "txtProgressBar") +importFrom(utils,URLencode) +importFrom(utils,packageVersion) +importFrom(utils,setTxtProgressBar) +importFrom(utils,txtProgressBar) diff --git a/Rfacebook/R/Rfacebook-package.R b/Rfacebook/R/Rfacebook-package.R index 5346b5a..4ce38ea 100644 --- a/Rfacebook/R/Rfacebook-package.R +++ b/Rfacebook/R/Rfacebook-package.R @@ -11,7 +11,8 @@ #' @name Rfacebook-package #' @aliases Rfacebook #' @docType package -#' @author Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' @author Pablo Barbera \email{pbarbera@@usc.edu} #' @import httr rjson httpuv +#' @importFrom utils URLencode packageVersion setTxtProgressBar txtProgressBar NULL diff --git a/Rfacebook/R/fbOAuth.R b/Rfacebook/R/fbOAuth.R index 6d6a148..6b4da3b 100644 --- a/Rfacebook/R/fbOAuth.R +++ b/Rfacebook/R/fbOAuth.R @@ -51,7 +51,7 @@ #' #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{searchFacebook}} #' #' @param app_id numeric, App ID of application to be used to create OAUth token. Available @@ -72,6 +72,7 @@ #' @param legacy_permissions For tokens created with old versions of the API, this option #' adds the "read_stream" permission #' +#' @param scope Specify an explicit lists of permissions to ask (overrides extended_permissions) #' #' @examples \dontrun{ #' ## an example of an authenticated request after creating the OAuth token @@ -90,8 +91,9 @@ #' -fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permissions=FALSE) +fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permissions=FALSE, scope=NULL) { + ## getting callback URL full_url <- oauth_callback() full_url <- gsub("(.*localhost:[0-9]{1,5}/).*", x=full_url, replacement="\\1") @@ -104,16 +106,18 @@ fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permi authorize = "https://www.facebook.com/dialog/oauth", access = "https://graph.facebook.com/oauth/access_token") myapp <- oauth_app("facebook", app_id, app_secret) - if (extended_permissions==TRUE){ - scope <- c("user_birthday", "user_hometown", "user_location", "user_relationships", - "publish_actions","user_status","user_likes") + if (is.null(scope)) { + if (extended_permissions==TRUE){ + scope <- c("user_birthday", "user_hometown", "user_location", "user_relationships", + "publish_actions","user_status","user_likes") + } + else { scope <- c("public_profile", "user_friends")} + + if (legacy_permissions==TRUE) { + scope <- c(scope, "read_stream") + } } - else { scope <- c("public_profile", "user_friends")} - if (legacy_permissions==TRUE) { - scope <- c(scope, "read_stream") - } - if (packageVersion('httr') < "1.2"){ stop("Rfacebook requires httr version 1.2.0 or greater") } @@ -123,7 +127,7 @@ fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permi ## with early httr versions if (packageVersion('httr') <= "0.2"){ facebook_token <- oauth2.0_token(facebook, myapp, - scope=scope, type = "application/x-www-form-urlencoded") + scope=scope) fb_oauth <- sign_oauth2.0(facebook_token$access_token) if (GET("https://graph.facebook.com/me", config=fb_oauth)$status==200){ message("Authentication successful.") @@ -133,7 +137,7 @@ fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permi ## less early httr versions if (packageVersion('httr') > "0.2" & packageVersion('httr') <= "0.6.1"){ fb_oauth <- oauth2.0_token(facebook, myapp, - scope=scope, type = "application/x-www-form-urlencoded", cache=FALSE) + scope=scope, cache=FALSE) if (GET("https://graph.facebook.com/me", config(token=fb_oauth))$status==200){ message("Authentication successful.") } @@ -143,7 +147,7 @@ fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permi if (packageVersion('httr') > "0.6.1" & packageVersion('httr') < "1.2"){ Sys.setenv("HTTR_SERVER_PORT" = "1410/") fb_oauth <- oauth2.0_token(facebook, myapp, - scope=scope, type = "application/x-www-form-urlencoded", cache=FALSE) + scope=scope, cache=FALSE) if (GET("https://graph.facebook.com/me", config(token=fb_oauth))$status==200){ message("Authentication successful.") } @@ -152,7 +156,7 @@ fbOAuth <- function(app_id, app_secret, extended_permissions=FALSE, legacy_permi ## httr version after 1.2 if (packageVersion('httr') >= "1.2"){ fb_oauth <- oauth2.0_token(facebook, myapp, - scope=scope, type = "application/x-www-form-urlencoded", cache=FALSE) + scope=scope, cache=FALSE) if (GET("https://graph.facebook.com/me", config(token=fb_oauth))$status==200){ message("Authentication successful.") } diff --git a/Rfacebook/R/getCheckins.R b/Rfacebook/R/getCheckins.R index ed6922d..fd4c6fc 100644 --- a/Rfacebook/R/getCheckins.R +++ b/Rfacebook/R/getCheckins.R @@ -15,7 +15,7 @@ #' Check-in search was deprecated with version 2.0 of the Facebook Graph API. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getFriends}} #' #' @param token Either a temporary access token created at @@ -30,25 +30,27 @@ #' elements: a data frame with user's checkins and a list of data frames, #' where each element contains information about users tagged in each checkin. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' @examples \dontrun{ #' token <- 'XXXXX' #' my_checkins <- getCheckins(user="me", token=token) #' } #' -getCheckins <- function(user, n=10, token, tags=FALSE){ +getCheckins <- function(user, n=10, token, tags=FALSE, api=NULL){ tkversion <- getTokenVersion(token) if (tkversion=="v2"){ - stop("Searching for posts was deprecated with version 2.0 of", + stop("Searching for check-ins was deprecated with version 2.0 of", " the Facebook Graph API.\nFor more details see ?getCheckins") } query <- paste0('https://graph.facebook.com/', user, '?fields=checkins.limit(', n, ').fields(tags,created_time,', 'place.fields(id,name,location))') - content <- callAPI(query, token) + content <- callAPI(query, token, api=api) if (length(content$checkins)>0){ df <- checkinDataToDF(content$checkins$data) if (tags) {tags.df <- tagsDataToDF(content$checkins$data)} diff --git a/Rfacebook/R/getCommentReplies.R b/Rfacebook/R/getCommentReplies.R index b930140..46b79bf 100644 --- a/Rfacebook/R/getCommentReplies.R +++ b/Rfacebook/R/getCommentReplies.R @@ -16,6 +16,10 @@ #' to the comment (author, message, creation time, id). Finally, \code{likes} is #' data frame that contains names and Facebook IDs of all the users that liked the comment. #' +#' Note that user information (from_id and from_name) are only returned if the token used +#' to authenticate is a Page access token. For more information, see: +#' \url{https://developers.facebook.com/docs/graph-api/reference/v2.10/comment} +#' #' @author #' Yan Turgeon #' @seealso \code{\link{getPage}}, \code{\link{getPost}} @@ -39,6 +43,8 @@ #' @param n.replies numeric, maximum number of replies to return. Default is #' \code{n}. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' @examples \dontrun{ #' ## See examples for fbOAuth to know how token was created. #' ## Getting information about Facebook's Facebook Page @@ -47,12 +53,12 @@ #' ## Getting information and likes/comments about most recent post #' post <- getPost(post=fb_page$id[1], n=2000, token=fb_oauth) #' ## Downloading list of replies to first comment -#' replies <- getCommentReplies(comment_id=post$id[1], token=fb_oauth) +#' replies <- getCommentReplies(comment_id=post$comments$id[1], token=fb_oauth) #' } #' getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALSE, n.likes=n, - n.replies=n){ + n.replies=n, api=NULL){ url <- paste0("https://graph.facebook.com/", comment_id, "?fields=from,message,created_time,like_count,comment_count") #return initial comments @@ -93,7 +99,7 @@ getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALS cat("Error!\n") Sys.sleep(0.5) error <- error + 1 - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) if (error==3){ stop(content$error_msg) } } if (length(content)==0){ @@ -124,7 +130,7 @@ getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALS if (!is.null(url.likes) && likes && n.likes > n.l){ # retrieving next batch of likes url <- content$likes$paging$`next` - content <- callAPI(url=url.likes, token=token) + content <- callAPI(url=url.likes, token=token, api=api) out[["likes"]] <- rbind(out[["likes"]], likesDataToDF(content$data)) n.l <- dim(out$likes)[1] @@ -132,7 +138,7 @@ getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALS while (n.l < n.likes & length(content$data)>0 & !is.null(url <- content$paging$`next`)){ url <- content$paging$`next` - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) out[["likes"]] <- rbind(out[["likes"]], likesDataToDF(content$data)) n.l <- dim(out$likes)[1] @@ -140,7 +146,7 @@ getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALS } if (!is.null(url.comments) && replies && n.replies > n.c){ # retriving next batch of comments - content <- callAPI(url=url.comments, token=token) + content <- callAPI(url=url.comments, token=token, api=api) out[["replies"]] <- rbind(out[["replies"]], repliesDataToDF(content$data)) n.c <- dim(out$replies)[1] @@ -148,7 +154,7 @@ getCommentReplies <- function(comment_id, token, n=500, replies=TRUE, likes=FALS while (n.c < n.replies & length(content$data)>0 & !is.null(content$paging$`next`)){ url <- content$paging$`next` - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) out[["replies"]] <- rbind(out[["replies"]], repliesDataToDF(content$data)) n.c <- dim(out$replies)[1] diff --git a/Rfacebook/R/getEvents.R b/Rfacebook/R/getEvents.R new file mode 100644 index 0000000..0304a0d --- /dev/null +++ b/Rfacebook/R/getEvents.R @@ -0,0 +1,56 @@ +#' @rdname getEvents +#' @export +#' +#' @title +#' Extract list of events from a public Facebook page or group +#' +#' @description +#' \code{getEvents} retrieves event information from a public Facebook group or page. +#' +#' @author +#' Pablo Barbera \email{pbarbera@@usc.edu} +#' @seealso \code{\link{getPage}}, \code{\link{fbOAuth}} +#' +#' @param page Facebook ID for the group or page. +#' +#' @param token Either a temporary access token created at +#' \url{https://developers.facebook.com/tools/explorer} or the OAuth token +#' created with \code{fbOAuth}. +#' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' +#' @examples \dontrun{ +#' load("fb_oauth") +#' ## Downloading events from Playa Vista Farmers' Market +#' events <- getEvents(page="playavistaFM", token=fb_oauth) +#' } + +getEvents <- function(page, token, api="v2.9"){ + + url <- paste0('https://graph.facebook.com/', page, + '?fields=events{description,name,start_time,end_time,place,id,attending_count,', + 'declined_count,maybe_count,noreply_count}') + + # making query + content <- callAPI(url=url, token=token, api=api) + l <- length(content$events$data); cat(l, "events ") + + ## retrying 3 times if error was found + error <- 0 + while (length(content$error_code)>0){ + cat("Error!\n") + Sys.sleep(0.5) + error <- error + 1 + content <- callAPI(url=url, token=token, api=api) + if (error==3){ stop(content$error_msg) } + } + if (length(content$events$data)==0){ + message("No public events were found") + return(data.frame()) + } + df <- eventDataToDF(content$events$data) + + return(df) +} + + diff --git a/Rfacebook/R/getFQL.R b/Rfacebook/R/getFQL.R index c43ecc6..4b296e3 100644 --- a/Rfacebook/R/getFQL.R +++ b/Rfacebook/R/getFQL.R @@ -10,7 +10,7 @@ #' an overview of the Facebook Query Language. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' #' @param query Text of query #' diff --git a/Rfacebook/R/getFriends.R b/Rfacebook/R/getFriends.R index b8dd6f9..70c72db 100644 --- a/Rfacebook/R/getFriends.R +++ b/Rfacebook/R/getFriends.R @@ -15,7 +15,7 @@ #' token to query the API will be returned. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getUsers}}, \code{\link{fbOAuth}} #' #' @param token Either a temporary access token created at diff --git a/Rfacebook/R/getGroup.R b/Rfacebook/R/getGroup.R index b350560..d3dcc31 100644 --- a/Rfacebook/R/getGroup.R +++ b/Rfacebook/R/getGroup.R @@ -8,7 +8,7 @@ #' \code{getGroup} retrieves information from a public Facebook group. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{fbOAuth}} #' #' @param group_id Facebook ID for the group. Note that this is different from @@ -33,6 +33,8 @@ #' that were made by others (not only the admin of the group). Note that, unlike #' in \code{getPage}, here \code{TRUE} is the default option. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' #' @examples \dontrun{ #' ## Find Facebook ID for R-Users Facebook group @@ -46,7 +48,7 @@ #' since='2013/01/01', until='2013/01/31') #' } -getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ +getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE, api=NULL){ url <- paste0('https://graph.facebook.com/', group_id, '/posts?fields=from,message,created_time,type,link,comments.summary(true)', @@ -69,7 +71,7 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ url <- paste0(url, "&limit=25") } # making query - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) l <- length(content$data); cat(l, "posts ") ## retrying 3 times if error was found @@ -78,7 +80,7 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ cat("Error!\n") Sys.sleep(0.5) error <- error + 1 - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) if (error==3){ stop(content$error_msg) } } if (length(content$data)==0){ @@ -107,7 +109,7 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ # waiting one second before making next API call... Sys.sleep(0.5) url <- content$paging$`next` - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) l <- l + length(content$data) if (length(content$data)>0){ cat(l, "posts ") } @@ -117,7 +119,7 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ cat("Error!\n") Sys.sleep(0.5) error <- error + 1 - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) if (error==3){ stop(content$error_msg) } } new.df <- pageDataToDF(content$data) @@ -153,7 +155,11 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ #' @param token Either a temporary access token created at #' \url{https://developers.facebook.com/tools/explorer} or the OAuth token #' created with \code{fbOAuth}. - +#' +#' @param n Number of groups to return. Default is up to 25. +#' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' @examples \dontrun{ #' ## Find Facebook ID for R-Users Facebook group #' load("fb_oauth") @@ -166,11 +172,11 @@ getGroup <- function(group_id, token, n=25, since=NULL, until=NULL, feed=TRUE){ #' since='2013/01/01', until='2013/01/31') #' } -searchGroup <- function(name, token){ +searchGroup <- function(name, token, n=25, api=NULL){ url <- paste0('https://graph.facebook.com/search?q=', - name, '&type=group') + name, '&type=group&limit=', n) # making query - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) # if no data, return error message if (length(content$data)==0){ diff --git a/Rfacebook/R/getInsights.R b/Rfacebook/R/getInsights.R index ebe99e4..9e03927 100644 --- a/Rfacebook/R/getInsights.R +++ b/Rfacebook/R/getInsights.R @@ -10,6 +10,8 @@ #' To request multiple metrics at one time, pass a vector of metric names with a vector #' of periods of the same length. If only one period is supplied, it will apply to each metric. #' Please refer to Facebook's documentation for valid combinations of objects, metrics and periods. +#' +#' Note that some insights require a page access token, see \code{getPageToken} #' #' @details #' The current list of supported metrics and periods is: page_fan_adds, page_fan_removes, @@ -85,11 +87,12 @@ getInsights <- function(object_id, token, metric, period='day', parms=NA, versio } ## CHECK IF DATE IS MORE THAN TWO YEARS OLD - since_date <- as.Date(gsub('.*since=([0-9]{4}-[0-9]{2}-[0-9]{2}).*', parms, repl="\\1")) - if (Sys.Date() - since_date > 365 * 2){ - message("Note: metrics older than 2 years may not be available through the API.") + since_date <- as.Date(gsub('.*since=([0-9]{4}-[0-9]{2}-[0-9]{2}).*', parms, replacement="\\1")) + if (!is.na(since_date)){ + if (Sys.Date() - since_date > 365 * 2){ + message("Note: metrics older than 2 years may not be available through the API.") + } } - ### CREATE LIST OF REQUEST URLS url <- list() for (i in 1:length(metric)) { diff --git a/Rfacebook/R/getLikes.R b/Rfacebook/R/getLikes.R index d6de5cd..8a0994a 100644 --- a/Rfacebook/R/getLikes.R +++ b/Rfacebook/R/getLikes.R @@ -2,27 +2,27 @@ #' @export #' #' @title -#' Extract list of likes of a Facebook friend +#' Extract list of likes of the authenticated Facebook user #' #' @description -#' \code{getLikes} retrieves information about a friend's likes. -#' To retrieve the number of likes for a page, use \code{getUsers} -#' with the page IDs. +#' \code{getLikes} retrieves information about the authenticated use +#' only (not any friend). To retrieve the number of likes for a page, +#' use \code{getUsers} with the page IDs. #' #' @details #' #' This function requires the use of an OAuth token with the following -#' permissions: user_likes, friends_likes +#' permission: user_likes #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getFriends}}, \code{\link{fbOAuth}} #' #' @param token Either a temporary access token created at #' \url{https://developers.facebook.com/tools/explorer} or the OAuth token #' created with \code{fbOAuth}. #' -#' @param user A user ID or screen name. +#' @param user The name of the user. By default, "me". #' #' @param n Maximum number of likes to return for each user. #' @@ -32,7 +32,7 @@ #' } #' -getLikes <- function(user, n=500, token){ +getLikes <- function(user="me", n=500, token){ query <- paste0('https://graph.facebook.com/', user, '?fields=likes.limit(', n, ').fields(id,name,website)') content <- callAPI(query, token) diff --git a/Rfacebook/R/getMembers.R b/Rfacebook/R/getMembers.R new file mode 100644 index 0000000..8410f2b --- /dev/null +++ b/Rfacebook/R/getMembers.R @@ -0,0 +1,51 @@ +#' @rdname getMembers +#' @export +#' @title +#' Retrieve members from a public group +#' +#' @description +#' \code{getMembers} retrieves members from a public group, up to 5000 members. +#' +#' @param page A group ID +#' +#' @author +#' Yan Turgeon +#' @seealso \code{\link{getPage}}, \code{\link{getPost}}, \code{\link{getCommentReplies}} + +#' @param token Either a temporary access token created at +#' \url{https://developers.facebook.com/tools/explorer} or the OAuth token +#' created with \code{fbOAuth}. +#' +#' @examples \dontrun{ +#' ## Find Facebook ID for R-Users Facebook group +#' load("fb_oauth") +#' ids <- searchGroup(name="rusers", token=fb_oauth) +#' ids[1,] # id = 18533493739 +#' ## Retrieves members ID for R-Users Facebook group +#' members <- getMembers(group_id="18533493739", token=fb_oauth) +#'} + +getMembers <- function(group_id, token, n=5000, api=NULL){ + url <- paste0('https://graph.facebook.com/', group_id, + '/members?fields=id,name,first_name,last_name,administrator&limit=', n) + + # making query + content <- callAPI(url=url, token=token) + + #if no data, return error message + if (length(content$data)==0){ + message("No groups with this name were found.") + return(data.frame()) + } + + # if data, return a data frame + df <- data.frame( + name = unlist(lapply(content$data, '[[', 'name')), + first_name = unlist(lapply(content$data, '[[', 'first_name')), + last_name = unlist(lapply(content$data, '[[', 'last_name')), + id = unlist(lapply(content$data, '[[', 'id')), + administrator = unlist(lapply(content$data, '[[', 'administrator')), + stringsAsFactors=F) + + return(df) +} diff --git a/Rfacebook/R/getNetwork.R b/Rfacebook/R/getNetwork.R index 0949762..4ed3ce6 100644 --- a/Rfacebook/R/getNetwork.R +++ b/Rfacebook/R/getNetwork.R @@ -17,7 +17,7 @@ #' only friends who are using the application will be returned. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getFriends}}, \code{\link{fbOAuth}} #' #' @param token Either a temporary access token created at diff --git a/Rfacebook/R/getNewsfeed.R b/Rfacebook/R/getNewsfeed.R index da7d2c1..e62e654 100644 --- a/Rfacebook/R/getNewsfeed.R +++ b/Rfacebook/R/getNewsfeed.R @@ -9,7 +9,7 @@ #' News Feed #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{fbOAuth}}, \code{\link{getPost}} #' #' @param token Either a temporary access token created at diff --git a/Rfacebook/R/getPage.R b/Rfacebook/R/getPage.R index 5afbf15..2199b88 100644 --- a/Rfacebook/R/getPage.R +++ b/Rfacebook/R/getPage.R @@ -18,8 +18,12 @@ #' field in the post objects, and not the \code{created_time}. As a result, this function #' might return old posts that have been updated recently. #' +#' \code{comments_count} refers to the total of comments, including nested comments (replies). +#' It might be different from the total number of comments available through the API if +#' some comments have been deleted. +#' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{fbOAuth}} #' #' @param page A page ID or page name. @@ -45,7 +49,10 @@ #' @param reactions If \code{TRUE}, will add variables to the data frame with #' the total count of reactions: love, haha, wow, sad, angry. #' +#' @param verbose If \code{TRUE}, will report a number of the posts retrieved. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' @examples \dontrun{ #' ## See examples for fbOAuth to know how token was created. #' ## Getting information about Facebook's Facebook Page @@ -61,14 +68,15 @@ #' -getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, reactions=FALSE){ +getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, reactions=FALSE, + verbose=TRUE, api=NULL){ url <- paste0('https://graph.facebook.com/', page, - '/posts?fields=from,message,created_time,type,link,comments.summary(true)', + '/posts?fields=from,message,created_time,type,link,story,comments.summary(true)', ',likes.summary(true),shares') if (feed){ url <- paste0('https://graph.facebook.com/', page, - '/feed?fields=from,message,created_time,type,link,comments.summary(true)', + '/feed?fields=from,message,created_time,type,link,story,comments.summary(true)', ',likes.summary(true),shares') } if (!is.null(until)){ @@ -84,8 +92,8 @@ getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, react url <- paste0(url, "&limit=25") } # making query - content <- callAPI(url=url, token=token) - l <- length(content$data); cat(l, "posts ") + content <- callAPI(url=url, token=token, api=api) + l <- length(content$data); if (verbose) cat(l, "posts ") ## retrying 3 times if error was found error <- 0 @@ -97,7 +105,7 @@ getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, react if (error==3){ stop(content$error_msg) } } if (length(content$data)==0){ - message("No public posts were found") + message("No public posts were found : ", page) return(data.frame()) } df <- pageDataToDF(content$data) @@ -122,9 +130,9 @@ getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, react # waiting one second before making next API call... Sys.sleep(0.5) url <- content$paging$`next` - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) l <- l + length(content$data) - if (length(content$data)>0){ cat(l, "posts ") } + if (length(content$data)>0){ if (verbose) cat(l, "posts ") } ## retrying 3 times if error was found error <- 0 @@ -132,7 +140,7 @@ getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, react cat("Error!\n") Sys.sleep(0.5) error <- error + 1 - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) if (error==3){ stop(content$error_msg) } } new.df <- pageDataToDF(content$data) @@ -158,7 +166,7 @@ getPage <- function(page, token, n=25, since=NULL, until=NULL, feed=FALSE, react # adding reactions data if (reactions==TRUE){ - re = getReactions(df$id, token=token, verbose=FALSE) + re = getReactions(df$id, token=token, verbose=FALSE, api=api) df <- merge(df, re, all.x=TRUE) # sorting df <- df[order(df$created_time),] diff --git a/Rfacebook/R/getPageToken.R b/Rfacebook/R/getPageToken.R new file mode 100644 index 0000000..9faabb4 --- /dev/null +++ b/Rfacebook/R/getPageToken.R @@ -0,0 +1,29 @@ +#' @rdname getPageToken +#' @export +#' +#' @title +#' Get a page access token +#' +#' @description +#' Gets a page access token that can be used to e.g. get insights for a page. +#' +#' @param page A page ID or page name. +#' +#' @param token the token (with scope 'manage_pages') of a user that has admin access to the page +#' +#' @return the page access token string +#' +#' @examples +#' \dontrun{ +#' ## Get a normal access token with manage_pages scope +#' token = fbOAuth(app_id, app_secret, scope="manage_pages") +#' ## Get a page access token for a page +#' page_token = getPageToken(page, token) +#' ## Get page insights +#' getInsights(page, token=page_token, metric = "page_impressions") +#' } +getPageToken <- function(page, token) +{ + url = paste0("https://graph.facebook.com/", page, "?fields=access_token") + callAPI(url, token=token)$access_token +} \ No newline at end of file diff --git a/Rfacebook/R/getPost.R b/Rfacebook/R/getPost.R index cdcc686..2daeeb5 100644 --- a/Rfacebook/R/getPost.R +++ b/Rfacebook/R/getPost.R @@ -9,16 +9,20 @@ #' list of comments and likes. #' #' @details -#' \code{getPost} returns a list with three components: \code{post}, -#' \code{likes}, and \code{comments}. First, \code{post} contains information -#' about the post: author, creation date, id, counts of likes, comments, and -#' shares, etc. Second, \code{likes} is a data frame that contains names and -#' Facebook IDs of all the users that liked the post. Finally, \code{comments} -#' is a data frame with information about the comments to the post (author, -#' message, creation time, id). +#' \code{getPost} returns a list with up to four components: \code{post}, +#' \code{likes}, \code{comments}, and \code{reactions}. +#' \code{post} contains information about the post: author, creation date, id, +#' counts of likes, comments, and shares, etc. +#' \code{likes} is a data frame that contains names and Facebook IDs of all +#' the users that liked the post. +#' \code{comments} is a data frame with information about the comments to +#' the post (author, message, creation time, id). To download also the replies +#' to specific comments, see \code{\link{getCommentReplies}}. Note that the total +#' number of comments may be different from the number report in \code{comments_count} +#' if some comments have been deleted. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getUsers}}, \code{\link{getPage}}, \code{\link{fbOAuth}} #' #' @param post A post ID @@ -32,13 +36,21 @@ #' @param comments logical, default is \code{TRUE}, which will return data frame #' with comments to the post. #' -#' @param likes logical, default is \code{TRUE}, which will return data frame +#' @param likes logical, default is \code{TRUE} unless reactions is true, which will return data frame #' with likes for the post. +#' +#' @param reactions logical, default is \code{FALSE}, which will return data frame with reactions (like, love, etc) for the post #' #' @param n.likes numeric, maximum number of likes to return. Default is \code{n}. #' -#' @param n.comments numeric, maximum number of likes to return. Default is +#' @param n.comments numeric, maximum number of comments to return. Default is #' \code{n}. +#' +#' @param n.reactions numeric, maximum number of reactions to return. Default is +#' \code{n}. +#' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' #' @examples \dontrun{ #' ## See examples for fbOAuth to know how token was created. @@ -50,8 +62,8 @@ #' } #' -getPost <- function(post, token, n=500, comments=TRUE, likes=TRUE, n.likes=n, - n.comments=n){ +getPost <- function(post, token, n=500, comments=TRUE, likes=(!reactions), reactions=FALSE, n.likes=n, + n.comments=n, n.reactions=n, api=NULL){ url <- paste0("https://graph.facebook.com/", post, "?fields=from,message,created_time,type,link,name,shares") @@ -82,10 +94,20 @@ getPost <- function(post, token, n=500, comments=TRUE, likes=TRUE, n.likes=n, if (likes==FALSE){ url <- paste0(url, ",likes.summary(true)") } - + if (reactions==TRUE){ + url <- paste0(url, ",reactions.summary(true).", + "fields(id,type,name)") + if (n.reactions>=2000){ + url <- paste0(url, ".limit(2000)") + } + if (n.reactions<2000){ + url <- paste0(url, ".limit(", n.likes, ")") + } + } + # making query - content <- callAPI(url=url, token=token) - + content <- callAPI(url=url, token=token, api=api) + # error traps: retry 3 times if error error <- 0 while (length(content$error_code)>0){ @@ -110,19 +132,26 @@ getPost <- function(post, token, n=500, comments=TRUE, likes=TRUE, n.likes=n, if (comments && n.likes > 0) n.c <- ifelse(!is.null(out$comments), dim(out$comments)[1], 0) if (n.comments == 0) n.c <- 0 if (!comments) n.c <- Inf + if (reactions && n.reactions > 0) out[["reactions"]] <- reactionsDataToDF(content$reactions$data) + if (reactions && n.reactions > 0) n.r <- ifelse(!is.null(out$reactions), dim(out$reactions)[1], 0) + if (n.reactions == 0) n.r <- 0 + if (!reactions) n.r <- Inf + # paging if we n.comments OR n.likes haven't been downloaded - if (n.likes > n.l || n.comments > n.c){ + if (n.likes > n.l || n.comments > n.c || n.reactions > n.r){ # saving URLs for next batch of likes and comments if (likes) url.likes <- content$likes$paging$`next` if (!likes) url.likes <- NULL if (comments) url.comments <- content$comments$paging$`next` if (!comments) url.comments <- NULL + if (reactions) url.reactions <- content$reactions$paging$`next` + if (!reactions) url.reactions <- NULL - if (!is.null(url.likes) && likes && n.likes > n.l){ + if (!is.null(url.likes) && likes && n.l > 0 && n.likes > n.l){ # retrieving next batch of likes url <- content$likes$paging$`next` - content <- callAPI(url=url.likes, token=token) + content <- callAPI(url=url.likes, token=token, api=api) out[["likes"]] <- rbind(out[["likes"]], likesDataToDF(content$data)) n.l <- dim(out$likes)[1] @@ -136,9 +165,28 @@ getPost <- function(post, token, n=500, comments=TRUE, likes=TRUE, n.likes=n, n.l <- dim(out$likes)[1] } } - if (!is.null(url.comments) && comments && n.comments > n.c){ + + if (!is.null(url.reactions) && reactions && n.r > 0 && n.reactions > n.r){ + # retrieving next batch of reactions + url <- content$reactions$paging$`next` + content <- callAPI(url=url.reactions, token=token, api=api) + out[["reactions"]] <- rbind(out[["reactions"]], + reactionsDataToDF(content$data)) + n.r <- dim(out$reactions)[1] + # next reactions, in batches of 500 + while (length(content$data)>0 && n.r < n.reactions & + !is.null(url <- content$paging$`next`)){ + url <- content$paging$`next` + content <- callAPI(url=url, token=token, api=api) + out[["reactions"]] <- rbind(out[["reactions"]], + reactionsDataToDF(content$data)) + n.r <- dim(out$reactions)[1] + } + } + + if (!is.null(url.comments) && comments && n.c > 0 && n.comments > n.c){ # retriving next batch of comments - content <- callAPI(url=url.comments, token=token) + content <- callAPI(url=url.comments, token=token, api=api) out[["comments"]] <- rbind(out[["comments"]], commentsDataToDF(content$data)) n.c <- dim(out$comments)[1] @@ -146,7 +194,7 @@ getPost <- function(post, token, n=500, comments=TRUE, likes=TRUE, n.likes=n, while (n.c < n.comments & length(content$data)>0 & !is.null(content$paging$`next`)){ url <- content$paging$`next` - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) out[["comments"]] <- rbind(out[["comments"]], commentsDataToDF(content$data)) n.c <- dim(out$comments)[1] diff --git a/Rfacebook/R/getReactions.R b/Rfacebook/R/getReactions.R index a19a360..3b3940f 100644 --- a/Rfacebook/R/getReactions.R +++ b/Rfacebook/R/getReactions.R @@ -14,7 +14,7 @@ #' \url{http://stackoverflow.com/questions/36930414/how-can-i-get-facebook-graph-api-reaction-summary-count-separately} #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getPage}}, \code{\link{getPost}} #' #' @param post A post ID, or a vector of post IDs @@ -26,6 +26,8 @@ #' @param verbose logical, default is \code{TRUE}, which will print additional #' information on the console. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. +#' #' @examples \dontrun{ #' ## See examples for fbOAuth to know how token was created. #' ## Getting information about Facebook's Facebook Page @@ -37,7 +39,7 @@ #' -getReactions <- function(post, token, verbose=TRUE){ +getReactions <- function(post, token, verbose=TRUE, api=NULL){ add_to_url <- paste0("?fields=reactions.type(LIKE).limit(0).summary(true).as(like),", "reactions.type(LOVE).limit(0).summary(true).as(love),", @@ -50,18 +52,24 @@ getReactions <- function(post, token, verbose=TRUE){ if (verbose==TRUE){ pb <- utils::txtProgressBar(min=0,max=length(post), style=3) } i = 0 for (p in as.character(post)){ - url <- paste0('https://graph.facebook.com/v2.6/', p, add_to_url) + url <- paste0('https://graph.facebook.com/', p, add_to_url) # making query - content <- callAPI(url=url, token=token) + content <- callAPI(url=url, token=token, api=api) # DF with results new.df <- data.frame( id = p, - likes_count = content$like$summary$total_count, - love_count = content$love$summary$total_count, - haha_count = content$haha$summary$total_count, - wow_count = content$wow$summary$total_count, - sad_count = content$sad$summary$total_count, - angry_count = content$angry$summary$total_count, + likes_count = ifelse(!is.null(content$like$summary$total_count), + content$like$summary$total_count, 0), + love_count = ifelse(!is.null(content$love$summary$total_count), + content$love$summary$total_count, 0), + haha_count = ifelse(!is.null(content$haha$summary$total_count), + content$haha$summary$total_count, 0), + wow_count = ifelse(!is.null(content$wow$summary$total_count), + content$wow$summary$total_count, 0), + sad_count = ifelse(!is.null(content$sad$summary$total_count), + content$sad$summary$total_count, 0), + angry_count = ifelse(!is.null(content$angry$summary$total_count), + content$angry$summary$total_count, 0), stringsAsFactors=FALSE) reactions <- rbind(reactions, new.df) if (verbose==TRUE){ i <- i + 1; utils::setTxtProgressBar(pb, i) } diff --git a/Rfacebook/R/getShares.R b/Rfacebook/R/getShares.R index d389daf..a933e15 100644 --- a/Rfacebook/R/getShares.R +++ b/Rfacebook/R/getShares.R @@ -19,7 +19,7 @@ #' \url{https://developers.facebook.com/bugs/1404733043148335/} #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getPage}}, \code{\link{getPost}} #' #' @param post A post ID diff --git a/Rfacebook/R/getUsers.R b/Rfacebook/R/getUsers.R index b151f96..4a71d8c 100644 --- a/Rfacebook/R/getUsers.R +++ b/Rfacebook/R/getUsers.R @@ -11,7 +11,7 @@ #' through the API. All the remaining fields will be missing. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{getFriends}}, \code{\link{getPost}}, \code{\link{searchFacebook}} #' #' @param users A vector of user IDs. @@ -37,7 +37,7 @@ #' } #' -getUsers <- function(users, token, private_info=FALSE) +getUsers <- function(users, token, private_info=FALSE, api="v2.9") { tkversion <- getTokenVersion(token) @@ -45,7 +45,7 @@ getUsers <- function(users, token, private_info=FALSE) if (length(users)==1 && users=='me'){ query <- paste0('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), 'me?') + ifelse(tkversion=='v2', api, ''), '/me?') content <- callAPI(query, token) df <- userDataToDF(list(content), private_info=private_info) return(df) @@ -57,27 +57,28 @@ getUsers <- function(users, token, private_info=FALSE) users.query <- paste(users[1:first.n], collapse=",") ## first query: checking what users are actual users vs pages query <- paste0('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', users.query) + ifelse(tkversion=='v2', api, ''), '?ids=', users.query, "&metadata=1") ## making query content <- callAPI(query, token) if (length(content$error_code)>0){ stop(content$error_msg, ". Querying too many users?") } - actual.users <- which(unlist(lapply(content, function(x) is.null(x$category)))) - pages <- which(unlist(lapply(content, function(x) !is.null(x$category)))) + types <- unlist(lapply(content, function(x) x$metadata$type)) + actual.users <- names(types)[types=="user"] + pages <- names(types)[types=="page"] ## getting data for users if (length(actual.users)>0){ if (private_info==TRUE){ query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(actual.users), collapse=","), + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(actual.users, collapse=","), "&fields=id,name,first_name,middle_name,last_name,gender,locale,birthday,", "location,hometown,relationship_status,picture.type(large)", sep="") } if (private_info==FALSE){ query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(actual.users), collapse=","), + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(actual.users, collapse=","), "&fields=id,name,first_name,middle_name,last_name,gender,locale,", "picture.type(large)", sep="") } @@ -91,9 +92,9 @@ getUsers <- function(users, token, private_info=FALSE) if (length(pages)>0){ ## getting data for pages query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(pages), collapse=","), - "&fields=id,name,category,likes,picture.type(large)", sep="") + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(pages, collapse=","), + "&fields=id,name,category,fan_count,picture.type(large)", sep="") ## making query content <- callAPI(query, token) df.pages <- userDataToDF(content, private_info=private_info) @@ -114,7 +115,7 @@ getUsers <- function(users, token, private_info=FALSE) users.query <- paste(users[first.n:last.n], collapse=",") ## first query: checking what users are actual users vs pages query <- paste0('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', users.query) + ifelse(tkversion=='v2', api, ''), '?ids=', users.query) ## making query content <- callAPI(query, token) if (length(content$error_code)>0){ @@ -126,15 +127,15 @@ getUsers <- function(users, token, private_info=FALSE) if (length(actual.users)>0){ if (private_info==TRUE){ query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(actual.users), collapse=","), + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(actual.users, collapse=","), "&fields=id,name,first_name,middle_name,last_name,gender,locale,birthday,", "location,hometown,relationship_status,picture.type(large)", sep="") } if (private_info==FALSE){ query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(actual.users), collapse=","), + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(actual.users, collapse=","), "&fields=id,name,first_name,middle_name,last_name,gender,locale,", "picture.type(large)", sep="") } @@ -148,8 +149,8 @@ getUsers <- function(users, token, private_info=FALSE) if (length(pages)>0){ ## getting data for pages query <- paste('https://graph.facebook.com/', - ifelse(tkversion=='v2', 'v2.0/', ''), '?ids=', - paste(names(pages), collapse=","), + ifelse(tkversion=='v2', api, ''), '?ids=', + paste(pages, collapse=","), "&fields=id,name,category,likes,picture.type(large)", sep="") ## making query content <- callAPI(query, token) diff --git a/Rfacebook/R/searchFacebook.R b/Rfacebook/R/searchFacebook.R index 259b1a4..0c1dacd 100644 --- a/Rfacebook/R/searchFacebook.R +++ b/Rfacebook/R/searchFacebook.R @@ -24,7 +24,7 @@ #' #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu} +#' Pablo Barbera \email{pbarbera@@usc.edu} #' @seealso \code{\link{fbOAuth}} #' #' @param string string or string vector containing keywords to search. diff --git a/Rfacebook/R/searchPages.R b/Rfacebook/R/searchPages.R index f3c50c4..31a21fd 100644 --- a/Rfacebook/R/searchPages.R +++ b/Rfacebook/R/searchPages.R @@ -8,11 +8,12 @@ #' \code{searchPages} retrieves public pages that mention a given keyword #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu}, Joel Gombin \email{joel.gombin@@gmail.com} +#' Pablo Barbera \email{pbarbera@@usc.edu}, Joel Gombin \email{joel.gombin@@gmail.com} #' @seealso \code{\link{fbOAuth}}, \code{\link{searchFacebook}} #' #' @param string string or string vector containing keywords to search. -#' Note that the returned results will contain any of the keywords. +#' When searching using multiple keywords, the returned results will be +#' pages whose name contains all the keywords. #' #' @param token Either a temporary access token created at #' \url{https://developers.facebook.com/tools/explorer} or the OAuth token @@ -34,7 +35,7 @@ searchPages <- function(string, token, n=200) if (length(string)>1){ string <- paste(string, collapse=" ") } url <- paste("https://graph.facebook.com/search?q=", string, - "&type=page&limit=", sep="") + "&type=place&limit=", sep="") if (n<=200){ url <- paste(url, n, sep="") } diff --git a/Rfacebook/R/updateStatus.R b/Rfacebook/R/updateStatus.R index 4e65c01..d931243 100644 --- a/Rfacebook/R/updateStatus.R +++ b/Rfacebook/R/updateStatus.R @@ -9,7 +9,7 @@ #' on the Facebook profile of the authenticated user. #' #' @author -#' Pablo Barbera \email{pablo.barbera@@nyu.edu}, Zakharov Kyrylo +#' Pablo Barbera \email{pbarbera@@usc.edu}, Zakharov Kyrylo #' (\url{https://github.com/Amice13}) #' #' @seealso \code{\link{getUsers}}, \code{\link{getPost}} diff --git a/Rfacebook/R/utils.R b/Rfacebook/R/utils.R index 62ad8b6..7e5dbb0 100644 --- a/Rfacebook/R/utils.R +++ b/Rfacebook/R/utils.R @@ -41,6 +41,7 @@ pageDataToDF <- function(json){ type = unlistWithNA(json, 'type'), link = unlistWithNA(json, 'link'), id = unlistWithNA(json, 'id'), + story = unlistWithNA(json, 'story'), likes_count = unlistWithNA(json, c('likes', 'summary', 'total_count')), comments_count = unlistWithNA(json, c('comments', 'summary', 'total_count')), shares_count = unlistWithNA(json, c('shares', 'count')), @@ -112,6 +113,22 @@ postDataToDF <- function(json){ return(df) } +reactionsDataToDF <- function(json){ + if (!is.null(json)){ + df <- data.frame( + from_name = unlistWithNA(json, "name"), + from_type = unlistWithNA(json, "type"), + from_id = unlistWithNA(json, "id"), + stringsAsFactors=F + ) + } + if (length(json)==0){ + df <- NULL + } + return(df) +} + + likesDataToDF <- function(json){ if (!is.null(json)){ df <- data.frame( @@ -171,8 +188,8 @@ userDataToDF <- function(user_data, private_info){ last_name = unlistWithNA(user_data, 'last_name'), gender = unlistWithNA(user_data, 'gender'), locale = unlistWithNA(user_data, 'locale'), - category = unlistWithNA(user_data, 'category'), - likes = unlistWithNA(user_data, 'likes'), + #category = unlistWithNA(user_data, 'category'), + likes = unlistWithNA(user_data, 'fan_count'), picture = unlistWithNA(user_data, c('picture', 'data', 'url')), stringsAsFactors=F) if (private_info==TRUE){ @@ -238,8 +255,8 @@ tagsDataToDF <- function(tags){ replyDataToDF <- function(json){ df <- data.frame( - from_id = json$from$id, - from_name = json$from$name, + from_id = ifelse(!is.null(json$from$id), json$from$id, NA), + from_name = ifelse(!is.null(json$from$name), json$from$name, NA), message = ifelse(!is.null(json$message),json$message, NA), created_time = json$created_time, likes_count = json$like_count, @@ -310,6 +327,24 @@ searchPageDataToDF <- function(json){ return(df) } +eventDataToDF <- function(json){ + df <- data.frame( + id = unlistWithNA(json, 'id'), + name = unlistWithNA(json, 'name'), + description = unlistWithNA(json, 'description'), + start_time = unlistWithNA(json, 'start_time'), + end_time = unlistWithNA(json, 'end_time'), + place_name = unlistWithNA(json, c("place", "name")), + attending_count = unlistWithNA(json, 'attending_count'), + declined_count = unlistWithNA(json, 'declined_count'), + maybe_count = unlistWithNA(json, 'maybe_count'), + noreply_count = unlistWithNA(json, 'noreply_count'), + stringsAsFactors=F) + return(df) +} + + + #' @rdname callAPI #' @export #' @@ -326,9 +361,14 @@ searchPageDataToDF <- function(json){ #' created with \code{fbOAuth}. It needs to have extended permissions in order #' to successfully post to the Facebook profile. #' +#' @param api API version. e.g. "v2.8". \code{NULL} is the default. #' -callAPI <- function(url, token){ +callAPI <- function(url, token, api=NULL){ + if (!is.null(api) & !grepl("v2\\..", url)){ + # if api version not in URL already + url <- gsub("facebook.com/", paste0("facebook.com/", api, "/"), url) + } if (class(token)[1]=="config"){ url.data <- GET(url, config=token) } diff --git a/Rfacebook/man/Rfacebook-package.Rd b/Rfacebook/man/Rfacebook-package.Rd index 6e655d0..5f848f1 100644 --- a/Rfacebook/man/Rfacebook-package.Rd +++ b/Rfacebook/man/Rfacebook-package.Rd @@ -2,21 +2,20 @@ % Please edit documentation in R/Rfacebook-package.R \docType{package} \name{Rfacebook-package} -\alias{Rfacebook} \alias{Rfacebook-package} +\alias{Rfacebook} \title{Access to Facebook API via R} \description{ This package provides a series of functions that allow R users to access Facebook's API to get information about users and posts, and collect public status updates that mention specific keywords. } -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} -} \seealso{ \code{\link{fbOAuth}}, \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{searchFacebook}}, \code{\link{updateStatus}}, \code{\link{getFriends}}, \code{\link{getNetwork}}, \code{\link{getPage}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/callAPI.Rd b/Rfacebook/man/callAPI.Rd index 9f1fe74..38964cf 100644 --- a/Rfacebook/man/callAPI.Rd +++ b/Rfacebook/man/callAPI.Rd @@ -4,7 +4,7 @@ \alias{callAPI} \title{Make an API request} \usage{ -callAPI(url, token) +callAPI(url, token, api = NULL) } \arguments{ \item{url}{URL of API request} @@ -13,8 +13,9 @@ callAPI(url, token) \url{https://developers.facebook.com/tools/explorer} or the OAuth token created with \code{fbOAuth}. It needs to have extended permissions in order to successfully post to the Facebook profile.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{callAPI} is an internal function to run an API request. } - diff --git a/Rfacebook/man/fbOAuth.Rd b/Rfacebook/man/fbOAuth.Rd index 24ae26f..6bef8b8 100644 --- a/Rfacebook/man/fbOAuth.Rd +++ b/Rfacebook/man/fbOAuth.Rd @@ -5,7 +5,7 @@ \title{Create OAuth token to Facebook R session} \usage{ fbOAuth(app_id, app_secret, extended_permissions = FALSE, - legacy_permissions = FALSE) + legacy_permissions = FALSE, scope = NULL) } \arguments{ \item{app_id}{numeric, App ID of application to be used to create OAUth token. Available @@ -25,6 +25,8 @@ requires passing App Review (\url{https://developers.facebook.com/docs/facebook- \item{legacy_permissions}{For tokens created with old versions of the API, this option adds the "read_stream" permission} + +\item{scope}{Specify an explicit lists of permissions to ask (overrides extended_permissions)} } \description{ \code{fbOAuth} creates a long-lived OAuth access token that enables R to make @@ -87,11 +89,10 @@ me$username me <- getUsers("me", token=token) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{searchFacebook}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getCheckins.Rd b/Rfacebook/man/getCheckins.Rd index cf7e7cd..a1bc8b7 100644 --- a/Rfacebook/man/getCheckins.Rd +++ b/Rfacebook/man/getCheckins.Rd @@ -4,7 +4,7 @@ \alias{getCheckins} \title{Extract list of checkins of a Facebook friend} \usage{ -getCheckins(user, n = 10, token, tags = FALSE) +getCheckins(user, n = 10, token, tags = FALSE, api = NULL) } \arguments{ \item{user}{A user ID or screen name.} @@ -18,6 +18,8 @@ created with \code{fbOAuth}.} \item{tags}{If \code{TRUE}, output of function will be a list of two elements: a data frame with user's checkins and a list of data frames, where each element contains information about users tagged in each checkin.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getCheckins} retrieves information about a friend's checkins @@ -34,11 +36,10 @@ Check-in search was deprecated with version 2.0 of the Facebook Graph API. my_checkins <- getCheckins(user="me", token=token) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getFriends}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getCommentReplies.Rd b/Rfacebook/man/getCommentReplies.Rd index 122221a..586fea6 100644 --- a/Rfacebook/man/getCommentReplies.Rd +++ b/Rfacebook/man/getCommentReplies.Rd @@ -5,7 +5,7 @@ \title{Extract replies to comments on page post} \usage{ getCommentReplies(comment_id, token, n = 500, replies = TRUE, - likes = FALSE, n.likes = n, n.replies = n) + likes = FALSE, n.likes = n, n.replies = n, api = NULL) } \arguments{ \item{comment_id}{A comment ID} @@ -26,6 +26,8 @@ with likes for the post.} \item{n.replies}{numeric, maximum number of replies to return. Default is \code{n}.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getCommentReplies} retrieves the list of comments replying to @@ -38,6 +40,10 @@ about the original comment: author, creation date, id, counts of likes and comme etc. Second, \code{replies} is a data frame with information about the replies to the comment (author, message, creation time, id). Finally, \code{likes} is data frame that contains names and Facebook IDs of all the users that liked the comment. + +Note that user information (from_id and from_name) are only returned if the token used +to authenticate is a Page access token. For more information, see: +\url{https://developers.facebook.com/docs/graph-api/reference/v2.10/comment} } \examples{ \dontrun{ @@ -48,14 +54,13 @@ data frame that contains names and Facebook IDs of all the users that liked the ## Getting information and likes/comments about most recent post post <- getPost(post=fb_page$id[1], n=2000, token=fb_oauth) ## Downloading list of replies to first comment - replies <- getCommentReplies(comment_id=post$id[1], token=fb_oauth) + replies <- getCommentReplies(comment_id=post$comments$id[1], token=fb_oauth) } -} -\author{ -Yan Turgeon } \seealso{ \code{\link{getPage}}, \code{\link{getPost}} } - +\author{ +Yan Turgeon +} diff --git a/Rfacebook/man/getEvents.Rd b/Rfacebook/man/getEvents.Rd new file mode 100644 index 0000000..522e5f5 --- /dev/null +++ b/Rfacebook/man/getEvents.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/getEvents.R +\name{getEvents} +\alias{getEvents} +\title{Extract list of events from a public Facebook page or group} +\usage{ +getEvents(page, token, api = "v2.9") +} +\arguments{ +\item{page}{Facebook ID for the group or page.} + +\item{token}{Either a temporary access token created at +\url{https://developers.facebook.com/tools/explorer} or the OAuth token +created with \code{fbOAuth}.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} +} +\description{ +\code{getEvents} retrieves event information from a public Facebook group or page. +} +\examples{ +\dontrun{ +load("fb_oauth") +## Downloading events from Playa Vista Farmers' Market + events <- getEvents(page="playavistaFM", token=fb_oauth) +} +} +\seealso{ +\code{\link{getPage}}, \code{\link{fbOAuth}} +} +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getFQL.Rd b/Rfacebook/man/getFQL.Rd index d395d15..a9e7d84 100644 --- a/Rfacebook/man/getFQL.Rd +++ b/Rfacebook/man/getFQL.Rd @@ -28,6 +28,5 @@ d <- getFQL("SELECT uid2 FROM friend WHERE uid1=me()", token=fb_oauth) } \author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} +Pablo Barbera \email{pbarbera@usc.edu} } - diff --git a/Rfacebook/man/getFriends.Rd b/Rfacebook/man/getFriends.Rd index 3a03fe2..83e2d7f 100644 --- a/Rfacebook/man/getFriends.Rd +++ b/Rfacebook/man/getFriends.Rd @@ -33,11 +33,10 @@ my_friends <- getFriends(token=token, simplify=TRUE) head(my_friends, n=10) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getUsers}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getGroup.Rd b/Rfacebook/man/getGroup.Rd index 89d5f2b..754364e 100644 --- a/Rfacebook/man/getGroup.Rd +++ b/Rfacebook/man/getGroup.Rd @@ -5,7 +5,7 @@ \title{Extract list of posts from a public Facebook group} \usage{ getGroup(group_id, token, n = 25, since = NULL, until = NULL, - feed = TRUE) + feed = TRUE, api = NULL) } \arguments{ \item{group_id}{Facebook ID for the group. Note that this is different from @@ -29,6 +29,8 @@ accepted values, see: \url{http://php.net/manual/en/function.strtotime.php}} \item{feed}{If \code{TRUE}, the function will also return posts on the group that were made by others (not only the admin of the group). Note that, unlike in \code{getPage}, here \code{TRUE} is the default option.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getGroup} retrieves information from a public Facebook group. @@ -46,10 +48,9 @@ ids <- searchGroup(name="rusers", token=fb_oauth) since='2013/01/01', until='2013/01/31') } } -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} -} \seealso{ \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getInsights.Rd b/Rfacebook/man/getInsights.Rd index e7cee21..2253a2d 100644 --- a/Rfacebook/man/getInsights.Rd +++ b/Rfacebook/man/getInsights.Rd @@ -33,6 +33,8 @@ that you must specify wich metric from insights you need and the period. To request multiple metrics at one time, pass a vector of metric names with a vector of periods of the same length. If only one period is supplied, it will apply to each metric. Please refer to Facebook's documentation for valid combinations of objects, metrics and periods. + +Note that some insights require a page access token, see \code{getPageToken} } \details{ The current list of supported metrics and periods is: page_fan_adds, page_fan_removes, @@ -74,4 +76,3 @@ Danilo Silva \email{silvadaniloc@gmail.com} Eduardo Carvalho \email{eduardooc.86@gmail.com} Andrew Geisler \url{https://github.com/andrewgeisler} } - diff --git a/Rfacebook/man/getLikes.Rd b/Rfacebook/man/getLikes.Rd index 9e72a93..f989a42 100644 --- a/Rfacebook/man/getLikes.Rd +++ b/Rfacebook/man/getLikes.Rd @@ -2,12 +2,12 @@ % Please edit documentation in R/getLikes.R \name{getLikes} \alias{getLikes} -\title{Extract list of likes of a Facebook friend} +\title{Extract list of likes of the authenticated Facebook user} \usage{ -getLikes(user, n = 500, token) +getLikes(user = "me", n = 500, token) } \arguments{ -\item{user}{A user ID or screen name.} +\item{user}{The name of the user. By default, "me".} \item{n}{Maximum number of likes to return for each user.} @@ -16,13 +16,13 @@ getLikes(user, n = 500, token) created with \code{fbOAuth}.} } \description{ -\code{getLikes} retrieves information about a friend's likes. -To retrieve the number of likes for a page, use \code{getUsers} -with the page IDs. +\code{getLikes} retrieves information about the authenticated use +only (not any friend). To retrieve the number of likes for a page, +use \code{getUsers} with the page IDs. } \details{ This function requires the use of an OAuth token with the following -permissions: user_likes, friends_likes +permission: user_likes } \examples{ \dontrun{ @@ -30,11 +30,10 @@ permissions: user_likes, friends_likes my_likes <- getLikes(user="me", token=token) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getFriends}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getMembers.Rd b/Rfacebook/man/getMembers.Rd new file mode 100644 index 0000000..25efb36 --- /dev/null +++ b/Rfacebook/man/getMembers.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/getMembers.R +\name{getMembers} +\alias{getMembers} +\title{Retrieve members from a public group} +\usage{ +getMembers(group_id, token, n = 5000, api = NULL) +} +\arguments{ +\item{token}{Either a temporary access token created at +\url{https://developers.facebook.com/tools/explorer} or the OAuth token +created with \code{fbOAuth}.} + +\item{page}{A group ID} +} +\description{ +\code{getMembers} retrieves members from a public group, up to 5000 members. +} +\examples{ +\dontrun{ +## Find Facebook ID for R-Users Facebook group +load("fb_oauth") +ids <- searchGroup(name="rusers", token=fb_oauth) + ids[1,] # id = 18533493739 +## Retrieves members ID for R-Users Facebook group + members <- getMembers(group_id="18533493739", token=fb_oauth) +} +} +\seealso{ +\code{\link{getPage}}, \code{\link{getPost}}, \code{\link{getCommentReplies}} +} +\author{ +Yan Turgeon +} diff --git a/Rfacebook/man/getNetwork.Rd b/Rfacebook/man/getNetwork.Rd index 5b4cd3a..941be6d 100644 --- a/Rfacebook/man/getNetwork.Rd +++ b/Rfacebook/man/getNetwork.Rd @@ -43,11 +43,10 @@ only friends who are using the application will be returned. dev.off() } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getFriends}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getNewsfeed.Rd b/Rfacebook/man/getNewsfeed.Rd index d617be2..1e1ad50 100644 --- a/Rfacebook/man/getNewsfeed.Rd +++ b/Rfacebook/man/getNewsfeed.Rd @@ -25,11 +25,10 @@ load("fb_oauth") my_newsfeed <- getNewsfeed(token=fb_oauth, n=100) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{fbOAuth}}, \code{\link{getPost}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getPage.Rd b/Rfacebook/man/getPage.Rd index b0177af..f69dbf5 100644 --- a/Rfacebook/man/getPage.Rd +++ b/Rfacebook/man/getPage.Rd @@ -5,7 +5,7 @@ \title{Extract list of posts from a public Facebook page} \usage{ getPage(page, token, n = 25, since = NULL, until = NULL, feed = FALSE, - reactions = FALSE) + reactions = FALSE, verbose = TRUE, api = NULL) } \arguments{ \item{page}{A page ID or page name.} @@ -30,6 +30,10 @@ that were made by others (not only the admin of the page).} \item{reactions}{If \code{TRUE}, will add variables to the data frame with the total count of reactions: love, haha, wow, sad, angry.} + +\item{verbose}{If \code{TRUE}, will report a number of the posts retrieved.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getPage} retrieves information from a public Facebook page. Note that @@ -42,7 +46,11 @@ with public profiles. The \code{since} and \code{until} parameters are applied to the \code{updated_time} field in the post objects, and not the \code{created_time}. As a result, this function -might return old posts that have been updated recently. +might return old posts that have been updated recently. + +\code{comments_count} refers to the total of comments, including nested comments (replies). +It might be different from the total number of comments available through the API if +some comments have been deleted. } \examples{ \dontrun{ @@ -58,11 +66,10 @@ might return old posts that have been updated recently. since='2013/01/01', until='2013/01/31') } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getUsers}}, \code{\link{getPost}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getPageToken.Rd b/Rfacebook/man/getPageToken.Rd new file mode 100644 index 0000000..a0f8640 --- /dev/null +++ b/Rfacebook/man/getPageToken.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/getPageToken.R +\name{getPageToken} +\alias{getPageToken} +\title{Get a page access token} +\usage{ +getPageToken(page, token) +} +\arguments{ +\item{page}{A page ID or page name.} + +\item{token}{the token (with scope 'manage_pages') of a user that has admin access to the page} +} +\value{ +the page access token string +} +\description{ +Gets a page access token that can be used to e.g. get insights for a page. +} +\examples{ +\dontrun{ +## Get a normal access token with manage_pages scope +token = fbOAuth(app_id, app_secret, scope="manage_pages") +## Get a page access token for a page +page_token = getPageToken(page, token) +## Get page insights +getInsights(page, token=page_token, metric = "page_impressions") +} +} diff --git a/Rfacebook/man/getPost.Rd b/Rfacebook/man/getPost.Rd index 25d6aa1..51444c0 100644 --- a/Rfacebook/man/getPost.Rd +++ b/Rfacebook/man/getPost.Rd @@ -4,8 +4,9 @@ \alias{getPost} \title{Extract information about a public Facebook post} \usage{ -getPost(post, token, n = 500, comments = TRUE, likes = TRUE, - n.likes = n, n.comments = n) +getPost(post, token, n = 500, comments = TRUE, likes = (!reactions), + reactions = FALSE, n.likes = n, n.comments = n, n.reactions = n, + api = NULL) } \arguments{ \item{post}{A post ID} @@ -19,26 +20,37 @@ created with \code{fbOAuth}.} \item{comments}{logical, default is \code{TRUE}, which will return data frame with comments to the post.} -\item{likes}{logical, default is \code{TRUE}, which will return data frame +\item{likes}{logical, default is \code{TRUE} unless reactions is true, which will return data frame with likes for the post.} +\item{reactions}{logical, default is \code{FALSE}, which will return data frame with reactions (like, love, etc) for the post} + \item{n.likes}{numeric, maximum number of likes to return. Default is \code{n}.} -\item{n.comments}{numeric, maximum number of likes to return. Default is +\item{n.comments}{numeric, maximum number of comments to return. Default is +\code{n}.} + +\item{n.reactions}{numeric, maximum number of reactions to return. Default is \code{n}.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getPost} retrieves information about a public Facebook post, including list of comments and likes. } \details{ -\code{getPost} returns a list with three components: \code{post}, -\code{likes}, and \code{comments}. First, \code{post} contains information -about the post: author, creation date, id, counts of likes, comments, and -shares, etc. Second, \code{likes} is a data frame that contains names and -Facebook IDs of all the users that liked the post. Finally, \code{comments} -is a data frame with information about the comments to the post (author, -message, creation time, id). +\code{getPost} returns a list with up to four components: \code{post}, +\code{likes}, \code{comments}, and \code{reactions}. +\code{post} contains information about the post: author, creation date, id, +counts of likes, comments, and shares, etc. +\code{likes} is a data frame that contains names and Facebook IDs of all +the users that liked the post. +\code{comments} is a data frame with information about the comments to +the post (author, message, creation time, id). To download also the replies +to specific comments, see \code{\link{getCommentReplies}}. Note that the total +number of comments may be different from the number report in \code{comments_count} +if some comments have been deleted. } \examples{ \dontrun{ @@ -50,11 +62,10 @@ fb_page <- getPage(page="facebook", token=fb_oauth) post <- getPost(post=fb_page$id[1], n=2000, token=fb_oauth) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getUsers}}, \code{\link{getPage}}, \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getReactions.Rd b/Rfacebook/man/getReactions.Rd index 0ee400d..c9d728a 100644 --- a/Rfacebook/man/getReactions.Rd +++ b/Rfacebook/man/getReactions.Rd @@ -4,7 +4,7 @@ \alias{getReactions} \title{Extract total count of reactions to one or more Facebook posts} \usage{ -getReactions(post, token, verbose = TRUE) +getReactions(post, token, verbose = TRUE, api = NULL) } \arguments{ \item{post}{A post ID, or a vector of post IDs} @@ -15,6 +15,8 @@ created with \code{fbOAuth}.} \item{verbose}{logical, default is \code{TRUE}, which will print additional information on the console.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ \code{getReactions} retrieves information from a single or multiple posts, @@ -35,11 +37,10 @@ fb_page <- getPage(page="facebook", token=fb_oauth) post <- getReactions(post=fb_page$id[1], token=fb_oauth) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getPage}}, \code{\link{getPost}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getShares.Rd b/Rfacebook/man/getShares.Rd index 8f02e71..10c1e7a 100644 --- a/Rfacebook/man/getShares.Rd +++ b/Rfacebook/man/getShares.Rd @@ -39,11 +39,10 @@ fb_page <- getPage(page="facebook", token=fb_oauth) shares <- getShares(post=fb_page$id[1], n=2000, token=fb_oauth) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getPage}}, \code{\link{getPost}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/getUsers.Rd b/Rfacebook/man/getUsers.Rd index e9f5cca..b082fee 100644 --- a/Rfacebook/man/getUsers.Rd +++ b/Rfacebook/man/getUsers.Rd @@ -4,7 +4,7 @@ \alias{getUsers} \title{Extract information about one or more Facebook users} \usage{ -getUsers(users, token, private_info = FALSE) +getUsers(users, token, private_info = FALSE, api = "v2.9") } \arguments{ \item{users}{A vector of user IDs.} @@ -36,11 +36,10 @@ fb <- getUsers("me", token=fb_oauth) fb$username } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{getFriends}}, \code{\link{getPost}}, \code{\link{searchFacebook}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/searchFacebook.Rd b/Rfacebook/man/searchFacebook.Rd index 4bd11dd..7b45ca7 100644 --- a/Rfacebook/man/searchFacebook.Rd +++ b/Rfacebook/man/searchFacebook.Rd @@ -50,11 +50,10 @@ posts <- searchFacebook( string="facebook", token=fb_oauth, n=100, since = "yesterday 00:00", until = "yesterday 23:59" ) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu} } \seealso{ \code{\link{fbOAuth}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu} +} diff --git a/Rfacebook/man/searchGroup.Rd b/Rfacebook/man/searchGroup.Rd index 936d033..0bdf07a 100644 --- a/Rfacebook/man/searchGroup.Rd +++ b/Rfacebook/man/searchGroup.Rd @@ -4,7 +4,7 @@ \alias{searchGroup} \title{Find Facebook ID of a group} \usage{ -searchGroup(name, token) +searchGroup(name, token, n = 25, api = NULL) } \arguments{ \item{name}{Name of Facebook group (in URL)} @@ -12,6 +12,10 @@ searchGroup(name, token) \item{token}{Either a temporary access token created at \url{https://developers.facebook.com/tools/explorer} or the OAuth token created with \code{fbOAuth}.} + +\item{n}{Number of groups to return. Default is up to 25.} + +\item{api}{API version. e.g. "v2.8". \code{NULL} is the default.} } \description{ Use \code{searchGroup} in combination with \code{getGroup} to scrape @@ -30,4 +34,3 @@ ids <- searchGroup(name="rusers", token=fb_oauth) since='2013/01/01', until='2013/01/31') } } - diff --git a/Rfacebook/man/searchPages.Rd b/Rfacebook/man/searchPages.Rd index ad2e62b..7d927de 100644 --- a/Rfacebook/man/searchPages.Rd +++ b/Rfacebook/man/searchPages.Rd @@ -8,7 +8,8 @@ searchPages(string, token, n = 200) } \arguments{ \item{string}{string or string vector containing keywords to search. -Note that the returned results will contain any of the keywords.} +When searching using multiple keywords, the returned results will be +pages whose name contains all the keywords.} \item{token}{Either a temporary access token created at \url{https://developers.facebook.com/tools/explorer} or the OAuth token @@ -27,11 +28,10 @@ created with \code{fbOAuth}.} pages <- searchPages( string="facebook", token=fb_oauth, n=100 ) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu}, Joel Gombin \email{joel.gombin@gmail.com} } \seealso{ \code{\link{fbOAuth}}, \code{\link{searchFacebook}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu}, Joel Gombin \email{joel.gombin@gmail.com} +} diff --git a/Rfacebook/man/updateStatus.Rd b/Rfacebook/man/updateStatus.Rd index a13d41c..d9b96ef 100644 --- a/Rfacebook/man/updateStatus.Rd +++ b/Rfacebook/man/updateStatus.Rd @@ -27,12 +27,11 @@ on the Facebook profile of the authenticated user. updateStatus("this is just a test", token=fb_oauth) } -} -\author{ -Pablo Barbera \email{pablo.barbera@nyu.edu}, Zakharov Kyrylo -(\url{https://github.com/Amice13}) } \seealso{ \code{\link{getUsers}}, \code{\link{getPost}} } - +\author{ +Pablo Barbera \email{pbarbera@usc.edu}, Zakharov Kyrylo +(\url{https://github.com/Amice13}) +}