Webinar

November 3rd, 2021 12:00 PM EDT
Automation for Field Services & DistributionNovember 3rd, 2021 12:00 PM EDT
Learn how creating a digital workforce can improve your supply chain processes!

How to work with email using Gmail and RPA Framework

Sending email messages is one of the most common requirements when automating processes: it could be a report about the results of the process or maybe part of the automation itself, like emailing invoices as attachments.

The RPA Framework adds libraries that make handling email easy and convenient. This article will show you how to use the RPA.Email.ImapSmtp library to send email messages from a Gmail account.

The library is meant to work with any SMTP server, not just Gmail. It can also read and manage email messages in any email account accessible via IMAP.

Configuration of the Gmail account

If the Google account you use for sending has Two Factor Authentication enabled, you will need to set up an App password and use that password here (YOUR_GMAIL_PASSWORD).

Depending on the configuration of your Gmail account, or if your account is part of Google Suite, you might need to enable the "Less secure app access" setting.

Sending plain text email messages

Here is an example robot that sends a plain text message:

*** Settings ***
Documentation     Sending plain text email via Gmail.
Library           RPA.Email.ImapSmtp    smtp_server=smtp.gmail.com    smtp_port=587

*** Variables ***
${USERNAME}       YOUR_GMAIL_ACCOUNT
${PASSWORD}       YOUR_GMAIL_PASSWORD
${RECIPIENT}      [email protected]

*** Tasks ***
Send test email
    Authorize    account=${USERNAME}    password=${PASSWORD}
    Send Message    sender=${USERNAME}
    ...    recipients=${RECIPIENT}
    ...    subject=Message generated by robot
    ...    body=This is the body of the email.

  1. We are adding the RPA.Email.ImapSmtp library at the top in the *** Settings *** section, passing the server name for Gmail and the SMTP port to use as configuration. The port can be omitted when using the default value (in this case, 587). It is used here to display that it can be configured if needed.
  2. In the *** Variables *** section, we are setting the required variables: the Gmail account username and password, and the recipient of the email message.
  3. In the *** Tasks *** section we add a new task Send test email, where we call the Authorize keyword passing our credentials, and then the Send Message keyword, specifying the sender, recipient, subject and body of the message.

Note: It is not a good practice to write credentials in your robot code. We recommend to use Control Room vault to store your secrets securely.

Sending email messages with attachments

You can send files as attachments to a message.

To send a file called results.csv residing in the same directory where you run the robot, the code becomes:

*** Settings ***
Documentation     Sending email via Gmail with a file attachment.
Library           RPA.Email.ImapSmtp    smtp_server=smtp.gmail.com    smtp_port=587

*** Variables ***
${USERNAME}       YOUR_GMAIL_ACCOUNT_NAME
${PASSWORD}       YOUR_GMAIL_ACCOUNT_PASSWORD
${RECIPIENT}      RECIPIENT_OF_THE_EMAIL

*** Tasks ***
Send test email
    Authorize    account=${USERNAME}    password=${PASSWORD}
    Send Message    sender=${USERNAME}
    ...    recipients=${RECIPIENT}
    ...    subject=Message generated by robot
    ...    body=This is the body of the email.
    ...    attachments=results.csv

All we needed to do was adding the line ... attachments=results.csv to the Send Message keyword.

Sending an email with multiple attachments

If you want to send an email message with multiple attachments, you have to pass a list of file paths as the attachments arguments of the Send Message keyword instead of a simple string.

If you have two files results1.csv and results2.csv in the same directory where you run the robot, the example code becomes:

*** Settings ***
Documentation     Sending email via Gmail with multiple file attachments.
Library           RPA.Email.ImapSmtp    smtp_server=smtp.gmail.com    smtp_port=587

*** Variables ***
${USERNAME}       YOUR_GMAIL_ACCOUNT_NAME
${PASSWORD}       YOUR_GMAIL_ACCOUNT_PASSWORD
${RECIPIENT}      RECIPIENT_OF_THE_EMAIL
@{ATTACHMENTS}    results1.csv    results2.csv

