diff --git a/DESCRIPTION b/DESCRIPTION index f28060d..fdb2943 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,4 +17,5 @@ Suggests: aws.sns URL: https://github.com/cloudyr/aws.ses BugReports: https://github.com/cloudyr/aws.ses/issues -RoxygenNote: 6.0.1 +RoxygenNote: 6.1.0 +Encoding: UTF-8 diff --git a/R/http.R b/R/http.R index 760c394..876ab74 100644 --- a/R/http.R +++ b/R/http.R @@ -8,6 +8,7 @@ #' @param key A character string specifying an AWS Access Key. See \code{\link[aws.signature]{locate_credentials}}. #' @param secret A character string specifying an AWS Secret Key. See \code{\link[aws.signature]{locate_credentials}}. #' @param session_token Optionally, a character string specifying an AWS temporary Session Token to use in signing a request. See \code{\link[aws.signature]{locate_credentials}}. +#' @param force_credentials A logical set to \code{TRUE} or \code{FALSE}. Use \code{TRUE} only if you are providing the key, secret, and region parameters. #' @param \dots Additional arguments passed to \code{\link[httr]{POST}}. #' @import httr #' @importFrom aws.signature signature_v4_auth @@ -20,24 +21,33 @@ function( headers = list(), body = NULL, verbose = getOption("verbose", FALSE), - region = Sys.getenv("AWS_DEFAULT_REGION", "us-east-1"), - key = NULL, - secret = NULL, + region = NULL, + key = NULL, + secret = NULL, session_token = NULL, + force_credentials = FALSE, ... ) { - # locate and validate credentials - credentials <- locate_credentials(key = key, secret = secret, session_token = session_token, region = region, verbose = verbose) - key <- credentials[["key"]] - secret <- credentials[["secret"]] - session_token <- credentials[["session_token"]] - region <- credentials[["region"]] - + # if necessary, locate and validate credentials + if(!isTRUE(force_credentials)) { + if(is.null(region)) { + region <- "us-east-1" + warning("AWS SES region defaulting to us-east-1. For us-west-2 or eu-west-1, set region parameter.") + } + SESregion <- region + region <- Sys.getenv("AWS_DEFAULT_REGION", "us-east-1") + credentials <- aws.signature::locate_credentials(key = key, secret = secret, session_token = session_token, region = region, verbose = verbose) + key <- credentials[["key"]] + secret <- credentials[["secret"]] + session_token <- credentials[["session_token"]] + region <- SESregion + } + # generate request signature uri <- paste0("https://email.",region,".amazonaws.com") d_timestamp <- format(Sys.time(), "%Y%m%dT%H%M%SZ", tz = "UTC") body_to_sign <- if (is.null(body)) { - "" + "" } else { paste0(names(body), "=", sapply(unname(body), utils::URLencode, reserved = TRUE), collapse = "&") } @@ -51,7 +61,7 @@ function( canonical_headers = list(host = paste0("email.",region,".amazonaws.com"), `x-amz-date` = d_timestamp), request_body = body_to_sign, - key = key, + key = key, secret = secret, session_token = session_token, verbose = verbose) @@ -63,7 +73,7 @@ function( headers[["x-amz-security-token"]] <- session_token } H <- do.call(add_headers, headers) - + # execute request if (length(query)) { if (!is.null(body)) { @@ -78,7 +88,7 @@ function( r <- POST(uri, H, ...) } } - + if (http_error(r)) { x <- try(jsonlite::fromJSON(content(r, "text", encoding = "UTF-8"))$Error, silent = TRUE) warn_for_status(r) diff --git a/R/sendemail.R b/R/sendemail.R index 097f6d7..7692b90 100644 --- a/R/sendemail.R +++ b/R/sendemail.R @@ -14,6 +14,10 @@ #' @param charset.message An optional character string specifying the character set, e.g., \dQuote{UTF-8}, \dQuote{ISO-8859-1}, etc. if \code{message} is not ASCII. #' @param charset.html An optional character string specifying the character set, e.g., \dQuote{UTF-8}, \dQuote{ISO-8859-1}, etc. if \code{html} is not ASCII. #' @param charset.subject An optional character string specifying the character set, e.g., \dQuote{UTF-8}, \dQuote{ISO-8859-1}, etc. if \code{subject} is not ASCII. +#' @param key A character string with the key from an Amazon user's access key who has permission to send email via Amazon SES. +#' @param secret A character string with the secret from from an Amazon user's access key who has permission to send email via Amazon SES. +#' @param region A character string giving the region of the user's Amazon SES service. Note that AWS SES is only available in regions us-east-1, us-west-2, or eu-west-1. +#' @param force_credentials A logical set to \code{TRUE} or \code{FALSE}. Use \code{TRUE} only if you are providing the key, secret, and region parameters. #' @template dots #' @details Send a test or raw email message. \code{get_quota} and \code{get_statistics} provide information on remaining and used email rate limits, respectively. #' @return A character string containg the message ID. @@ -26,18 +30,18 @@ #' a <- get_verification_attrs("me@example.com") #' if (a[[1]]$VerificationStatus == "Success") { #' # simple plain-text email -#' send_email("Test Email Body", subject = "Test Email", +#' send_email("Test Email Body", subject = "Test Email", #' from = "me@example.com", to = "recipient@example.com") -#' +#' #' # html and plain text versions -#' send_email(message = "Plain text body", -#' html = "

HTML text body

", -#' subject = "Test Email", +#' send_email(message = "Plain text body", +#' html = "

HTML text body

