You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用emayili自动化发送含个性化过滤数据的R Markdown邮件报告的实现方案

Hey Yoav, I’ve run into similar issues with emayili and personalized R Markdown reports before—let’s break down two solid solutions that should work for you, since the emayili::render function doesn’t support params directly.


Solution 1: Render HTML Reports First, Then Inject into Emails

Your initial idea of pre-rendering HTML was on the right track—you probably just missed a step in loading the HTML content correctly into the emayili envelope. Here’s how to fix it:

Step 1: Create a Parameterized R Markdown File

First, set up your report.Rmd to accept user-specific parameters:

---
title: "Your Personalized Data Report"
output: html_document
params:
  user_email: ""
  user_data: NULL
---

# Custom Report for `r params$user_email`

Below is your filtered dataset:

`r knitr::kable(params$user_data)`

Step 2: Loop Through Users, Render, and Send

In your standalone R script, render a unique HTML report for each user, read its content as a string, and pass it to emayili::html():

library(emayili)
library(rmarkdown)
library(dplyr) # For data filtering

# Define your user list with email and filtered data
user_list <- list(
  list(email = "user1@example.com", data = your_dataset %>% filter(user_id == 1)),
  list(email = "user2@example.com", data = your_dataset %>% filter(user_id == 2))
)

# Set up your SMTP client
smtp_client <- server(
  host = "smtp.yourprovider.com",
  port = 587,
  username = "your-email@example.com",
  password = "your-app-password"
)

# Loop through each user to send personalized emails
for (user in user_list) {
  # Create a temporary HTML file to store the rendered report
  temp_html <- tempfile(fileext = ".html")
  
  # Render the Rmd with user-specific params
  render(
    input = "report.Rmd",
    output_file = temp_html,
    params = list(
      user_email = user$email,
      user_data = user$data
    ),
    quiet = TRUE # Suppress render logs for cleaner output
  )
  
  # Read the HTML content as a single string (this is the key fix!)
  html_content <- readLines(temp_html, warn = FALSE) %>% paste(collapse = "\n")
  
  # Build and send the email
  email_msg <- envelope() %>%
    from("your-email@example.com") %>%
    to(user$email) %>%
    subject("Your Exclusive Data Report") %>%
    html(html_content)
  
  smtp_client(email_msg)
  
  # Clean up the temporary file
  file.remove(temp_html)
}

Why this works: emayili::html() accepts raw HTML strings, not file paths. By reading the rendered HTML into a string first, you avoid the path-related issues that likely broke your initial attempt.


Solution 2: Use Global Variables with emayili::render

If you prefer to avoid temporary files entirely, you can inject user data into the global environment before calling emayili::render:

Step 1: Adjust Your R Markdown File

Update report_global.Rmd to reference global variables instead of params:

---
title: "Your Personalized Data Report"
output: html_document
---

# Custom Report for `r current_user_email`

Below is your filtered dataset:

`r knitr::kable(current_user_data)`

Step 2: Loop and Inject Global Variables

In your R script, assign user-specific data to global variables before rendering each report:

library(emayili)
library(rmarkdown)
library(dplyr)

user_list <- list(
  list(email = "user1@example.com", data = your_dataset %>% filter(user_id == 1)),
  list(email = "user2@example.com", data = your_dataset %>% filter(user_id == 2))
)

smtp_client <- server(...) # Same SMTP setup as Solution 1

for (user in user_list) {
  # Assign user data to global variables (visible to the Rmd)
  assign("current_user_email", user$email, envir = .GlobalEnv)
  assign("current_user_data", user$data, envir = .GlobalEnv)
  
  # Render directly into the email
  email_msg <- envelope() %>%
    from("your-email@example.com") %>%
    to(user$email) %>%
    subject("Your Exclusive Data Report") %>%
    render("report_global.Rmd")
  
  smtp_client(email_msg)
  
  # Clean up global variables to avoid cross-user contamination
  rm(current_user_email, current_user_data, envir = .GlobalEnv)
}

This skips the intermediate HTML file entirely, which can be cleaner for smaller reports. Just be cautious with global variables—always clean them up after each loop iteration to prevent bugs.


Quick Notes

  • Make sure you’re running the latest versions of emayili and rmarkdown—older versions had compatibility quirks with dynamic content.
  • Test with a single user first to verify the report content and email delivery before scaling to your full user list.
  • For large datasets, Solution 1 is more reliable because it isolates each report’s rendering process.

内容的提问来源于stack exchange,提问作者yoav.raskin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:47:32