Problem: Im a fairly novice user running a script in RStudio, and it emailed out a report using outmail from the RDCOMClient library. I installed and updated RStudio and am getting error messages that RDCOMClient is no longer supported. An AI query recommended I try to setup the report to send through Microsoft Azure with token and client secret. Though Ive created a file with the client secret and have provided RStudio the path, it claims the file with the secret doesn`t exist. Any guidance you can offer? The script with errors is pasted below:
------------------------------------------------------------
BLK Tactical VP Daily Holdings + HTML Report + Graph Email
Consolidated Script with GUARANTEED Runtime Secret Loading #
options(stringsAsFactors = FALSE)
Sys.setenv(RSTUDIO_PANDOC =C:/Program Files/RStudio/bin/rstudio-pandoc)suppressPackageStartupMessages({
- library(rmarkdown)
- library(tidyverse)
- library(openxlsx)
- library(lubridate)
- library(AzureAuth)
- library(httr)
- library(jsonlite)
- library(base64enc)
- })
There were 11 warnings (use warnings() to see them)
============================================================
0) RUNTIME GRAPH SECRET LOADING (GUARANTEED FIX)
============================================================
GRAPH_SECRET_FILE <-
Y:/R/BLK/secure/graph_client_secret.txtif (!file.exists(GRAPH_SECRET_FILE)) {
- stop(
Graph secret file not found:, GRAPH_SECRET_FILE) }
Error: Graph secret file not found: Y:/R/BLK/secure/graph_client_secret.txt
client_secret <- trimws(readLines(GRAPH_SECRET_FILE, warn = FALSE))
Error in file(con,r) : cannot open the connection In addition: Warning message:
In file(con,r) :
cannot open fileY:/R/BLK/secure/graph_client_secret.txt: No such file or directoryif (!nzchar(client_secret)) {
- stop(
Graph client secret file exists but is empty) }
Error: objectclient_secretnot found
Sys.setenv(
- BLK_GRAPH_TENANT_ID =
46e16835-c804-41de-be3c-55835d14dee4, - BLK_GRAPH_CLIENT_ID =
aee4dd30-675d-45d8-b658-1d4bd198d0b3, - BLK_GRAPH_CLIENT_SECRET = client_secret
- )
Error in Sys.setenv(BLK_GRAPH_TENANT_ID =46e16835-c804-41de-be3c-55835d14dee4, :
objectclient_secretnot found
Hard fail if this ever breaks again
stopifnot(nzchar(Sys.getenv(
BLK_GRAPH_CLIENT_SECRET)))
Error: nzchar(Sys.getenv(BLK_GRAPH_CLIENT_SECRET)) is not TRUE============================================================
1) PATHS
============================================================
in_zip <-
Y:/R/BLK/Temp/attachment.zip
temp_dir <-Y:/R/BLK/Temp
in_csv <- file.path(temp_dir,BLK TA Daily Holdings - Prior Close.csv)out_dir <-
Y:/R/BLK/Outputs
rmd_in <-Y:/R/BLK/Inputs/BLK_TA_Calc.Rmdif (!dir.exists(out_dir)) dir.create(out_dir, recursive = TRUE)
============================================================
2) UNZIP + READ CSV
============================================================
if (!file.exists(in_zip)) stop(
Input zip not found:, in_zip)
unzip(in_zip, exdir = temp_dir)if (!file.exists(in_csv)) stop(
Holdings CSV not found:, in_csv)blk_raw <- read.csv(in_csv, stringsAsFactors = FALSE, check.names =
FALSE)normalize_names <- function(x) {
- x |> trimws() |> tolower() |> gsub(
[^a-z0-9]+,_, _) |> - gsub(
^_|_$, ``, _)
Error: unexpected>in:
normalize_names <- function(x) { x |>
}
Error: unexpected}in}
names(blk_raw) <- normalize_names(names(blk_raw))
Error in normalize_names(names(blk_raw)) :
could not find functionnormalize_namesrequired_cols <- c(
period_end_date,cusip_number,asset_class,security_name,base_market_value,percent_of_fund- )
missing <- setdiff(required_cols, names(blk_raw)) if (length(missing)
- stop(
Missing required columns:, paste(missing, collapse =,))
Error: Missing required columns: period_end_date, cusip_number, asset_class, security_name, base_market_value, percent_of_fund============================================================
3) AS-OF DATE
============================================================
blk_raw$period_end_date <- mdy(blk_raw$period_end_date)
Error in$<-.data.frame(*tmp*, period_end_date, value = numeric(0)) :
replacement has 0 rows, data has 19
if (all(is.na(blk_raw$period_end_date))) stop(Unable to parse Period End Date)
Error: Unable to parse Period End Dateasof <- as.character(blk_raw$period_end_date[1])
if (!nzchar(asof)) stop(As-of date could not be determined)
Error in if (!nzchar(asof)) stop(As-of date could not be determined) :
argument is of length zeroblk_raw$cusip_number <- gsub(
^``, ``, blk_raw$cusip_number) Error in$<-.data.frame(tmp`, cusip_number, value = character(0)) :
replacement has 0 rows, data has 19write.xlsx(
- blk_raw,
- file = file.path(out_dir, paste0(
BLK TA -, asof,.xlsx)), - overwrite = TRUE
- )
============================================================
4) WORKING DATA + CLASSIFICATION
============================================================
blk <- blk_raw |>
Error: unexpected>inblk <- blk_raw |>
transmute(
-
CUSIP = cusip_number, -
AssetClass = asset_class, -
SecurityName = security_name, -
MarketValueUSD = as.numeric(base_market_value), -
WeightPct = as.numeric(percent_of_fund) - )
Error in transmute(CUSIP = cusip_number, AssetClass = asset_class, SecurityName = security_name, :
objectcusip_numbernot found
etf_override <- c(
900934845,900934852)blk <- blk |>
Error: unexpected>inblk <- blk |>
mutate(
-
Type = case_when( -
CUSIP %in% etf_override ~ `ETF`, -
str_detect(AssetClass, `CASH`) ~ `CASH`, -
AssetClass == `FUTURE` ~ `FUTURE`, -
AssetClass == `EQUITY` & -
str_detect(SecurityName, `TRANSAMERICA|TA | VP`) & -
!str_detect(SecurityName, `\\bETF\\b`) ~ `FUND`, -
AssetClass == `EQUITY` ~ `ETF`, -
TRUE ~ `OTHER` -
) - )
Error in CUSIP %in% etf_override : objectCUSIPnot found
blkta <- blk |>
Error: unexpected>inblkta <- blk |>
select(
-
CUSIP, Type, -
`Security Name` = SecurityName, -
`Market Value - USD` = MarketValueUSD, -
`Weight - %` = WeightPct - ) |>
Error: unexpected>in:
Weight - %= WeightPct ) |>
mutate(
-
`Market Value - USD` = round(`Market Value - USD`, 0), -
`Weight - %` = round(`Weight - %`, 2) - )
Error in mutate(Market Value - USD= round(Market Value - USD, 0), :
objectMarket Value - USDnot found
blklist <- split(blkta, blkta$Type)
Error in split(blkta, blkta$Type) : objectblktanot foundadd_total <- function(df) {
- df2 <- df |> select(-Type)
Error: unexpected>in:
add_total <- function(df) { df2 <- df |>
bind_rows(
-
df2, -
tibble( -
CUSIP = ``, -
`Security Name` = ``, -
`Market Value - USD` = sum(df2$`Market Value - USD`, na.rm = TRUE), -
`Weight - %` = sum(df2$`Weight - %`, na.rm = TRUE) -
) - )
Error in list2(...) : objectdf2not found
}
Error: unexpected}in}
blklist <- lapply(blklist, add_total)
Error in h(simpleError(msg, call)) :
error in evaluating the argumentXin selecting a method for functionlapply: objectblklistnot found============================================================
5) RENDER HTML
============================================================
html_file <- paste0(
BLK TA -, asof,.html) html_out <-
file.path(out_dir, html_file)render(
- input = rmd_in,
- output_file = html_file,
- output_dir = out_dir,
- envir = globalenv()
- )
processing file: BLK_TA_Calc.Rmd
|....................... | 17%
ordinary text without R code
|.............................................. | 33%
label: unnamed-chunk-1 (with options)
List of 1
$ include: logi FALSE
|..................................................................... | 50%
inline R code fragments
|............................................................................................ | 67%
label: unnamed-chunk-2 (with options)
List of 2
echo : logi FALSE
results: chr asis
Quitting from lines 16-38 (BLK_TA_Calc.Rmd) Error in nrow(blkta[blkta$Type == ETF, ]) : object blkta not found
if (!file.exists(html_out)) stop(
HTML was not created)============================================================
6) MICROSOFT GRAPH EMAIL (APP ONLY)
============================================================
token <- AzureAuth::get_azure_token(
- resource =
https://graph.microsoft.com/.default, - tenant = Sys.getenv(
BLK_GRAPH_TENANT_ID), - app = Sys.getenv(
BLK_GRAPH_CLIENT_ID), - password = Sys.getenv(
BLK_GRAPH_CLIENT_SECRET), - auth_type =
client_credentials, - version = 2
- )
Error in process_aad_response(res) :
Unauthorized (HTTP 401). Failed to obtain Azure Active Directory token. Message:
AADSTS7000216:client_assertion,client_secretorrequestis required for theclient_credentialsgrant type. Trace ID: e7798ef2-89d0-4563-85d1-6c59cb193a00 Correlation ID: cbb1f8ea-76d5-4e03-8064-1a71da876325 Timestamp: 2026-05-07 20:04:43Z.
access_token <- token$credentials$access_token
Error: objecttokennot foundsend_graph_mail <- function(from_user, to, subject, body, attachment)
{
- url <- sprintf(
https://graph.microsoft.com/v1.0/users/%s/sendMail, - from_user)
- recipients <- lapply(to, function(x) list(emailAddress =
- list(address = x)))
- raw <- readBin(attachment,
raw, file.info(attachment)$size) - payload <- list(
-
message = list( -
subject = subject, -
body = list(contentType = `Text`, content = body), -
toRecipients = recipients, -
attachments = list(list( -
`@odata.type` = `#microsoft.graph.fileAttachment`, -
name = basename(attachment), -
contentBytes = base64enc::base64encode(raw), -
contentType = `text/html` -
)) -
), -
saveToSentItems = TRUE - )
- resp <- POST(
-
url, -
add_headers(Authorization = paste(`Bearer`, access_token)), -
body = toJSON(payload, auto_unbox = TRUE), -
encode = `json` - )
- if (status_code(resp) >= 300)
-
stop(`Graph sendMail failed: `, content(resp, `text`)) }
send_graph_mail(
- from_user =
kane.cotton@transamerica.com, - to = c(
-
`first.last@transamerica.com`, - ),
- subject =
Daily BlackRock Tactical Update, - body = paste(
Please open the HTML in Chrome:, html_out), - attachment = html_out
- )
Error in paste(Bearer, access_token) : objectaccess_tokennot found >
message(
SUCCESS: Report generated and email sent →, html_out)
SUCCESS: Report generated and email sent → Y:/R/BLK/Outputs/BLK TA - .html