在R Shiny中实现将编织临时文件附加至邮件的功能
Got it, let's get this working smoothly for you! The core idea is to first generate your RMarkdown report to a temporary file when the email button is clicked, then include that file as an attachment in your Mailgun API request. Here's the complete implementation:
Step 1: Required Packages
First, make sure these packages are installed and loaded—they handle Shiny interactions, report rendering, API calls, and MIME type detection:
install.packages(c("shiny", "rmarkdown", "httr", "mime"))
Step 2: UI Code (No Major Changes)
Your existing UI works perfectly; I’ve included it here for completeness:
library(shiny) shinyUI(fluidPage( sliderInput("slider", "Slider", 1, 100, 50), downloadButton("report", "Generate report"), actionButton("mail", "Send Email"), textOutput('mailStatus') ))
Step 3: Full Server Logic with Attachment Support
Here’s the updated server.R code that ties report generation and email sending together. Replace the placeholder values (like YOUR_MAILGUN_API_KEY) with your actual Mailgun credentials:
library(shiny) library(rmarkdown) library(httr) library(mime) shinyServer(function(input, output) { # Reusable function to generate the report (works for both download and email) generate_report <- function() { # Create a unique temporary file to hold the report (use .html for HTML reports) temp_report <- tempfile(fileext = ".pdf") # Render the RMarkdown report, passing the slider value as a parameter render("report.Rmd", output_file = temp_report, params = list(slider_value = input$slider)) return(temp_report) } # Existing download handler for standalone report downloads output$report <- downloadHandler( filename = function() { paste0("report_", Sys.Date(), ".pdf") }, content = function(file) { file.copy(generate_report(), file) } ) # Email sending logic with attachment observeEvent(input$mail, { # Generate the report first report_path <- generate_report() # Mailgun API configuration - replace these with your own details! mailgun_api_key <- "YOUR_MAILGUN_API_KEY" mailgun_domain <- "YOUR_MAILGUN_DOMAIN" # e.g., "mg.yourdomain.com" from_email <- "Your Shiny App <noreply@yourdomain.com>" to_email <- "recipient@example.com" email_subject <- "Your Requested Report" email_body <- "Attached is the report generated from the Shiny app." # Send POST request to Mailgun API with the attachment response <- POST( url = paste0("https://api.mailgun.net/v3/", mailgun_domain, "/messages"), authenticate("api", mailgun_api_key), body = list( from = from_email, to = to_email, subject = email_subject, text = email_body, attachment = upload_file(report_path, type = mime::guess_type(report_path)) ) ) # Update status message for the user if (http_status(response)$category == "Success") { output$mailStatus <- renderText("Email sent successfully!") } else { output$mailStatus <- renderText(paste("Failed to send email. Error:", content(response)$message)) } # Clean up the temporary file (good practice to avoid clutter) file.remove(report_path) }) })
Key Details to Note:
- Reusable Report Logic: The
generate_report()function is shared between the download button and email button, so you don’t duplicate code. - Temporary Files:
tempfile()creates a unique, isolated file for each report, preventing conflicts and getting cleaned up after sending. - Mailgun Setup: Ensure your Mailgun domain is verified and your API key has permission to send emails with attachments.
- RMarkdown Params: Your
report.Rmdneeds aparamssection to accept the slider value. Here’s a quick example of the top of your.Rmdfile:--- title: "Generated Report" params: slider_value: NA --- ## Report Details Slider value at generation: **`r params$slider_value`** - MIME Type Detection:
mime::guess_type()ensures Mailgun correctly identifies the attachment format (PDF, HTML, etc.).
内容的提问来源于stack exchange,提问作者eflores89

