Last active
August 7, 2021 19:30
-
-
Save jnolis/49d328f58e6bb0074442d032f4e79c7f to your computer and use it in GitHub Desktop.
Do 3-legged Twitter authentication for rtweet (lite version)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# _____ __ __ | |
# |__ / / /__ ____ _____ ____ ____/ / | |
# /_ <______/ / _ \/ __ `/ __ `/ _ \/ __ / | |
# ___/ /_____/ / __/ /_/ / /_/ / __/ /_/ / | |
# /____/ /_/\___/\__, /\__, /\___/\__,_/ | |
# /____//____/ | |
# RTWEET + 3-LEGGED-AUTH DEMO (LITE) | |
# This code demonstrates how to do 3-legged authentication for Twitter | |
# using the {rtweet} package. Based heavily on code from Michael Kearney. | |
# This is the 'lite' version which requires the user to reauthenticate every time | |
# they refresh the page. The full version is in a separate gist | |
# To run this you need: | |
# 1. An app set up in the twitter developer portal (and http://127.0.0.1 set as a callback URL) | |
# 2. A config.yml file set up with the API keys like so: | |
# default: | |
# consumer_key: "xxx" | |
# consumer_secret: "xxx" | |
# access_token: "xxx" | |
# access_secret: "xxx" | |
# then to actually run it, use the command: `shiny::runApp(port=80L, launch.browser=FALSE)` and navigate to | |
# the url http://127.0.0.1 in your browser. It's important that you use port 80 and your desktop browser instead | |
# of the RStudio one for the app to work. | |
library(shiny) | |
library(httr) | |
library(rtweet) | |
library(jsonlite) | |
# this loads the consumer/access keys from a yaml file using the config package. | |
# You can load them however you want! | |
keys <- read_json("config.json") | |
# this is a modification of Michael's code to make the signature for authenticating twitter | |
# API requests. It's pulled from tokens.R in the rtweet package | |
oauth_sig <- function(url, method, | |
token = NULL, | |
token_secret = NULL, | |
private_key = NULL, ...) { | |
httr::oauth_header(httr::oauth_signature(url, method, app, token, | |
token_secret, private_key, other_params = list(...))) | |
} | |
# This function creates a URL for users to click to authenticate. | |
# You should use it to show a URL when users haven't authenticated yet. | |
# the callback_url HAS to be in the app configuration on the developer portal, | |
# and it needs to have the right http/https protocol. | |
# for testing in RSTudio I found it best to user 127.0.0.1 and have shiny use port 80 | |
get_authorization_url <- function(app, callback_url, permission=NULL){ | |
private_key <- NULL | |
response <- httr::POST("https://api.twitter.com/oauth/request_token", | |
oauth_sig("https://api.twitter.com/oauth/request_token", | |
"POST", private_key = NULL, oauth_callback = callback_url)) | |
httr::stop_for_status(response) | |
params <- httr::content(response, type = "application/x-www-form-urlencoded") | |
authorize_url <- httr::modify_url("https://api.twitter.com/oauth/authenticate", | |
query = list(oauth_token = params$oauth_token, permission = permission)) | |
authorize_url | |
} | |
# Once a user authenticates them, Twitter will pass them back to the callback | |
# url in the authentication one, with the results of the authentication in the query | |
# of the callback url. This function takes the information from the query | |
# and does the final conversion to get it into the useful format | |
get_access_token <- function(app, oauth_token, oauth_verifier){ | |
url <- paste0("https://api.twitter.com/oauth/access_token?oauth_token=", | |
oauth_token,"&oauth_verifier=",oauth_verifier) | |
response <- httr::POST(url, | |
oauth_sig(url, | |
"POST", | |
private_key = NULL)) | |
if(response$status_code == 200L){ | |
results <- content(response,type="application/x-www-form-urlencoded", encoding="UTF-8") | |
results[["screen_name"]] <- NULL # since storing that might be creepy | |
results[["user_id"]] <- NULL # since storing that might be creepy | |
results | |
} else { | |
NULL | |
} | |
} | |
# The app we'll be using. I didn't give it a name since it doesn't seem to matter | |
app <- oauth_app( | |
app = "", | |
key = keys$consumer_key, | |
secret = keys$consumer_secret | |
) | |
ui <- fluidPage( | |
verticalLayout( | |
uiOutput("main") # this will either show a link to authenticate or some tweets | |
) | |
) | |
server <- function(input, output, session) { | |
# this will be NULL if the user hasn't logged in yet, otherwise | |
# it will have the valid twitter token for user | |
access_token <- reactive({ | |
# is the user is coming in from having just authenticated? | |
# if yes save the tokens, if not then no keys to user | |
access_token <- NULL | |
query <- getQueryString(session) | |
if(!is.null(query) | |
&& !is.null(query$oauth_token) | |
&& !is.null(query$oauth_verifier)){ | |
access_token <- get_access_token(app, query$oauth_token, query$oauth_verifier) | |
} | |
# turn the information from the file into a valid token object | |
if(!is.null(access_token)){ | |
create_token(app="", | |
keys$consumer_key, | |
keys$consumer_secret, | |
access_token = access_token$oauth_token, | |
access_secret = access_token$oauth_token_secret) | |
} | |
}) | |
# either show the authentication URL or a few tweets | |
output$main <- renderUI({ | |
if(is.null(access_token())){ | |
url <- get_authorization_url(app, callback_url = "http://127.0.0.1") | |
a(href = url, "Click here to authorize this app") | |
} else { | |
do.call(div,lapply(get_my_timeline(token = access_token())$text[1:3], p)) | |
} | |
}) | |
} | |
# make sure you use port 80 or whatever you put in the twitter developer portal | |
# in RStudio if you hit "Run App" it ignore the port, so watch out! | |
shinyApp(ui = ui, server = server, options=list(port=80L)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment