CancelBot: Twitter Profanity Finder
- toldham2
- Jan 20, 2022
- 1 min read
Updated: May 13, 2023
This R Shiny App collects tweets from any Twitter user and displays all of their tweets containing vulgarity.
NOTE: STILL WORKS AS OF 5/14/23 DESPITE TWITTER CLAIMING TO HAVE REMOVED FREE API ACCESS
This Shiny App collects all tweets (3,200 max) from any Twitter username and displays all of their tweets containing vulgarity. Try it on yourself to make sure your social media is clean for a job application, or cause a little bit of trouble and try it on someone else.
Code
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
tags$head(
tags$script(async = NA,
src = "https://platform.twitter.com/widgets.js")
),
titlePanel("CancelBot"),
sidebarLayout(
sidebarPanel(
helpText(
"See a Twitter user's explicit and/or offensive tweets.\nWARNING: App will crash if username invalid or if user has no vulgar tweets."
),
br(),
textInput(
"username",
label = h5("Enter a Twitter handle"),
placeholder = "Enter handle..."
),
checkboxInput("checkStrict", "Strict Lexicon", value = FALSE),
checkboxInput("checkReplies", "Include Replies", value = FALSE),
checkboxInput("checkRts", "Include Retweets", value = FALSE),
actionButton("actionConfirm", "Get Tweets")
), # sidebarPanel
mainPanel(lapply(1:3200, function(i) {
uiOutput(paste0('tweet', i))
})) # mainPanel
) # sidebarLayout
) # fluidPage
# Define server logic required to draw a histogram
server <- function(input, output) {
# ---- Libraries ----
library(academictwitteR)
library(tidytext)
library(stringr)
library(dplyr)
# ---- run App ----
observeEvent(input$actionConfirm, {
withProgress(message = 'Getting Tweets', value = 0, {
# ---- Get Parameters ----
incProgress(1 / 5, detail = "Setting parameters...")
username <- input$username
strict = input$checkStrict
replies = input$checkReplies
retweets = input$checkRts
incProgress(1 / 5, detail = "Getting user ID...")
if (str_detect(username, "@")) {
username <- str_replace(username, "@", "")
}
bearer <- "AAAAAAAAAAAAAAAAAAAAAKBjWwEAAAAAdzslRclhVPpPk%2BpLmsag%2FaMP1Lc%3DOFW3srfgJ4yNluxIgjEsFwJ5oHsDuuinHJcf13NYFY1reCAHyk"
user_id <- get_user_id(username, bearer)
# ---- Get Tweets ----
incProgress(1 / 5, detail = "Getting all tweets...")
tweets <- get_user_timeline(
user_id,
start_tweets = "2010-11-06T00:00:00Z",
end_tweets = paste0(Sys.Date(), "T00:00:00Z"),
bearer_token = bearer,
n = 3200,
bind_tweets = TRUE,
verbose = FALSE
)
# ---- Format Tweet Data ----
incProgress(1 / 5, detail = "Filtering tweets...")
if (!retweets) {
tweets <- tweets[!grepl("RT @", tweets$text),]
}
if (!replies) {
tweets <- tweets[!grepl("@", tweets$text),]
}
tweets_unnested <- tweets %>%
unnest_tokens(word, text, drop = FALSE)
# ---- Get Bad Tweets ----
idlist <- list()
if (strict) {
badwords <-
read.csv(
"data/LDNOOBW-Strict/strictwords.csv"
)
varList <- names(badwords)
for (i in 1:nrow(tweets_unnested)) {
lang <- tweets_unnested[i, "lang"]
if (lang %in% varList) {
for (badword in badwords[, lang]) {
if ((badword == tweets_unnested[i, "word"]) && (badword != "")) {
idlist <- append(idlist, tweets_unnested[i, "id"])
}
}
}
}
} else {
badwords <-
read.csv(
"data/LDNOOBW-Lax/laxwords.csv"
)
varList <- names(badwords)
for (i in 1:nrow(tweets_unnested)) {
lang <- tweets_unnested[i, "lang"]
if (lang %in% varList) {
for (badword in badwords[, lang]) {
if ((badword == tweets_unnested[i, "word"]) && (badword != "")) {
idlist <- append(idlist, tweets_unnested[i, "id"])
}
}
}
}
}
id_df <- do.call(rbind.data.frame, idlist)
colnames(id_df) <- c("id")
id_df <- id_df %>% distinct()
incProgress(1 / 5, detail = "Printing tweets...")
lapply(1:nrow(id_df), function(i) {
outputID <- paste0("tweet", i)
outputLink <- paste0("https://twitter.com/", username, "/status/", id_df[i, "id"])
outputScript <- paste0("twttr.widgets.load(document.getElementById('",
outputID,
"'));")
output[[outputID]] <- renderUI({
tagList(
tags$blockquote(class = "twitter-tweet",
tags$a(href = outputLink)),
tags$script(outputScript)
)
}) # renderUI
}) # loop
}) # withProgress
}) # observeEvent actionConfirm
} # function
# Run the application
shinyApp(ui = ui, server = server)






Comments