46

How can I send emails in R via Outlook?

All the examples of sendmailR use the gmail server, but I cannot do that.

bryn
  • 1,246
  • 1
  • 13
  • 21
user3022875
  • 8,598
  • 26
  • 103
  • 167
  • possible duplicate of [how to send email with attachment from R in windows](http://stackoverflow.com/questions/2885660/how-to-send-email-with-attachment-from-r-in-windows) – ARobertson Nov 08 '14 at 10:37
  • 1
    @ARobertson no this is not a duplicated. The Op looks for an outlook solution and mention in his question the sendmailR solution... – agstudy Nov 08 '14 at 12:56
  • Should probably add a 'vba' and/or 'outlook' tag. Might need a `system()`-call. – IRTFM Nov 08 '14 at 17:29

4 Answers4

96

You can use RDCOMClient package to access to COM objects from within R. You can easily access the Application Object (Outlook) and configure it. Here a simple example of sending an email:

library(RDCOMClient)
## init com api
OutApp <- COMCreate("Outlook.Application")
## create an email 
outMail = OutApp$CreateItem(0)
## configure  email parameter 
outMail[["To"]] = "dest@dest.com"
outMail[["subject"]] = "some subject"
outMail[["body"]] = "some body"
## send it                     
outMail$Send()

Of course, this assumes that you have already install outlook and configure it to send/receive your emails. Adding attachment is quite simple also:

outMail[["Attachments"]]$Add(path_to_attch_file)

sending on behalf of secondary mailbox:

outMail[["SentOnBehalfOfName"]] = "yoursecondary@mail.com"
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • - do you know how i can attach a file? – user3022875 Dec 11 '14 at 18:33
  • @user3022875 yes. You can see my edit. – agstudy Dec 11 '14 at 18:48
  • 11
    This is absolutely brilliant. And don't even need all of these smtp server nonsense which never works properly – David Arenburg May 26 '15 at 13:19
  • 2
    I'm geeting following error > outMail$Send() 80020009 No support for InterfaceSupportsErrorInfo checkErrorInfo -2147352567 Error: Exception occurred. Windows 8 and Outlook 2013 R 3.2 – Indranil Gayen Oct 16 '15 at 10:55
  • 1
    @IndranilGayen When does the error occur? I guess it has to do with the attachments. If that is the case the error probably is that you are giving a relative path. The $Add(path) command requires a full path on windows something like: "c:\\Files\\image.jpg" would work. – Rasmus Ø. Pedersen Jan 19 '16 at 12:34
  • 1
    Replacing the outMail[["body"]] part with: outMail[["HTMLBody"]] = paste0("

    Hello see my cool image:

    ") With only the file name (if it's an image), will put the image directly in the mail with the text. (Tested on Windows 8.1, Outlook 2010)
    – Rasmus Ø. Pedersen Jan 19 '16 at 12:37
  • Brilliant solution. I want to automate this, maybe set it up as a scheduler on a Windows Box - is it required for me to have Outlook open for this to work? – theMJof91 Feb 02 '16 at 20:18
  • Can you describe how i might use a secondary email account (in outlook) rather than my primary account? Something like this: https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-msoffice_custom/excel-vba-sending-email-with-outlook-2010-specify/4ae28948-0b01-4eb7-8f5f-10fbfa8f4df9 – RyanStochastic Dec 15 '16 at 04:25
  • Looks like this needs to click "Allow" button in Outlook to send email? – Deqing Aug 09 '17 at 02:50
  • @RasmusØ.Pedersen this will work IF the path has no spaces in it. If not it will display a box with a red x in it instead. – Nova Sep 20 '17 at 15:55
  • 13
    Does anyone have an updated solution for R 3.5.1? `Warning in install.packages :package ‘RDCOMClient’ is not available (for R version 3.5.1)` – P__2 Feb 07 '19 at 15:01
  • 2
    @P__2 Try with: install.packages('RDCOMClient', repos = 'http://www.omegahat.net/R/') – Repmat Dec 20 '19 at 12:15
  • 4
    @Repmat Thanks -I found a similar solution with devtools::install_github('omegahat/RDCOMClient') – Raj Padmanabhan Jan 16 '20 at 23:25
14

It is possible to send emails in R via Outlook. sendmailR works for me on Windows 7 and Outlook 2010. I referenced http://cran.es.r-project.org/web/packages/sendmailR/sendmailR.pdf

smtpServer= info for Outlook 2010 is in File -> Account Settings -> Account Settings -> double click your account -> text in "Server" box

library(sendmailR)

#set working directory
setwd("C:/workingdirectorypath")

#####send plain email

from <- "you@account.com"
to <- "recipient@account.com"
subject <- "Email Subject"
body <- "Email body."                     
mailControl=list(smtpServer="serverinfo")

sendmail(from=from,to=to,subject=subject,msg=body,control=mailControl)

#####send same email with attachment

#needs full path if not in working directory
attachmentPath <- "subfolder/log.txt"

#same as attachmentPath if using working directory
attachmentName <- "log.txt"

#key part for attachments, put the body and the mime_part in a list for msg
attachmentObject <- mime_part(x=attachmentPath,name=attachmentName)
bodyWithAttachment <- list(body,attachmentObject)

sendmail(from=from,to=to,subject=subject,msg=bodyWithAttachment,control=mailControl)

In addition, multiple files can be sent by adding another mime_part to the msg list as follows (I also condensed it):

attachmentObject <- mime_part(x="subfolder/log.txt",name="log.txt")
attachmentObject2 <- mime_part(x="subfolder/log2.txt",name="log2.txt")
bodyWithAttachment <- list(body,attachmentObject,attachmentObject2)
ARobertson
  • 2,857
  • 18
  • 24
10

You can also use vbscript to expose all the functionalities of Outlook

Reference: MailItem Members (Outlook) - MSDN - Microsoft

################################################
#Outlook Enumerations
################################################
#OlMailRecipientType Enumeration (Outlook)
OlMailRecipientType  <- c(olBCC=3, olCC=2, olOriginator=0, olTo=1)

#OlBodyFormat Enumeration (Outlook)
OlBodyFormat <- c(olFormatHTML=2, olFormatPlain=1, olFormatRichText=3, olFormatUnspecified=0)

#OlImportance Enumeration (Outlook)
OlImportance <- c(olImportanceHigh=2, olImportanceLow=0, olImportanceNormal=1)

#OlSensitivity Enumeration (Outlook)
OlSensitivity <- c(olConfidential=3, olNormal=0, olPersonal=1, olPrivate=2)

#OlDefaultFolders Enumeration (Outlook)
OlDefaultFolders <- c(olFolderCalendar=9, olFolderConflicts=19, olFolderContacts=10, olFolderDeletedItems=3,
     olFolderDrafts=16, olFolderInbox=6, olFolderJournal=11, olFolderJunk=23,
     olFolderLocalFailures=21, olFolderManagedEmail=29, olFolderNotes=12, olFolderOutbox=4,
     olFolderSentMail=5, olFolderServerFailures=22, olFolderSyncIssues=20,
     olFolderTasks=13, olFolderToDo=28, olPublicFoldersAllPublicFolders=18, olFolderRssFeeds=25)

################################################
#function to send email using Outlook
################################################
outlookSend <- function(To, Subject='', CC=NULL, BCC=NULL,
    HTMLBodyFile=NULL, HTMLBody=NULL, Body='', Attachments=NULL,
    DeferredDeliveryTime=NULL, OriginatorDeliveryReportRequested=NULL, ReadReceiptRequested=NULL,
    FlagRequest=NULL, Importance=NULL, Sensitivity=NULL,
    SentOnBehalfOfName=NULL)
{
    vbscript <- c('Dim objOutlook',
        'Dim objMailItem',
        'Dim objFileSystem',
        'Dim objNamespace',
        'Dim objSentFolder',

        'Set objOutlook = CreateObject("Outlook.Application")',
        'Set objMailItem = objOutlook.CreateItem(0)',

        'With objMailItem',
        paste0('\t.Subject = "', Subject, '"'),

        #Add recipients
        unlist(lapply(To, function(recip) c(
            paste0('\tSet recip = .Recipients.Add ("',recip,'")'),
            paste('\trecip.Type =',OlMailRecipientType['olTo'])))),

        if (!is.null(CC)) {
            unlist(lapply(CC, function(recip) c(
                paste0('\tSet recip = .Recipients.Add ("',recip,'")'),
                paste('\trecip.Type =',OlMailRecipientType['olCC']))))
        },
        if (!is.null(BCC)) {
            unlist(lapply(BCC, function(recip) c(
                paste0('\tSet recip = .Recipients.Add ("',recip,'")'),
                paste('\trecip.Type =',OlMailRecipientType['olBCC']))))
        },
        '\t.Recipients.ResolveAll',

        #Insert email body
        if (!is.null(HTMLBodyFile)) {
            c(paste('\t.BodyFormat =', OlBodyFormat['olFormatHTML']),
              '\tSet objFileSystem = CreateObject("Scripting.FileSystemObject")',
              paste0('\tSet file = objFileSystem.OpenTextFile("',HTMLBodyFile,'", 1)'),
              '\t.HTMLBody = file.ReadAll')

        } else if (!is.null(HTMLBody)) {
            c(paste('\t.BodyFormat =', OlBodyFormat['olFormatHTML']),
              paste0('\t.HTMLBody = "',HTMLBody,'"'))

        } else {
            c(paste('\t.BodyFormat =', OlBodyFormat['olFormatPlain']),
              paste0('\t.Body = "', Body, '"'))

        },

        #Add attachments
        if (!is.null(Attachments)) {
            vapply(Attachments, function(x) paste0('\t.Attachments.Add  "',x,'"'), character(1))
        },

        #copy of the mail message is saved down
        '\t.DeleteAfterSubmit = False',

        #Delay delivery in minutes
        if (!is.null(DeferredDeliveryTime)) {
            paste0('\t.DeferredDeliveryTime = dateadd("n", ',DeferredDeliveryTime,', Now)')
        },

        #Indicates the requested action for a mail item
        if (!is.null(FlagRequest)) {
            '\t.FlagRequest = "Follow up"'
        },

        #Indicates the relative importance level for the mail item
        if (!is.null(Importance)) {
            paste('\t.Importance =', OlImportance[Importance])
        },

        #OriginatorDeliveryReportRequested of type logical: whether to receive delivery report
        if (!is.null(OriginatorDeliveryReportRequested) && OriginatorDeliveryReportRequested) {
            '\t.OriginatorDeliveryReportRequested = True'
        },

        #ReadReceiptRequested of type logical: request read receipt
        if (!is.null(ReadReceiptRequested) && ReadReceiptRequested) {
            '\t.ReadReceiptRequested = True'
        },

        #Indicates the the display name for the intended sender of the mail message
        if (!is.null(SentOnBehalfOfName)) {
            paste('\t.SentOnBehalfOfName =', SentOnBehalfOfName)
        },

        #Indicates the sensitivity for the Outlook item
        if (!is.null(Sensitivity)) {
            paste('\t.Sensitivity =', OlSensitivity[Sensitivity])
        },

        'End With',
        'objMailItem.Send',
        'Set objFileSystem = Nothing',
        'Set objMailItem = Nothing',
        'Set objOutlook = Nothing')

    vbsfile <- tempfile('vbs',getwd(),'.vbs')
    write(vbscript, vbsfile)
    shell(paste('cscript /NOLOGO', vbsfile))
    unlink(vbsfile)
} #outlookSend


#Examples Usage:
outlookSend(To=c("XXX@mail.com","YYY@mail.com"),
    Subject="XXX", HTMLBodyFile='C:/Users/XXX/Documents/XXX.html',
    Attachments=c('C:/Users/XXX/Documents/XXX.html', 'C:/Users/XXX/Documents/XXX.txt'))

This solution will be useful when you are blocked from sending emails directly through the SMTP server.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
chinsoon12
  • 25,005
  • 4
  • 25
  • 35
3

Old question, but if somebudy wants to use mailR for this task have a look at Settings (in outlook) than click "E-Mail" (below "Your App Settings") and navigate to "POP and IMAP" .. you will find hostname and port for SMTP here.

Jack
  • 31
  • 1