├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── NAMESPACE ├── R ├── sysdata.rda ├── textme.R └── tm_configure.R ├── README.Rmd ├── README.md ├── man ├── textme.Rd └── tm_configure.Rd ├── textme.Rproj └── vignettes ├── .gitignore └── my-vignette.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | /docs* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | cache: packages 3 | 4 | after_success: 5 | - Rscript -e 'pkgdown::build_site()' 6 | 7 | deploy: 8 | provider: pages 9 | skip-cleanup: true 10 | github-token: $GITHUB_PAT 11 | keep-history: true 12 | local-dir: docs 13 | on: 14 | branch: master -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: textme 2 | Type: Package 3 | Title: Text message yourself from R. 4 | Version: 0.0.0.9000 5 | Authors@R: person("Rich", "Pauloo", email = "richpauloo@gmail.com", role = c("aut", "cre")) 6 | Maintainer: Rich Pauloo 7 | Description: This package will be familiar to fans of beepr. 8 | The main function of this package is textme(), which sends 9 | you a text message from R. By adding a textme() to a long-running 10 | job, you can leave the computer while it's processing, and receive 11 | a text message via the instant that your job finishes. This package 12 | uses Twilio to send text messages, and thus requires a Twilio account. 13 | License: GPL-3 14 | Encoding: UTF-8 15 | LazyData: true 16 | Imports: 17 | twilio (>= 0.1.0) 18 | URL: https://richpauloo.github.io/textme 19 | BugReports: https://github.com/richpauloo/textme/issues 20 | RoxygenNote: 6.1.1 21 | Suggests: 22 | knitr, 23 | rmarkdown, 24 | pkgdown 25 | VignetteBuilder: knitr 26 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(textme) 4 | export(tm_configure) 5 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richpauloo/textme/50d98844125905b5b4490b889f73e0bd053907ac/R/sysdata.rda -------------------------------------------------------------------------------- /R/textme.R: -------------------------------------------------------------------------------- 1 | #' Send a text message. 2 | #' 3 | #' @param message A message to send. 4 | #' @param twilio_sid Twilio SID--not needed if supplied in \code{\link{tm_configure()}}. 5 | #' @param twilio_token Twilio token--not needed if supplied in \code{\link{tm_configure.R}}. 6 | #' @param twilio_phone_number Twilio phone number--not needed if supplied in \code{\link{tm_configure}}. 7 | #' @param target_phone_number Target phone number--not needed if supplied in \code{\link{tm_configure}}. 8 | #' 9 | #' @return A text message sent from the twilio phone number to the target phone number. 10 | #' 11 | #' @examples 12 | #' 13 | #' # send a text message 14 | #' textme() 15 | #' 16 | #' # send a custom message 17 | #' textme(message = "A new text message.") 18 | #' 19 | #' # send a text message to a different number 20 | #' textme(target_phone_number = "1234567890") 21 | #' 22 | #' @export 23 | 24 | textme <- function(message = NULL, 25 | twilio_sid = NULL, 26 | twilio_token = NULL, 27 | twilio_phone_number = NULL, 28 | target_phone_number = NULL){ 29 | 30 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | # set the target phone number 32 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | 34 | # if the target is not provided (NULL): 35 | if(is.null(target_phone_number)){ 36 | 37 | # check that it's been previously saved by tm_configure() 38 | if(nchar(Sys.getenv("TARGET_PHONE_NUMBER")) == 0) 39 | stop("Either provide your target phone number in the `target_phone_number` argument, or specify it in `tm_configure()`.") 40 | 41 | # if it's been saved in tm_confgure, access it. 42 | if(nchar(Sys.getenv("TARGET_PHONE_NUMBER")) > 0) 43 | target_phone_number <- Sys.getenv("TARGET_PHONE_NUMBER") 44 | 45 | } 46 | 47 | # if the target is provided (! NULL): 48 | if(!is.null(target_phone_number)){ 49 | 50 | # check that it has class == vector 51 | if(!is.vector(target_phone_number)) 52 | stop(paste0("`target_phone_number` must be of class `vector`, not `", 53 | class(target_phone_number), "`.")) 54 | 55 | 56 | # check that it's a vecotr of length 1 57 | if(length(target_phone_number) > 1) 58 | stop(paste0("`target_phone_number` must be a vector of length 1. It is currently a vector of length ", 59 | length(target_phone_number), ".")) 60 | 61 | # if it's a vector of length 1, coerce it to character 62 | if(length(target_phone_number) == 1) 63 | target_phone_number <- as.character(target_phone_number) 64 | 65 | } 66 | 67 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | # set the twilio phone number 69 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | 71 | # if the twilio number is not provided (NULL): 72 | if(is.null(twilio_phone_number)){ 73 | 74 | # check that it's been previously saved by tm_configure() 75 | if(nchar(Sys.getenv("TWILIO_PHONE_NUMBER")) == 0) 76 | stop("Either provide your Twilio phone number in the `twilio_phone_number` argument, or specify it in `tm_configure()`.") 77 | 78 | # if it's been saved in tm_confgure, access it. 79 | if(nchar(Sys.getenv("TWILIO_PHONE_NUMBER")) > 0) 80 | twilio_phone_number <- Sys.getenv("TWILIO_PHONE_NUMBER") 81 | 82 | } 83 | 84 | # if the twilio number is provided (! NULL): 85 | if(!is.null(twilio_phone_number)){ 86 | 87 | # check that it has class == vector 88 | if(!is.vector(twilio_phone_number)) 89 | stop(paste0("`twilio_phone_number` must be of class `vector`, not `", 90 | class(twilio_phone_number), "`.")) 91 | 92 | 93 | # check that it's a vector of length 1 94 | if(length(twilio_phone_number) > 1) 95 | stop(paste0("`twilio_phone_number` must be a vector of length 1. It is currently a vector of length ", 96 | length(twilio_phone_number), ".")) 97 | 98 | # if it's a vector of length 1, coerce it to character 99 | if(length(twilio_phone_number) == 1) 100 | twilio_phone_number <- as.character(twilio_phone_number) 101 | 102 | } 103 | 104 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 105 | # set the twilio sid 106 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 107 | 108 | # if the twilio sid is not provided (NULL): 109 | if(is.null(twilio_sid)){ 110 | 111 | # check that it's been previously saved by tm_configure() 112 | if(nchar(Sys.getenv("TWILIO_SID")) == 0) 113 | stop("Either provide your Twilio SID in the `twilio_sid` argument, or specify it in `tm_configure()`.") 114 | 115 | # if it's been saved in tm_confgure, access it. 116 | if(nchar(Sys.getenv("TWILIO_SID")) > 0) 117 | twilio_sid <- Sys.getenv("TWILIO_SID") 118 | 119 | } 120 | 121 | # if the twilio sid is provided (! NULL): 122 | if(!is.null(twilio_sid)){ 123 | 124 | # check that it has class == vector 125 | if(!is.vector(twilio_sid)) 126 | stop(paste0("`twilio_sid` must be of class `vector`, not `", 127 | class(twilio_sid), "`.")) 128 | 129 | 130 | # check that it's a vector of length 1 131 | if(length(twilio_sid) > 1) 132 | stop(paste0("`twilio_sid` must be a vector of length 1. It is currently a vector of length ", 133 | length(twilio_sid), ".")) 134 | 135 | # if it's a vector of length 1, coerce it to character 136 | if(length(twilio_sid) == 1) 137 | twilio_sid <- as.character(twilio_sid) 138 | 139 | } 140 | 141 | 142 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 | # set the twilio token 144 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | 146 | # if the twilio token is not provided (NULL): 147 | if(is.null(twilio_token)){ 148 | 149 | # check that it's been previously saved by tm_configure() 150 | if(nchar(Sys.getenv("TWILIO_TOKEN")) == 0) 151 | stop("Either provide your Twilio SID in the `twilio_token` argument, or specify it in `tm_configure()`.") 152 | 153 | # if it's been saved in tm_confgure, access it. 154 | if(nchar(Sys.getenv("TWILIO_TOKEN")) > 0) 155 | twilio_token <- Sys.getenv("TWILIO_TOKEN") 156 | 157 | } 158 | 159 | # if the twilio token is provided (! NULL): 160 | if(!is.null(twilio_token)){ 161 | 162 | # check that it has class == vector 163 | if(!is.vector(twilio_token)) 164 | stop(paste0("`twilio_token` must be of class `vector`, not `", 165 | class(twilio_token), "`.")) 166 | 167 | 168 | # check that it's a vector of length 1 169 | if(length(twilio_token) > 1) 170 | stop(paste0("`twilio_token` must be a vector of length 1. It is currently a vector of length ", 171 | length(twilio_token), ".")) 172 | 173 | # if it's a vector of length 1, coerce it to character 174 | if(length(twilio_token) == 1) 175 | twilio_token <- as.character(twilio_token) 176 | 177 | } 178 | 179 | 180 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 181 | # determine the message 182 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 | 184 | # a message is provided 185 | if(!is.null(message)) 186 | body = as.character(message) 187 | 188 | # a message is not provided, so create one 189 | if(is.null(message)) 190 | body = sample(premade_messages, 1) 191 | 192 | 193 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 194 | # send the message 195 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 | 197 | twilio::tw_send_message(from = twilio_phone_number, 198 | to = target_phone_number, 199 | body = body) 200 | 201 | } 202 | -------------------------------------------------------------------------------- /R/tm_configure.R: -------------------------------------------------------------------------------- 1 | #' Store Twilio SID, Twilio token, Twilio phone number, and target phone number for later use. 2 | #' 3 | #' @param twilio_sid Your Twilio SID. 4 | #' @param twilio_token Your Twilio Token. 5 | #' @param twilio_phone_number Your Twilio phone number. 6 | #' @param target_phone_number The phone number you want to receive a text message at 7 | #' @param overwrite By default, this is set to \code{FALSE}. If \code{TRUE}, R will overwrite existing .Renviron variables that match the ones named in this function. 8 | #' 9 | #' @return A .Renviron file that stores the supplied paramaters for ease of use in future R sessions. 10 | #' 11 | #' @examples 12 | #' 13 | #' # set parameters 14 | #' tm_configure(twilio_sid = "AC1ffb497954c02119a0f0720784bde131", 15 | #' twilio_token = "f5c8af81ddadaf3e8904b909f975c369", 16 | #' twilio_phone_number = "1234567890", 17 | #' target_phone_number = "0987654321") 18 | #' 19 | #' # view and edit the .Renvion file 20 | #' file.edit("~/.Renviron") 21 | #' 22 | #' @export 23 | 24 | tm_configure <- function(twilio_sid = NULL, 25 | twilio_token = NULL, 26 | twilio_phone_number = NULL, 27 | target_phone_number = NULL, 28 | overwrite = FALSE){ 29 | 30 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | # enforce completeness 32 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | if (is.null(twilio_sid)) 34 | stop ("Please supply your Twilio SID in the `twilio_sid` argument.") 35 | if (is.null(twilio_token)) 36 | stop ("Please supply your Twilio token in the `twilio_token` argument.") 37 | if (is.null(twilio_phone_number)) 38 | stop ("Please supply your Twilio phone number in the `twilio_phone_number` argument.") 39 | if (is.null(target_phone_number)) 40 | stop ("Please supply your target phone number in the `target_phone_number` argument.") 41 | 42 | 43 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44 | # store variables in .Renviron 45 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 46 | 47 | # open the .Renviron file to store API info 48 | if (!file.exists("~/.Renviron")) # only create if not already there 49 | file.create("~/.Renviron") # (don't overwrite it) 50 | renv <- readLines("~/.Renviron") # read the .Renviron file 51 | 52 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 53 | # Manage overwite conditions 54 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | 56 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | # Twilio SID 58 | 59 | # if a Twilio SID is already set, but overwrite permission isn't granted 60 | if (sum(grepl("TWILIO_SID", renv)) > 0 & isFALSE(overwrite)) 61 | stop ("TWILIO_SID is already set in .Renviron. If you wish to overwrite it, set the `overwrite` argument to TRUE.") 62 | 63 | # if a Twilio SID is already set, and overwrite permission is granted 64 | if (sum(grepl("TWILIO_SID", renv)) > 0 & isTRUE(overwrite)) 65 | renv[grep("TWILIO_SID", renv)] <- paste("TWILIO_SID =", twilio_sid) 66 | 67 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | # Twilio token 69 | 70 | # if a Twilio token is already set, but overwrite permission isn't granted 71 | if (sum(grepl("TWILIO_TOKEN", renv)) > 0 & isFALSE(overwrite)) 72 | stop ("TWILIO_TOKEN is already set in .Renviron. If you wish to overwrite it, set the `overwrite` argument to TRUE.") 73 | 74 | # if a Twilio token is already set, and overwrite permission is granted 75 | if (sum(grepl("TWILIO_TOKEN", renv)) > 0 & isTRUE(overwrite)) 76 | renv[grep("TWILIO_TOKEN", renv)] <- paste("TWILIO_TOKEN =", twilio_token) 77 | 78 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 | # Twilio phone number 80 | 81 | # if a Twilio token is already set, but overwrite permission isn't granted 82 | if (sum(grepl("TWILIO_PHONE_NUMBER", renv)) > 0 & isFALSE(overwrite)) 83 | stop ("TWILIO_PHONE_NUMBER is already set in .Renviron. If you wish to overwrite it, set the `overwrite` argument to TRUE.") 84 | 85 | # if a Twilio token is already set, and overwrite permission is granted 86 | if (sum(grepl("TWILIO_PHONE_NUMBER", renv)) > 0 & isTRUE(overwrite)) 87 | renv[grep("TWILIO_PHONE_NUMBER", renv)] <- paste("TWILIO_PHONE_NUMBER =", 88 | twilio_phone_number) 89 | 90 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 91 | # target phone number 92 | 93 | # if a Twilio token is already set, but overwrite permission isn't granted 94 | if (sum(grepl("TARGET_PHONE_NUMBER", renv)) > 0 & isFALSE(overwrite)) 95 | stop ("TARGET_PHONE_NUMBER is already set in .Renviron. If you wish to overwrite it, set the `overwrite` argument to TRUE.") 96 | 97 | # if a Twilio token is already set, and overwrite permission is granted 98 | if (sum(grepl("TARGET_PHONE_NUMBER", renv)) > 0 & isTRUE(overwrite)) 99 | renv[grep("TARGET_PHONE_NUMBER", renv)] <- paste("TARGET_PHONE_NUMBER =", 100 | target_phone_number) 101 | 102 | 103 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 104 | # if creating .Renviron from scratch 105 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 | if (sum(grepl("TWILIO_SID", renv)) == 0) 107 | renv <- c(renv, 108 | paste("TWILIO_SID =", twilio_sid) 109 | ) 110 | if (sum(grepl("TWILIO_TOKEN", renv)) == 0) 111 | renv <- c(renv, 112 | paste("TWILIO_TOKEN =", twilio_token) 113 | ) 114 | if (sum(grepl("TWILIO_PHONE_NUMBER", renv)) == 0) 115 | renv <- c(renv, 116 | paste("TWILIO_PHONE_NUMBER =", twilio_phone_number) 117 | ) 118 | if (sum(grepl("TARGET_PHONE_NUMBER", renv)) == 0) 119 | renv <- c(renv, 120 | paste("TARGET_PHONE_NUMBER =", target_phone_number) 121 | ) 122 | 123 | 124 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125 | # ensure one blank line at the end of .Renviron and write file 126 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | if (nchar(renv[length(renv)]) > 0) 128 | renv <- c(renv, "") 129 | 130 | writeLines(renv, "~/.Renviron") 131 | 132 | 133 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 134 | # set variables for this session so R doesn't need to be restarted 135 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | Sys.setenv(TWILIO_SID = twilio_sid) 137 | Sys.setenv(TWILIO_TOKEN = twilio_token) 138 | Sys.setenv(TWILIO_PHONE_NUMBER = twilio_phone_number) 139 | Sys.setenv(TARGET_PHONE_NUMBER = target_phone_number) 140 | 141 | 142 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 | # verify success 144 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | 146 | cat("Success! You've stored your Twilio credentials as environmental variables in '~/.Renviron', and your new .Renvion file looks like this: ") 147 | cat(paste(c("\n", renv), collapse="\n")) 148 | 149 | } 150 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-"#, 12 | #out.width = "100%" 13 | ) 14 | ``` 15 | # textme 16 | 17 | 18 | 19 | 20 | The heart of this package is a single function called `textme()` that sends you a text message 📱 the instant a long-running job completes ⌛✔️. 21 | 22 | Now you can leave the computer while it crunches away. Go get a cofee, hit the gym, or work on other things! You'll be notified exactly when your job completes 🎉. 23 | 24 | ![](https://github.com/richpauloo/junkyard/blob/master/img/textme.png?raw=true) 25 | 26 | 27 | ## Installation 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | **textme** is not currently on CRAN. Install the development version from github: 36 | 37 | ```r 38 | devtools::install_github("richpauloo/textme") 39 | ``` 40 | 41 | ## Example 42 | 43 | First, sign up for a free Twilio trial account. 44 | 45 | 1. [regular sign up](https://www.twilio.com/) 46 | 2. [my referral link](https://www.twilio.com/referral/rIaK9w), and if you decide down the line to upgrade to a paid Twilio account (I have one), you and I both get $10 in free credit (~1,250 messages). 47 | 48 | It doesn't matter to me which road you take. Go for option 1. just to get started and to avoid ponzi-scheme vibes. 49 | 50 | Next, [set up a project](https://support.twilio.com/hc/en-us/articles/360011177133-View-and-Create-New-Projects-in-Twilio-Console) and [verify your number](https://support.twilio.com/hc/en-us/articles/223180048-Adding-a-Verified-Phone-Number-or-Caller-ID-with-Twilio). The Twilio docs are good for this. 51 | 52 | Then, provide information about your twilio account and the number you want to text. These variables are stored in `"~/.Renviron"` for later use. The benefit of doing it this way is that it's virtually impossible to accidentally push these credentials to Github, which is likely if you save them in scripts. 53 | 54 | 55 | ```{r setup, eval = FALSE} 56 | library(textme) 57 | 58 | # replace the values here with your own 59 | tm_configure(twilio_sid = "AC1ffb4917879549a0f0720c0214bde131", 60 | twilio_token = "f5c8904b9af81daf3e8dda09f975c369", 61 | twilio_phone_number = "1234567890", 62 | target_phone_number = "0987654321") 63 | ``` 64 | 65 | The above code needs to be run only once. Now, and in future R sessions, simply throw a `textme()` at the end of a long-running job (**textme** comes pre-loaded with a handful of fun messages): 66 | 67 | ```{r eval = FALSE} 68 | Sys.sleep(5) # some long-running job 69 | textme() # text me when it's done! 70 | ``` 71 | 72 | Or, you can supply a custom message with the `message` argument: 73 | 74 | ```{r, eval = FALSE} 75 | textme(message = "👹 Back to work! You're not paid to run around and drink ☕ all day!") 76 | ``` 77 | 78 | 79 | ## Acknowledgments 80 | 81 | This package is inspired by [{ beepr }](https://www.r-project.org/nosvn/pandoc/beepr.html), and wouldn't be possible without the [{ twilio }](https://github.com/seankross/twilio) package from Sean Kross, [{ devtools }](https://github.com/r-lib/devtools), [{ roxygen2}](https://github.com/r-lib/roxygen2), and [RStudio](https://www.rstudio.com/). 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # textme 5 | 6 | 7 | 8 | 9 | 10 | Major thanks to Sean Kross for the [{ twilio 11 | }](https://github.com/seankross/twilio) package, 12 | which this package relies entirely upon. 13 | 14 | The heart of this package is a single function called `textme()` that 15 | sends you a text message 📱 the instant a long-running job completes ⌛✔️. 16 | 17 | Now you can leave the computer while it crunches away. Go get a cofee, 18 | hit the gym, or work on other things\! You’ll be notified exactly when 19 | your job completes 🎉. 20 | 21 | ![](https://github.com/richpauloo/junkyard/blob/master/img/textme.png?raw=true) 22 | 23 | ## Installation 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | **textme** is not currently on CRAN. Install the development version 34 | from github: 35 | 36 | ``` r 37 | devtools::install_github("richpauloo/textme") 38 | ``` 39 | 40 | ## Example 41 | 42 | First, sign up for a free Twilio trial account. 43 | 44 | 1. [regular sign up](https://www.twilio.com/) 45 | 2. [my referral link](https://www.twilio.com/referral/rIaK9w). If 46 | you decide to upgrade to a paid Twilio account (I have 47 | one), you and I both get $10 in free credit. 48 | 49 | If option 2 gives you ponzi-scheme vibes, go for option 1. It doesn’t matter to me which road you take. 50 | 51 | Next, [set up a 52 | project](https://support.twilio.com/hc/en-us/articles/360011177133-View-and-Create-New-Projects-in-Twilio-Console) 53 | and [verify your 54 | number](https://support.twilio.com/hc/en-us/articles/223180048-Adding-a-Verified-Phone-Number-or-Caller-ID-with-Twilio). 55 | The Twilio docs are good for this. 56 | 57 | Then, provide information about your twilio account and the number you 58 | want to text. These variables are stored in `"~/.Renviron"` for later 59 | use. The benefit of doing it this way is that it’s virtually impossible 60 | to accidentally push these credentials to Github, which is likely if you 61 | save them in scripts. 62 | 63 | ``` r 64 | library(textme) 65 | 66 | # replace the values here with your own 67 | tm_configure(twilio_sid = "AC1ffb4917879549a0f0720c0214bde131", 68 | twilio_token = "f5c8904b9af81daf3e8dda09f975c369", 69 | twilio_phone_number = "1234567890", 70 | target_phone_number = "0987654321") 71 | ``` 72 | 73 | The above code needs to be run only once. Now, and in future R sessions, 74 | simply throw a `textme()` at the end of a long-running job (**textme** 75 | comes pre-loaded with a handful of fun messages): 76 | 77 | ``` r 78 | Sys.sleep(5) # some long-running job 79 | textme() # text me when it's done! 80 | ``` 81 | 82 | Supply a custom message: 83 | 84 | ``` r 85 | textme(message = "👹 Back to work! You're not paid to run around and drink ☕ all day!") 86 | ``` 87 | 88 | ## Acknowledgments 89 | 90 | This package is inspired by [{ beepr 91 | }](https://www.r-project.org/nosvn/pandoc/beepr.html), and wouldn’t be 92 | possible without [{ devtools 93 | }](https://github.com/r-lib/devtools), [{ 94 | roxygen2}](https://github.com/r-lib/roxygen2), and 95 | [RStudio](https://www.rstudio.com/). 96 | -------------------------------------------------------------------------------- /man/textme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/textme.R 3 | \name{textme} 4 | \alias{textme} 5 | \title{Send a text message.} 6 | \usage{ 7 | textme(message = NULL, twilio_sid = NULL, twilio_token = NULL, 8 | twilio_phone_number = NULL, target_phone_number = NULL) 9 | } 10 | \arguments{ 11 | \item{message}{A message to send.} 12 | 13 | \item{twilio_sid}{Twilio SID--not needed if supplied in \code{\link{tm_configure()}}.} 14 | 15 | \item{twilio_token}{Twilio token--not needed if supplied in \code{\link{tm_configure.R}}.} 16 | 17 | \item{twilio_phone_number}{Twilio phone number--not needed if supplied in \code{\link{tm_configure}}.} 18 | 19 | \item{target_phone_number}{Target phone number--not needed if supplied in \code{\link{tm_configure}}.} 20 | } 21 | \value{ 22 | A text message sent from the twilio phone number to the target phone number. 23 | } 24 | \description{ 25 | Send a text message. 26 | } 27 | \examples{ 28 | 29 | # send a text message 30 | textme() 31 | 32 | # send a custom message 33 | textme(message = "A new text message.") 34 | 35 | # send a text message to a different number 36 | textme(target_phone_number = "1234567890") 37 | 38 | } 39 | -------------------------------------------------------------------------------- /man/tm_configure.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tm_configure.R 3 | \name{tm_configure} 4 | \alias{tm_configure} 5 | \title{Store Twilio SID, Twilio token, Twilio phone number, and target phone number for later use.} 6 | \usage{ 7 | tm_configure(twilio_sid = NULL, twilio_token = NULL, 8 | twilio_phone_number = NULL, target_phone_number = NULL, 9 | overwrite = FALSE) 10 | } 11 | \arguments{ 12 | \item{twilio_sid}{Your Twilio SID.} 13 | 14 | \item{twilio_token}{Your Twilio Token.} 15 | 16 | \item{twilio_phone_number}{Your Twilio phone number.} 17 | 18 | \item{target_phone_number}{The phone number you want to receive a text message at} 19 | 20 | \item{overwrite}{By default, this is set to \code{FALSE}. If \code{TRUE}, R will overwrite existing .Renviron variables that match the ones named in this function.} 21 | } 22 | \value{ 23 | A .Renviron file that stores the supplied paramaters for ease of use in future R sessions. 24 | } 25 | \description{ 26 | Store Twilio SID, Twilio token, Twilio phone number, and target phone number for later use. 27 | } 28 | \examples{ 29 | 30 | # set parameters 31 | tm_configure(twilio_sid = "AC1ffb497954c02119a0f0720784bde131", 32 | twilio_token = "f5c8af81ddadaf3e8904b909f975c369", 33 | twilio_phone_number = "1234567890", 34 | target_phone_number = "0987654321") 35 | 36 | # view and edit the .Renvion file 37 | file.edit("~/.Renviron") 38 | 39 | } 40 | -------------------------------------------------------------------------------- /textme.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/my-vignette.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Send text message notifications from R" 3 | author: "Rich Pauloo" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{my-vignette} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | Some R users run code that takes a long time to process. To notify users when code is done execuing, the [`beepr`](https://cran.r-project.org/web/packages/beepr/index.html) package is a great tool that plays a sound on the computer. 20 | 21 | In the spirit of `beepr::beep()`, this package provides a single function called `textme()` that sends you a text message the instant a long-running job completes. This allows you to leave your computer while running code, and know exactly when to return. 22 | 23 | *** 24 | 25 | This package relies on Twilio to send text messages. Presently, free trial accounts are avaialble. Sign up for a [twilio account here](https://www.twilio.com/). 26 | 27 | On the user dashboard, take note of three pieces of information: 28 | 29 | * Twilio SID 30 | * Twilio token 31 | * Twilio phone number 32 | 33 | You only need to set these variables once. Afterward, they are stored in the `.Renviron` file of your home directory. To store these variables, use `tm_configure()`. It is recommended that you set a target phone number as well--this should be **your phone number**, where you want to **receive** text messages. 34 | 35 | ```{r setup, eval = FALSE} 36 | library(textme) 37 | 38 | # replace the values here with your own 39 | tm_configure(twilio_sid = "AC1ffb4919a0f0720787954c0214bde131", 40 | twilio_token = "f5c8daf3e8904b9af81dda09f975c369", 41 | twilio_phone_number = "1234567890", 42 | target_phone_number = "0987654321") 43 | ``` 44 | 45 | Once you've configured your environment, you should be able to send a text message. In future sessions, you don't need to re-configure anything. You should be able to simply run `textme()` and `R` will load your stored SID, token, and phone numbers. 46 | 47 | ```{r eval = FALSE} 48 | textme() 49 | ``` 50 | 51 | To send a custom message, simply supply a `message` argument: 52 | ```{r, eval = FALSE} 53 | textme(message = "My custom message.") 54 | ``` 55 | 56 | To send a message to another number, supply a new `target_phone_number`: 57 | ```{r, eval = FALSE} 58 | textme(target_phone_number = "1112223333") 59 | ``` 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | --------------------------------------------------------------------------------