Open quickbendelat opened 2 years ago
Have you tried sending the email as normal, but setting the From: address to the desired individual? I haven't got access to a business MS365 org right now, so can't test this.
I've tried it out, but no success.
Adding a "from" argument to either one of create_emaill()
and send()
both give the error:
"unused argument (from = ...)"
See if this helps: https://docs.microsoft.com/en-us/graph/outlook-create-send-messages#setting-the-from-and-sender-properties
You can update the properties of an (unsent) email object with the object$update()
method.
Also try asking on Stack Overflow, make sure to use the microsoft-graph-api
tag rather than anything R-specific.
I tried modifying the build_email_request
method, to add a "from" arguement:
build_email_request.blastula_message <- function(body, content_type,
subject=NULL, to=NA, cc=NA, bcc=NA, reply_to=NA, from=NA, token=NULL, user_id=NULL, ...)
{
req <- list(
body=list(
contentType="html", # blastula emails are always HTML
content=body$html_str
)
)
if(!is_empty(subject))
req$subject <- subject
utils::modifyList(req, build_email_recipients(to, cc, bcc, reply_to, from))
}
and the build_email_recipients()
function based on this link showing that "from" is a field for Microsoft Graph api:
https://docs.microsoft.com/en-us/graph/outlook-send-mail-from-other-user
build_email_recipients <- function(to, cc, bcc, reply_to, from)
{
make_recipients <- function(addr_list)
{
# NA means don't update current value
if(!is_empty(addr_list) && is.na(addr_list))
return(NA)
# handle case of a single az_user object
if(is.object(addr_list))
addr_list <- list(addr_list)
lapply(addr_list, function(x)
{
if(inherits(x, "az_user"))
{
props <- x$properties
x <- if(!is.null(props$mail))
props$mail
else props$userPrincipalName
if(is_empty(x) || nchar(x) == 0)
stop("Unable to find email address", call.=FALSE)
name <- props$displayName
}
else name <- x <- as.character(x)
if(!all(grepl(".+@.+", x))) # basic check for a valid address
stop("Invalid email address supplied", call.=FALSE)
list(emailAddress=list(name=name, address=x))
})
}
out <- list(
toRecipients=make_recipients(to),
ccRecipients=make_recipients(cc),
bccRecipients=make_recipients(bcc),
replyTo=make_recipients(reply_to)
)
out[sapply(out, function(x) is_empty(x) || !is.na(x))]
}
But it fails at the the second step in the code below inside the create_email()
function:
req <- build_email_request(body, content_type, subject, to, cc, bcc, reply_to, from)
res <- ms_outlook_email$new(self$token, self$tenant,
self$do_operation("messages", body=req, http_verb="POST"), user_id=self$user_id)
with the error:
Bad Request (HTTP 400). Failed to complete operation. Message:
Property from in payload has a value that does not match schema.
Based on your comment about looking at the object$update()
method and looking at this link where I am led to believe "sender" is a valid property:
https://docs.microsoft.com/en-us/graph/outlook-send-mail-from-other-user
I then changed tack and have now tried adding an extra method to the ms_outlook_email
R6 object:
set_sender=function(sender=NULL)
{
if(is_empty(sender))
message("Clearing sender")
sender <- build_email_sender(sender)
sender$sender <- self$properties$sender
do.call(self$update, sender)
},
which is a modified copy of the set_reply_to
method.
Also created a modified copy of build_email_recipients
:
build_email_sender <- function(sender)
{
make_recipients <- function(addr_list)
{
# NA means don't update current value
if(!is_empty(addr_list) && is.na(addr_list))
return(NA)
# handle case of a single az_user object
if(is.object(addr_list))
addr_list <- list(addr_list)
lapply(addr_list, function(x)
{
if(inherits(x, "az_user"))
{
props <- x$properties
x <- if(!is.null(props$mail))
props$mail
else props$userPrincipalName
if(is_empty(x) || nchar(x) == 0)
stop("Unable to find email address", call.=FALSE)
name <- props$displayName
}
else name <- x <- as.character(x)
if(!all(grepl(".+@.+", x))) # basic check for a valid address
stop("Invalid email address supplied", call.=FALSE)
list(emailAddress=list(name=name, address=x))
})
}
# browser()
out <- list(
sender=make_recipients(sender)
)
out[sapply(out, function(x) is_empty(x) || !is.na(x))]
}
My understanding is that this will build a list that can be passed through to the object in the Shared mailbox.
However, when I run eml$set_sender
, I receive the error:
Error in process_response(res, match.arg(http_status_handler), simplify) :
Bad Request (HTTP 400). Failed to complete operation. Message:
Empty Payload. JSON content expected.
Debugging build_email_sender()
, I get a valid output the same as build_email_recipients
Browse[2]> out
$sender
$sender[[1]]
$sender[[1]]$emailAddress
$sender[[1]]$emailAddress$name
[1] "blah@blah.com"
$sender[[1]]$emailAddress$address
[1] "blah@blah.com"
It would be great if someone with better knowledge than me could work on adding extra methods to set the "sender", as this would enhance the usability of this package.
KISS solution for anyone coming across this issue. Based on @hongooi73's tip to use the object$update()
method, the Microsoft Graph API JSON payload schema ( https://learn.microsoft.com/en-us/graph/outlook-send-mail-from-other-user#sending-with-microsoft-graph), and noting that the object$update()
's internals are:
function (...)
{
self$do_operation(body = list(...), encode = "json", http_verb = "PATCH")
self$properties <- self$do_operation()
self
}
You can write a nested list (to go into the ellipsis above) so the method will send a properly formatted payload to modify the draft email like this:
email$update(
from = list(
emailAddress = list(
address = "datateam@example.com")
)
)
Can I please follow up on this and ask if I can use the
email$update(
...
to add a different "reply to" address? (Just to make sure, I want to send an email on my behalf but with another address for which I have permission to do so. But I would like the recipient to hit reply and send the email to my own address. Is that possible?).
Thanks!
I have got my company's IT team to set up a Shared Mailbox. I can use
get_business_outlook()
, and then the methodscreate_email()
andsend
() successfully.Now, IT have created some other email addresses and have set them up as "Mail enabled security group" so that these can be used to send emails via the Shared Mailbox. However, I cannot find any documentation on how to send on behalf of the Shared Mailbox. I want the sender to be the individual email address and not the email address of the Shared Mailbox.
The use case is that there will be multiple Docker Containers running in Azure that will have their own email addresses. The architecture that has been defined is for all these to send via the one Shared Mailbox.