", +#' subject = "Test Email", #' from = "me@example.com", to = "recipient@example.com") #' } #' } #' @export -send_email <- +send_email <- function(message, html, raw = NULL, @@ -51,9 +55,13 @@ function(message, charset.subject = NULL, charset.message = NULL, charset.html = NULL, + key = NULL, + secret = NULL, + region = NULL, + force_credentials = FALSE, ...) { query <- list(Source = from) - + # configure message body and subject if (!is.null(raw)) { query[["Action"]] <- "SendRawEmail" @@ -80,7 +88,7 @@ function(message, query[["Message.Subject.Charset"]] <- charset.subject } } - + # configure recipients if (length(c(to,cc,bcc)) > 50L) { stop("The total number of recipients cannot exceed 50.") @@ -97,15 +105,20 @@ function(message, names(bcc) <- paste0("Destination.BccAddresses.member.", seq_along(bcc)) query <- c(query, bcc) } - if (!is.null(replyto)) { - query[["ReplyToAddresses"]] <- replyto + names(replyto) <- paste0("ReplyToAddresses.member.", seq_along(replyto)) + query <- c(query, replyto) } if (!is.null(returnpath)) { query[["ReturnPath"]] <- returnpath } - - r <- sesPOST(body = query, ...) + + r <- sesPOST(body = query, + key = key, + secret = secret, + region = region, + force_credentials = force_credentials, + ...) structure(r[["SendEmailResponse"]][["SendEmailResult"]][["MessageId"]], RequestId = r[["SendEmailResponse"]][["ResponseMetadata"]][["RequestId"]]) } diff --git a/man/idnotification.Rd b/man/idnotification.Rd index ebebb3d..0200932 100644 --- a/man/idnotification.Rd +++ b/man/idnotification.Rd @@ -7,8 +7,8 @@ \usage{ get_id_notification(identity, ...) -set_id_notification(identity, type = c("Bounce", "Complaint", "Delivery"), - topic, ...) +set_id_notification(identity, type = c("Bounce", "Complaint", + "Delivery"), topic, ...) } \arguments{ \item{identity}{An SES identity.} diff --git a/man/sendemail.Rd b/man/sendemail.Rd index 5820b40..6605e33 100644 --- a/man/sendemail.Rd +++ b/man/sendemail.Rd @@ -6,9 +6,11 @@ \alias{get_statistics} \title{Send Email via SES} \usage{ -send_email(message, html, raw = NULL, subject, from, to = NULL, cc = NULL, - bcc = NULL, replyto = NULL, returnpath = NULL, charset.subject = NULL, - charset.message = NULL, charset.html = NULL, ...) +send_email(message, html, raw = NULL, subject, from, to = NULL, + cc = NULL, bcc = NULL, replyto = NULL, returnpath = NULL, + charset.subject = NULL, charset.message = NULL, + charset.html = NULL, key = NULL, secret = NULL, region = NULL, + force_credentials = FALSE, ...) get_quota(...) @@ -41,6 +43,14 @@ get_statistics(...) \item{charset.html}{An optional character string specifying the character set, e.g., \dQuote{UTF-8}, \dQuote{ISO-8859-1}, etc. if \code{html} is not ASCII.} +\item{key}{A character string with the key from an Amazon user's access key who has permission to send email via Amazon SES.} + +\item{secret}{A character string with the secret from from an Amazon user's access key who has permission to send email via Amazon SES.} + +\item{region}{A character string giving the region of the user's Amazon SES service. Note that AWS SES is only available in regions us-east-1, us-west-2, or eu-west-1.} + +\item{force_credentials}{A logical set to \code{TRUE} or \code{FALSE}. Use \code{TRUE} only if you are providing the key, secret, and region parameters.} + \item{\dots}{Additional arguments passed to \code{\link{sesPOST}}.} } \value{ @@ -61,13 +71,13 @@ verify_identity("me@example.com") a <- get_verification_attrs("me@example.com") if (a[[1]]$VerificationStatus == "Success") { # simple plain-text email - send_email("Test Email Body", subject = "Test Email", + send_email("Test Email Body", subject = "Test Email", from = "me@example.com", to = "recipient@example.com") # html and plain text versions - send_email(message = "Plain text body", - html = "

HTML text body

", - subject = "Test Email", + send_email(message = "Plain text body", + html = "

HTML text body

", + subject = "Test Email", from = "me@example.com", to = "recipient@example.com") } } diff --git a/man/sesPOST.Rd b/man/sesPOST.Rd index 3a67f98..3fdd77b 100644 --- a/man/sesPOST.Rd +++ b/man/sesPOST.Rd @@ -7,7 +7,8 @@ sesPOST(query = list(), headers = list(), body = NULL, verbose = getOption("verbose", FALSE), region = Sys.getenv("AWS_DEFAULT_REGION", "us-east-1"), key = NULL, - secret = NULL, session_token = NULL, ...) + secret = NULL, session_token = NULL, force_credentials = FALSE, + ...) } \arguments{ \item{query}{A list containing query string parameters} @@ -26,6 +27,8 @@ sesPOST(query = list(), headers = list(), body = NULL, \item{session_token}{Optionally, a character string specifying an AWS temporary Session Token to use in signing a request. See \code{\link[aws.signature]{locate_credentials}}.} +\item{force_credentials}{A logical set to \code{TRUE} or \code{FALSE}. Use \code{TRUE} only if you are providing the key, secret, and region parameters.} + \item{\dots}{Additional arguments passed to \code{\link[httr]{POST}}.} } \description{