*** Tasks ***
Send test email
    Authorize    account=${USERNAME}    password=${PASSWORD}
    Send Message    sender=${USERNAME}
    ...    recipients=${RECIPIENT}
    ...    subject=Message generated by robot
    ...    body=This is the body of the email.
    ...    [email protected]{ATTACHMENTS}
  1. We are adding the @{ATTACHMENTS} list variable, filling it with the paths of our two files.
  2. We are passing the variable containing the list as the attachments arguments of the Send Message keyword.

To create and manage lists inside your keywords, check out the Collections library, part of the Built-in libraries provided by Robot Framework.

Sending HTML email messages with inline images

You can send images in the body of the email message using HTML.

To embed an image file called image.png residing in the same directory where you run the robot, the code becomes:

*** Settings ***
Documentation     Sending email via Gmail with an inline image.
Library           RPA.Email.ImapSmtp    smtp_server=smtp.gmail.com    smtp_port=587

*** Variables ***
${USERNAME}       YOUR_GMAIL_ACCOUNT_NAME
${PASSWORD}       YOUR_GMAIL_ACCOUNT_PASSWORD
${RECIPIENT}      RECIPIENT_OF_THE_EMAIL

*** Tasks ***
Send test email
    Authorize    account=${USERNAME}    password=${PASSWORD}
    Send Message    sender=${USERNAME}
    ...    recipients=${RECIPIENT}
    ...    subject=Message generated by robot
    ...    html=True
    ...    images=image.png
    ...    body=<p>See this image: <img src='image.png' alt='approved image'/></p>

In this case, we need to modify the Send Message keyword:

  • adding html=True to tell the SMTP server that we are sending an email in HTML format
  • adding the names (and path) of the images that we will use in the email body using the images parameter (images=image.png)
  • now we can use the image in the body of the message, using HTML formatting: body=<p>See this image: <img src='image.png' alt='approved image'/></p>

This is how the generated message will look like in an email client:

Email with inline images

Sending multiple attachments and saving them

This robot sends multiple attachments, collects the messages by criterion (email subject) using the List Messages keyword, logs some information regarding each email, and saves the attachments using the Save Attachment keyword. It also uses a vault for the credentials.

*** Settings ***
Documentation     Sending email via Gmail with multiple file attachments,
...               and saving the attachments.
Library           RPA.Email.ImapSmtp
...               smtp_server=smtp.gmail.com
...               smtp_port=587
Library           RPA.Robocorp.Vault

*** Variables ***
${BODY}=          This is the body of the email.
${RECIPIENT}=     [email protected]
${SENDER}=        [email protected]
${SUBJECT}=       Message generated by robot
@{ATTACHMENTS}=
...               ${CURDIR}${/}devdata${/}attachment1.csv
...               ${CURDIR}${/}devdata${/}attachment2.csv

*** Keywords ***
Send Email With Attachments
    ${secret}=    Get Secret    emailCredentials
    Authorize    account=${secret}[username]    password=${secret}[password]
    Send Message
    ...    sender=${SENDER}
    ...    recipients=${RECIPIENT}
    ...    subject=${SUBJECT}
    ...    body=${BODY}
    ...    [email protected]{ATTACHMENTS}

*** Keywords ***
Get Messages Where Subject Contains
    [Arguments]    ${subject}
    @{emails}    List Messages    SUBJECT "${subject}"
    FOR    ${email}    IN    @{emails}
        Log    ${email}[Subject]
        Log    ${email}[From]
        Log    ${email}[Date]
        Log    ${email}[Received]
        Log    ${email}[Has-Attachments]
    END
    [Return]    @{emails}

*** Keywords ***
Download Attachments
    [Arguments]    @{emails}
    FOR    ${email}    IN    @{emails}
        IF    ${email}[Has-Attachments] == True
            Save Attachment
            ...    ${email}
            ...    target_folder=${CURDIR}${/}output
            ...    overwrite=True
        END
    END

