mailR: Sending mail to multiple addresses from shiny - r

I am trying to send a mail from my Shiny app. I have created text input boxes for to address, subject and body of the mail. The app sends mail when I my input in textInput box is a single email Id. When I add the second email id, it fails. However, the same code when I try to run it from RStudio instead of a shiny app, I am able to send the emails. How do I make my textInput parse the email id correctly so that mailR sends mail to them?
My current code:
library(shiny)
library(mailR)
ui =fluidPage(
fluidRow(
div(id = "login",
wellPanel(title = "Mail your report",
textInput("to", label = "To:", placeholder = "To:"),
textInput("sub","Subject:"),
textInput("msg","Message:"),
actionButton("mailButton",label = "Send mail")
)
))
)
server = function(input, output, session) {
observeEvent(input$mailButton,{
isolate({
send.mail(from = "myemail#gmail.com",
to = input$to,
subject = input$sub,
body = input$msg,
smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "myemail#gmail.com", passwd = "mypasword", ssl = TRUE),
authenticate = TRUE,
html = TRUE,
send = TRUE)
})
})
}
runApp(list(ui = ui, server = server))
I am getting the following error:
Listening on http://127.0.0.1:3499
javax.mail.internet.AddressException: Illegal address in string ``email1#gmail.com, email2#gmail.com''
at javax.mail.internet.InternetAddress.<init>(InternetAddress.java:114)
NULL
Warning: Error in : AddressException (Java): Illegal address
Stack trace (innermost first):
83: <Anonymous>
82: signalCondition
81: doWithOneRestart
80: withOneRestart
79: withRestarts
78: message
77: value[[3L]]
76: tryCatchOne
75: tryCatchList
74: tryCatch
73: .jTryCatch
72: .valid.email
71: send.mail
64: isolate
63: observeEventHandler [#3]
1: runApp
ERROR: [on_request_read] connection reset by peer

Try this, assuming the separator between emails is the semicolon:
to = unlist(strsplit(input$to, ";", fixed = TRUE))

Related

Error sending html with mailR "can only read in bytes in a non-UTF-8 MBCS locale"

The environment is windows 7 and Rstudio version 4.0.1
I want to send html created with Rmarkdown using mailR.
I am using the following code.
send.R
library(rmarkdown)
rmarkdown::render("example.Rmd")
library(mailR)
send.mail(from = "me#gmail.com",
to = "me#gmail.com",
subject = "R Markdown Report - rmarkdown",
html = T,
inline = T,
body = "example.html",
smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "me", passwd = "password", ssl = T),
authenticate = T,
send = T)
example.Rmd
---
title: "Report for email"
output:
html_document:
self_contained: no
---
```{r}
summary(cars)
\```
Using this code I get the following error
Error: EmailException (Java): Sending the email to the following server failed : smtp.gmail.com:465
In addition: Warning message:
In readChar(body, file.info(body)$size) :
can only read in bytes in a non-UTF-8 MBCS locale
With this code
body = "example.html",
change
body = "text",
The transmission is successful
Is there a solution?
Thank you

R Shiny sending user-uploaded file via email attachment

I am trying to build a Shiny app that will accept a user-uploaded file as well as some other user-input information (textInput inputs), then send me an email using the textInput objects to fill out the subject, body, etc. while taking the file and attaching it to the email with a specific name, using the mailR package. I've posted the code I'm using below (with email addresses, usernames, and passwords changed).
Code
# load packages
library(shiny)
library(rJava)
library(mailR)
library(timeDate)
##############
##### ui -----
##############
ui = fluidPage(
fluidRow(
wellPanel(title = "Submit Data to the Database",
textInput("name", label = "Name:", placeholder = "Name"),
textInput("email","Email Address:"),
textInput("inst","Institution:"),
textInput("notes","Notes:", placeholder = ""),
fileInput("userdata", label = "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")),
actionButton("submitdata",label = "Submit Data")
)
))
##################
##### server -----
##################
server <- function(input, output) {
observeEvent(input$submitdata, {
isolate({
send.mail(from = "myemail#gmail.com",
to = "myotheremail#gmail.com",
subject = paste("New data submitted to WoodDAM from", input$name, sep = " "),
body = paste(input$name, "from institution:", input$inst, "with email:", input$email,
"has submitted data to the wood jam dynamics database.",
"This data is attached to this email",
input$name, "sent the following note accompanying this data:", input$note, collapse = ","),
smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "myusername", passwd = "mypassword", ssl = TRUE),
authenticate = TRUE,
send = TRUE,
attach.files = input$userdata,
file.names = paste(timeDate(Sys.time(), FinCenter = "America/Denver"), input$name, "WooDDAM_user_data", sep = "_", collapse = ","), # optional parameter
debug = T)
})
})
}
shinyApp(ui = ui, server = server)
When I run this app in an external viewer (chrome browser), I can input text and get an email to send just fine, but when I upload a test .csv file and click the submit button, it returns the error shown below.
Error
Listening on http://127.0.0.1:3587
Warning: Error in .createEmailAttachments: If not NULL, length of argument 'file.names' must equal length of argument 'file.paths'
Stack trace (innermost first):
77: .createEmailAttachments
76: send.mail
69: isolate
68: observeEventHandler [#3]
4: <Anonymous>
3: do.call
2: print.shiny.appobj
1: <Promise>
When I remove the file.names argument by commenting it out, thinking that will fix things, I get the following error:
2nd Error
Warning: Error in file.exists: invalid 'file' argument
Stack trace (innermost first):
78: file.exists
77: .createEmailAttachments
76: send.mail
69: isolate
68: observeEventHandler [#3]
4: <Anonymous>
3: do.call
2: print.shiny.appobj
1: <Promise>
Does anyone have any suggestions as to how to get this app to send the uploaded csv file without throwing an error? I suspect I'm doing something wrong when I try to feed input$userdata to the attach.files argument of send.mail, but I'm not sure how else to make that input be the email attachment. Although the file names issue is annoying, I could live with not being able to change the file name, as long as the uploaded file gets attached to the email.
Thanks for any help you can provide!
The reason why it doesn't work is that you're providing the object input$userdata to the send.mail function instead of the filepath.
If you print out the contents of input$userdata you can see that it contains the following attributes:
name
size
type
datapath
You should pass the datapath like this: attach.files = input$userdata$datapath.
With this the syntax is corrected, however you may still need to enable less secure apps on your google account if you're keen on using gmail.

shinyFiles defining a web directory as the root

I am trying to create a simple shiny app using shineFiles that allows users to select a file for download from a directory on the web.
library(shiny)
library(shinyFiles)
ui <- fluidPage(
shinyFilesButton('files', label='File select', title='Please select a file', multiple=FALSE)
)
server <- function(input, output) {
shinyFileChoose(input, 'files',
roots = (root = c('http://mirrors.vbi.vt.edu/mirrors/ftp.ncbi.nih.gov/blast/db/')),
filetypes=c('', 'txt' , '.gz' , '.md5'))
}
shinyApp(ui = ui , server = server)
However, I am getting the below error:
Listening on http://127.0.0.1:6772
Warning: Error in fileGet: Roots must be a named vector or a function returning one
Stack trace (innermost first):
60: fileGet
59: do.call
58: observerFunc
1: runApp
ERROR: [on_request_read] connection reset by peer
I need help in defining the directory as: http://mirrors.vbi.vt.edu/mirrors/ftp.ncbi.nih.gov/blast/db/

How to access the environment of the function that started a Shiny application?

I have a Shiny application that I run by calling a function that calls shiny::runApp. The application can access the global environment, therefore it can access to data in objects that have a name decided in advance. However, I would like to pass it data through the parameters of the function that runs the app. The following example works.
f <- function(param) {
runApp(
list(
ui = fixedPage({
verbatimTextOutput('text')
}),
server = function(input, output) {
output$text <- renderPrint(param)
})
)
}
f("hello")
However, I can not reproduce this behaviour when the ui and server components are loaded from a file:
File contents:
$ cat ui.R
fixedPage({
verbatimTextOutput('text')
})
$ cat server.R
function(input, output) {
output$text <- renderPrint(param)
}
R code:
g <- function(param) {
runApp()
}
g("hello")
Error message:
Listening on http://127.0.0.1:3870
Warning: Error in renderPrint: object 'param' not found
Stack trace (innermost first):
86: renderPrint
85: func
84: eval
83: eval
82: withVisible
81: evalVis
80: utils::capture.output
79: paste
78: origRenderFunc
77: output$text
2: runApp
1: g [#2]
I guess that it has something to do with the fact that the components are not created in similar scopes in the two examples, but I could not find a workaround... In the second example, is there a way where I can access the environment of the function g from the Shiny app ?
Yes. Define the param object in the global environment:
g <- function(param) {
assign("param",param,.GlobalEnv)
runApp()
}
#this now works and print `hello` as intended
g("hello")

'Failed to connect: no buffer space' when curlPerform attempted

I'm sending a curlPerform with curl.opts set to
curl.opts = curlOptions(
httpheader = c(
'Content-Type' = "application/x-www-form-urlencoded; charset=UTF-8",
'Accept' = "application/json"
),
verbose = FALSE,
header = TRUE,
useragent = "RCurl"
)
and I eventually get the error "failed to connect to 192.168.141.136: no buffer space".
I need to run this program constantly for days but this happens after about 6 minutes.
Is there a way to set the buffer maximum higher?
Alternatively, is there a way to view how much "buffer space" is remaining? If so I can set it to restart R and resume the program.
Note that this happens if the program runs for a while, stops, and I manually restart it. The "buffer" is never being cleared. The only way to clear it that I've found is to restart R.
If it helps, I also lose my "connection" with Rstudio, even if I'm just doing this with a separate R window, and I also lose my connection to the internet after getting this error until I close R
edit: here is a partial result of traceback() (the rest isn't a problem)
11: fun(structure(list(message = msg, call = sys.call()), class = c(typeName,
"GenericCurlError", "error", "condition")))
10: function (type, msg, asError = TRUE)
{
if (!is.character(type)) {
i = match(type, CURLcodeValues)
typeName = if (is.na(i))
character()
else names(CURLcodeValues)[i]
}
typeName = gsub("^CURLE_", "", typeName)
fun = (if (asError)
stop
else warning)
fun(structure(list(message = msg, call = sys.call()), class = c(typeName,
"GenericCurlError", "error", "condition")))
}(7L, "Failed to connect to 192.168.141.136: No buffer space",
TRUE)
9: .Call("R_curl_easy_perform", curl, .opts, isProtected, .encoding,
PACKAGE = "RCurl")
8: curlPerform(url = "http://gt-tradeview/House/TradeView/ajax/varys",
postfields = mkURL(parameters), .opts = curl.opts, writefunction = r$update,
post = 1L, curl = r$curl()) at functiondefinitionsLive.R#211
7: value[[3L]](cond)
6: tryCatchOne(expr, names, parentenv, handlers[[1L]])
5: tryCatchList(expr, classes, parentenv, handlers)
The problem was that handles were being reserved with every call, and never closed. To prevent this, get a curl handle with getCurlHandle() then pass that with the curl argument in dynCurlReader()
I was having the same issues with the getURL command. I tried CloseAllConnections() but that did not seem to work.
When I restarted the R session then the issue was resolved automatically. However, I have to admit that I got the issue when my RStudio ( R Session ) was opened for a long time. Might be some memory usage that an empty R Session does

Resources