*** Tasks ***
Send email with attachments, list messages, and download the attachments
    Send Email With Attachments
    @{emails}=    Get Messages Where Subject Contains    ${SUBJECT}
    Download Attachments    @{emails}

Listing email messages by criteria

The above example robot uses the List Messages keyword to list messages matching the given criteria. Learn more about the search syntax in the RFC 3501, IMAP4rev1 Protocol Specification.

IMAP search criteria examples and description

Criterion example (search key)Description
123Messages with message sequence numbers corresponding to the specified message sequence number set.
ALLAll messages in the mailbox; the default initial key for ANDing.
ANSWEREDMessages with the \Answered flag set.
BCC "Text"Messages that contain the specified string in the envelope structure's BCC field.
BEFORE 1-May-2021Messages whose internal date (disregarding time and timezone) is earlier than the specified date.
BODY "Text"Messages that contain the specified string in the body of the message.
CC "Text"Messages that contain the specified string in the envelope structure's CC field.
DELETEDMessages with the \Deleted flag set.
DRAFTMessages with the \Draft flag set.
FLAGGEDMessages with the \Flagged flag set.
FROM "Text"Messages that contain the specified string in the envelope structure's FROM field.
HEADER "Field" "Text"Messages that have a header with the specified field-name (as defined in RFC-2822) and that contains the specified string in the text of the header (what comes after the colon). If the string to search is zero-length, this matches all messages that have a header line with the specified field-name regardless of the contents. Example: HEADER Message-ID <[email protected]>
KEYWORD "Keyword"Messages with the specified keyword flag set.
LARGER 4Messages with an RFC-2822 size larger than the specified number of octets.
NEWMessages that have the \Recent flag set but not the \Seen flag. This is functionally equivalent to "(RECENT UNSEEN)".
NOT <search-key>Messages that do not match the specified search key. Example: NOT FROM "Smith"
OLDMessages that do not have the \Recent flag set. This is functionally equivalent to "NOT RECENT" (as opposed to "NOT NEW").
ON 1-May-2021Messages whose internal date (disregarding time and timezone) is within the specified date.
OR <search-key1> <search-key2>Messages that match either search key. Examples: OR FROM "Google" SUBJECT "Hello", OR DELETED (SEEN ANSWERED), OR (OR DELETED SEEN) ANSWERED
RECENTMessages that have the \Recent flag set.
SEENMessages that have the \Seen flag set.
SENTBEFORE 1-May-2021Messages whose RFC-2822 Date: header (disregarding time and timezone) is earlier than the specified date.
SENTON 1-May-2021Messages whose RFC-2822 Date: header (disregarding time and timezone) is within the specified date.
SENTSINCE 1-May-2021Messages whose RFC-2822 Date: header (disregarding time and timezone) is within or later than the specified date.
SINCE 1-May-2021Messages whose internal date (disregarding time and timezone) is within or later than the specified date.
SMALLER 4Messages with an RFC-2822 size smaller than the specified number of octets.
SUBJECT "Text"Messages that contain the specified string in the envelope structure's SUBJECT field.
TEXT "Text"Messages that contain the specified string in the header or body of the message.
TO "Text"Messages that contain the specified string in the envelope structure's TO field.
UID 2,4:7,9,12:*Messages with unique identifiers corresponding to the specified unique identifier set. Sequence set ranges are permitted. Example: a message sequence number set of 2,4:7,9,12:* for a mailbox with 15 messages is equivalent to 2,4,5,6,7,9,12,13,14,15
UNANSWEREDMessages that do not have the \Answered flag set.
UNDELETEDMessages that do not have the \Deleted flag set.
UNDRAFTMessages that do not have the \Draft flag set.
UNFLAGGEDMessages that do not have the \Flagged flag set.
UNKEYWORD "Keyword"Messages that do not have the specified keyword flag set.
UNSEENMessages that do not have the \Seen flag set.

Combining IMAP search criteria (ANDing)

There is no "AND" operator. Combine search keys by appending them right after each other:

FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"

Learn more about the libraries mentioned on this page:

October 11, 2021