Python API
ImapSmtp
- class RPA.Email.ImapSmtp.ImapSmtp(smtp_server: Optional[str] = None, smtp_port: int = 587, imap_server: Optional[str] = None, imap_port: int = 993, account: Optional[str] = None, password: Optional[str] = None, encoding: str = 'utf-8', provider: Union[OAuthProvider, str] = OAuthProvider.GOOGLE, tenant: Optional[str] = None)
ImapSmtp is a library for sending, reading, and deleting emails. ImapSmtp is interfacing with SMTP and IMAP protocols.
*About criteria argument*
Various keywords like
List Messages
andMove Messages
have keyword argument calledcriterion
which can be used to filter emails according to given criteria.Syntax needs to according to specification and more information about that can be read from https://robocorp.com/docs/development-guide/email/sending-emails-with-gmail-smtp#listing-email-messages-by-criteria
Troubleshooting
- Authentication error with GMail - “Application-specific password required”
- More secure apps (XOAUTH2 protocol) - Use the OAuth2 flow as in this Portal robot:
-
Make sure to specify a provider (and optionally a tenant) when importing the library and planning to use this flow.
Examples
Robot Framework
It is highly recommended to secure your passwords and take care that they are not stored in version control by mistake. See
RPA.Robocorp.Vault
to see how to store secrets in Robocorp Vault.When sending HTML content with IMG tags, the
src
filenames must match the base image name given with theimages
parameter.*** Settings *** Library RPA.Email.ImapSmtp smtp_server=smtp.gmail.com smtp_port=587 Task Setup Authorize account=${GMAIL_ACCOUNT} password=${GMAIL_PASSWORD} *** Variables *** ${GMAIL_ACCOUNT} ACCOUNT_NAME ${GMAIL_PASSWORD} APP_PASSWORD ${RECIPIENT_ADDRESS} RECIPIENT ${BODY_IMG1} ${IMAGEDIR}${/}approved.png ${BODY_IMG2} ${IMAGEDIR}${/}invoice.png ${EMAIL_BODY} <h1>Heading</h1><p>Status: <img src='approved.png' alt='approved image'/></p> ... <p>INVOICE: <img src='invoice.png' alt='invoice image'/></p> *** Tasks *** Sending email Send Message sender=${GMAIL_ACCOUNT} ... recipients=${RECIPIENT_ADDRESS} ... subject=Message from RPA Robot ... body=RPA Robot message body Sending HTML Email With Image [Documentation] Sending email with HTML content and attachment Send Message ... sender=${GMAIL_ACCOUNT} ... recipients=${RECIPIENT_ADDRESS} ... subject=HTML email with body images (2) plus one attachment ... body=${EMAIL_BODY} ... html=${TRUE} ... images=${BODY_IMG1}, ${BODY_IMG2} ... attachments=example.png
Python
from RPA.Email.ImapSmtp import ImapSmtp gmail_account = "ACCOUNT_NAME" gmail_password = "APP_PASSWORD" mail = ImapSmtp(smtp_server="smtp.gmail.com", smtp_port=587) mail.authorize(account=gmail_account, password=gmail_password) mail.send_message( sender=gmail_account, recipients="RECIPIENT", subject="Message from RPA Python", body="RPA Python message body", )
- ROBOT_LIBRARY_DOC_FORMAT = 'REST'
- ROBOT_LIBRARY_SCOPE = 'GLOBAL'
- TO_PROTECT = ['authorize', 'authorize_imap', 'authorize_smtp', 'set_credentials', 'generate_oauth_string', 'get_oauth_token', 'refresh_oauth_token']
- add_gmail_labels(labels, criterion, source_folder: str = None) bool
Add GMail labels to messages matching criterion and if given, source folder
- Parameters
labels – comma separated list of labels to add
criterion – label messages matching criterion
source_folder – look for messages in this folder, default all folders
- Returns
status of the operation
Example:
Add Gmail Labels customer1 SUBJECT "order confirmation" Add Gmail Labels wip SUBJECT "order confirmation" customerfolder
- authorize(account: Optional[str] = None, password: Optional[str] = None, smtp_server: Optional[str] = None, imap_server: Optional[str] = None, smtp_port: Optional[int] = None, imap_port: Optional[int] = None, is_oauth: bool = False) None
Authorize user to SMTP and IMAP servers.
- Parameters
account – user account as string, defaults to None
password – user password as string, defaults to None
smtp_server – SMTP server address, defaults to None
imap_server – IMAP server address, defaults to None
smtp_port – SMTP server port, defaults to None (587 for SMTP)
imap_port – IMAP server port, defaults to None
is_oauth – Use XOAUTH2 protocol with a base64 encoded OAuth2 string as password
Will use separately set credentials or those given in keyword call.
Example:
Authorize ${username} ${password} smtp_server=smtp.gmail.com smtp_port=587
- authorize_imap(account: Optional[str] = None, password: Optional[str] = None, imap_server: Optional[str] = None, imap_port: Optional[int] = None, is_oauth: bool = False) None
Authorize to IMAP server.
- Parameters
account – IMAP account name, defaults to None
password – IMAP account password, defaults to None
imap_server – IMAP server address, defaults to None
imap_port – IMAP server port, defaults to None
is_oauth – Use XOAUTH2 protocol with a base64 encoded OAuth2 string as password
Can be called without giving any parameters if library has been initialized with necessary information and/or keyword
Set Credentials
has been called.Example:
Authorize IMAP ${username} ${password} imap.gmail.com 993
- authorize_smtp(account: Optional[str] = None, password: Optional[str] = None, smtp_server: Optional[str] = None, smtp_port: Optional[int] = None, is_oauth: bool = False) None
Authorize to SMTP server.
- Parameters
account – SMTP account name, defaults to None
password – SMTP account password, defaults to None
smtp_server – SMTP server address, defaults to None
smtp_port – SMTP server port, defaults to None (587 for SMTP)
is_oauth – Use XOAUTH2 protocol with a base64 encoded OAuth2 string as password
Can be called without giving any parameters if library has been initialized with necessary information and/or keyword
Set Credentials
has been called.Example:
Authorize SMTP ${username} ${password} smtp.gmail.com 587
- convert_eml_file_into_message(eml_filepath: str, save_attachments_directory: Optional[str] = None)
Converts EML file into message dictionary.
Returned dictionary contains:
headers of the email
attachments the filenames of the attachments or if attachments have been saved then they are absolute filepaths to each attachment
body_text is the TEXT formatted content of the email body
body_html is the HTML formatted content of the email body
- Parameters
eml_filepath – filepath to the EML file
save_attachments_directory – path to the directory where possible attachments will be saved to, if not given then attachment filenames are returned in a list of the return dictionary in the key ‘attachments’
- Returns
dictionary containing information aboutthe EML message
- create_folder(folder_name: str = None) bool
Create email folder
- Parameters
folder_name – name for the new folder
- Returns
True if operation was successful, False if not
Example:
Create Folder filtered
- delete_folder(folder_name: str = None) bool
Delete email folder
- Parameters
folder_name – current folder name
- Returns
True if operation was successful, False if not
Example:
Delete Folder filtered
- delete_message(criterion: Union[str, dict] = None, source_folder: str = None) bool
Delete single message from server based on criterion.
- Parameters
criterion – filter messages based on this search, can also be a message dictionary
source_folder – defaults to already selected folder, but can be set to delete message in a specific folder
- Returns
True if success, False if not
If criterion does not return exactly 1 message then delete is not done.
Example:
Delete Message SUBJECT "Greetings RPA developer"
- delete_messages(criterion: Union[str, list] = None, limit: int = None, source_folder: str = None) bool
Delete messages from server based on criterion.
- Parameters
criterion – filter messages based on this search, can also be a list of message dictionaries
limit – maximum number of message to delete
source_folder – defaults to already selected folder, but can be set to delete message in a specific folder
- Returns
True if success, False if not
Example:
Delete Messages SUBJECT Greetings
- do_message_actions(criterion: str = '', actions: list = None, source_folder: str = None, target_folder: str = None, labels: str = None, limit: int = None, overwrite: bool = False, prefix: str = None) Any
Do actions to messages matching criterion and if given, source folder
Actions can be:
msg_copy
msg_delete
msg_flag
msg_unflag
msg_read
msg_unread
msg_save
msg_attachment_save
glabel_add
glabel_remove
Result object contains following attributes:
actions_done, number of messages on which action was performed
message_count, number of messages matching criterion
ids, message ids matching criterion
uids, dictionary of message uids and message content
- Parameters
criterion – perform actions on messages matching this
actions – list of actions to perform on matching messages
source_folder – look for messages in this folder, default all folders
target_folder – can be file path or email folder (for example action: msg_copy)
labels – comma separated list of labels (for example action: glabel_add)
limit – maximum number of messages (for example action: msg_delete)
overwrite – to control if file should overwrite (for example action: msg_attachment_save)
prefix – prefix to be added into filename (for example: msg_save)
- Returns
result object
Example:
${actions}= Create List msg_unflag msg_read msg_save msg_attachment_save Do Message Actions SUBJECT "Order confirmation" ... ${actions} ... source_folder=XXX ... target_folder=${CURDIR} ... overwrite=True
- email_to_document(input_source: Union[str, Path, BinaryIO, bytes], output_path: Union[str, Path])
Convert a raw e-mail into a Word document.
This keyword extracts the HTML (or Text) content from the passed input e-mail and saves it into docx format at the provided output path.
- Parameters
input_source – Path, bytes or file-like object with the input raw e-mail content
output_path – Where to save the output docx file
Example:
Robot Framework
Convert email to docx ${mail_file} = Get Work Item File mail.eml Email To Document ${mail_file} ${OUTPUT_DIR}${/}mail.docx
Python
from pathlib import Path from RPA.Email.ImapSmtp import ImapSmtp from RPA.Robocorp.WorkItems import WorkItems lib_work = WorkItems() lib_mail = ImapSmtp() def convert_email_to_docx(): lib_work.get_input_work_item() mail_file = lib_work.get_work_item_file("mail.eml") lib_mail.email_to_document(mail_file, Path("./output") / "mail.docx")
- flag_messages(criterion: Union[str, dict] = None, unflag: bool = False) Any
Mark messages as flagged
- Parameters
criterion – mark messages matching criterion
unflag – to mark messages as not flagged
- Returns
successful operations (int), matching messages (int)
Example:
${flagged} ${oftotal} Flag Messages SUBJECT rpa ${unflagged} ${oftotal} Flag Messages SUBJECT rpa unflag=True
- generate_oauth_string(username: str, access_token: str) str
Generate and return an OAuth2 string compatible with the IMAP/POP/SMTP XOAUTH2 protocol.
This string usually gets passed to the
Authorize
keyword as password when is_oauth=${True}.- Parameters
username – The e-mail address you’re going to send the e-mail with.
access_token – Access token string found in the dictionary obtained with
Get OAuth Token
orRefresh OAuth Token
.
- Returns
Base64 encoded string packing these credentials and replacing the legacy password when enabling the OAuth2 flow.
Example: Robot Framework
*** Tasks *** Authorize ImapSmtp ${password} = Generate OAuth String ${username} ... ${token}[access_token] Authorize account=${username} is_oauth=${True} ... password=${password}
- generate_oauth_url(client_id: str) str
Generates an authorization URL which must be opened by the user to start the OAuth2 flow and obtain an authorization code as response.
- Parameters
client_id – Client app ID. (generated by the provider)
- Returns
Authorization URL string not containing any sensitive info in it.
Example: Robot Framework
*** Tasks *** Start OAuth Flow ${auth_url} = Generate OAuth URL ... client_id=810482312368-19htmcgcj*******googleusercontent.com Log Start OAuth2 flow: ${auth_url}
- get_decoded_email_body(message, html_first: bool = False) Tuple[str, bool]
Decodes email body and extracts its text/html content.
Automatically detects character set if the header is not set.
- Parameters
message – Raw 7-bit message body input e.g. from imaplib. Double encoded in quoted-printable and latin-1
html_first – Prioritize html extraction over text when this is True
- Returns
Message body as unicode string and a boolean telling if the message has attachments
- get_folder_list(subdirectory: str = None, pattern: str = None) list
Get list of folders on the server
- Parameters
subdirectory – list subdirectories for this folder
pattern – list folders matching this pattern
- Returns
list of folders
Example:
@{folders} Get Folder List @{folders} Get Folder List pattern=important @{folders} Get Folder List subdirectory=sub
- get_oauth_token(client_secret: str, response_url: str) dict
Exchanges the code obtained previously with
Generate OAuth URL
for a token.- Parameters
client_secret – Client app secret. (generated by the provider)
response_url – The final URL containing the authorization code found in the address bar after authenticating and authorizing the Client app through the authorization URL.
- Returns
A dictionary containing the access & refresh token, plus metadata.
Example: Robot Framework
*** Tasks *** Finish OAuth Flow ${token} = Get OAuth Token ... client_secret=GOCSPX-******mqZAW89 ... response_url=${resp_url} # redirect of `Generate OAuth URL`
- list_messages(criterion: str = '', source_folder: str = None, readonly: bool = True) Any
Return list of messages matching criterion.
- Parameters
criterion – list emails matching this, defaults to “”
source_folder – list messages from this folder
readonly – set False if you want to mark matching messages as read
- Returns
list of messages
Note. listing messages without source_folder might take a long time
Example:
@{emails} List Messages SUBJECT "rpa task" FOR ${email} IN @{EMAILS} Log ${email}[Subject] Log ${email}[From] Log ${email}[Date] Log ${email}[Delivered-To] Log ${email}[Received] Log ${email}[Has-Attachments] Log ${email}[uid] END
- mark_as_read(criterion: Union[str, dict] = None, unread: bool = False) Any
Mark messages as read
- Parameters
criterion – mark messages matching criterion
unread – to mark messages as not read
- Returns
successful operations (int), matching messages (int)
Example:
${read} ${oftotal} Mark As Read SUBJECT rpa
- mark_as_unread(criterion: Union[str, dict] = None) Any
Mark messages as not read
- Parameters
criterion – mark messages matching criterion
- Returns
successful operations (int), matching messages (int)
Example:
${unread} ${oftotal} Mark As Unread SUBJECT rpa
- move_messages(criterion: Union[str, dict] = None, target_folder: str = None, source_folder: str = None) bool
Move messages from source folder to target folder
- Parameters
criterion – move messages matching criterion
source_folder – location of the messages, default INBOX
target_folder – where messages should be move into
- Returns
True if all move operations succeeded, False if not
Example:
${result}= Move Messages ... criterion=SUBJECT "order confirmation 32" ... target_folder=yyy ${result}= Move Messages ... criterion=ALL ... source_folder=yyy ... target_folder=XXX
- move_messages_by_ids(message_ids: Union[str, List], target_folder: str, source_folder: str, use_gmail_search: bool = False) bool
Move message by their Message-ID’s from source folder to target folder
- Parameters
message_ids – one Message-ID as string or list of Message-IDs
source_folder – location of the messages, default INBOX
target_folder – where messages should be move into
use_gmail_search – set to True to use Rfc822msgid search, default is HEADER Message-ID search
- Returns
True if all move operations succeeded, False if not
- refresh_oauth_token(client_id: str, client_secret: str, token: dict) dict
Refreshes the token as the access one usually expires after 1h and the refresh one never expires. (as long as it doesn’t get revoked)
- Parameters
client_id – Client app ID. (generated by the provider)
client_secret – Client app secret. (generated by the provider)
token – Full token dictionary previously obtained with
Get OAuth Token
.
- Returns
A token dictionary containing a new access token and updated metadata.
Example: Robot Framework
*** Tasks *** Refresh OAuth Flow ${token} = Refresh OAuth Token ... client_id=810482312368-19htmcgcj*******googleusercontent.com ... client_secret=GOCSPX-******mqZAW89 ... token=${token} # from `Get OAuth Token`
- remove_gmail_labels(labels, criterion, source_folder: str = None) bool
Remove GMail labels to messages matching criterion and if given, source folder
- Parameters
labels – comma separated list of labels to remove
criterion – unlabel messages matching criterion
source_folder – look for messages in this folder, default all folders
- Returns
status of the operation
Example:
Remove Gmail Labels wip SUBJECT "order confirmation" Remove Gmail Labels wip SUBJECT "order confirmation" customerfolder
- rename_folder(oldname: str = None, newname: str = None, suppress_error: bool = False) bool
Rename email folder
- Parameters
oldname – current folder name
newname – new name for the folder
suppress_error – to silence warning message, defaults to False
- Returns
True if operation was successful, False if not
Example:
Rename Folder subfolder filtered
- save_attachment(message: Union[dict, Message], target_folder: Optional[str], overwrite: bool, prefix: Optional[str] = None) List[str]
Save mail attachment of a single given email on the local disk.
- Parameters
message – message item
target_folder – local folder for saving attachments to (needs to exist), defaults to user’s home directory if None
overwrite – overwrite existing file if True, defaults to False
prefix – optional filename prefix added to the attachments, empty by default
- Returns
list of saved attachments (list of absolute filepaths) in one email
Example:
@{emails} = List Messages ALL FOR ${email} IN @{emails} IF ${email}[Has-Attachments] Log To Console Saving attachment for: ${email}[Subject] ${attachments} = Save Attachment ... ${email} ... target_folder=${CURDIR} ... overwrite=${True} Log To Console Saved attachments: ${attachments} END END
- save_attachments(criterion: str = '', target_folder: Optional[str] = None, overwrite: bool = False, prefix: Optional[str] = None) List[str]
Save mail attachments of emails matching criterion on the local disk.
- Parameters
criterion – attachments are saved for mails matching this, defaults to “”
target_folder – local folder for saving attachments to (needs to exist), defaults to user’s home directory if None
overwrite – overwrite existing file if True, defaults to False
prefix – optional filename prefix added to the attachments, empty by default
- Returns
list of saved attachments (absolute file paths) of all emails
Example:
${attachments} = Save Attachments SUBJECT "rpa task" ... target_folder=${CURDIR}${/}messages overwrite=${True} FOR ${file} IN @{attachments} OperatingSystem.File Should Exist ${file} END
- save_messages(criterion: Optional[Union[str, dict, list]] = None, target_folder: Optional[str] = None, prefix: Optional[str] = None) bool
Save messages based on criteria and store them to target folder with attachment files.
Does not save message if target_folder is not given.
- Parameters
criterion – filter messages based on this, defaults to “”
target_folder – path to folder where message are saved, defaults to None
prefix – optional filename prefix added to the attachments, empty by default
- Returns
True if succeeded, False otherwise
Example:
Save Messages SUBJECT Important message target_folder=${USERDIR}${/}messages
- select_folder(folder_name: str = 'INBOX', readonly: bool = False) int
Select folder by name
- Parameters
folder_name – name of the folder to select
readonly – if set to True then message flags are not modified
- Returns
message count in the selected folder
Returns number of messages in the folder or exception if folder does not exist on the server.
Example:
Select Folder subfolder
- send_message(sender: str, recipients: Optional[Union[List[str], str]] = None, subject: str = '', body: str = '', attachments: Optional[Union[List[str], str]] = None, html: bool = False, images: Optional[Union[List[str], str]] = None, cc: Optional[Union[List[str], str]] = None, bcc: Optional[Union[List[str], str]] = None, attachment_position: Optional[AttachmentPosition] = AttachmentPosition.TOP, in_reply_to: Optional[str] = None, return_path: Optional[str] = None, reply_to: Optional[str] = None) bool
Send SMTP email
- Parameters
sender – who is sending, ie. ‘from’
recipients – who is receiving, ie. ‘to’
subject – mail subject field
body – mail body content
attachments – list of filepaths to attach
html – if message content is in HTML, default False
images – list of filepaths for inline images
cc – list of email addresses for email ‘cc’ field
bcc – list of email addresses for email ‘bcc’ field
attachment_position – content position for attachment, default top
in_reply_to – the ‘Message ID’ to which this message is in reply to, for example <message_id_for_reply_to>
return_path – email address which should receive “bounce messages”
reply_to – email address which should receive the reply
Valid sender values
First Lastname <address@domain>
About in_reply_to
In addition of setting in_reply_to parameter to match the ‘Message ID’ of the email this message is replying to, some email servers require that also subject of the original email is included in the reply email subject with `re: ` prefix, ie. “re: Why it is best to use Robocorp RPA” or with the original email subject.
And please note that in_reply_to the ‘Message ID’ needs to contain < in the start of the ID and > at the end of the ID.
About return_path
Email servers tend to set ‘Return-Path’ of the email on their own so in some cases user given address won’t work as the email server does not use the user set address. If possible, the email server’s configuration can be changed to ensure that ‘Return-Path’ header is respected.
Example:
Send Message sender@domain.com recipient@domain.com ... cc=need_to_know@domain.com ... bcc=hidden_copy@domain.com ... subject=Greetings Software Robot Developer ... body=${email_body} ... attachments=${CURDIR}${/}report.pdf # Fixing attachments to the bottom of the content Send Message sender@domain.com recipient@domain.com ... subject=Greetings Software Robot Developer ... body=${email_body} ... attachments=${CURDIR}${/}report.pdf ... attachment_position=bottom
- send_smtp_hello() None
Send hello message to SMTP server.
Required step when creating SMTP connection.
- set_credentials(account: Optional[str] = None, password: Optional[str] = None) None
Set credentials
- Parameters
account – user account as string, defaults to None
password – user password as string, defaults to None
Example:
Set Credentials ${username} ${password} Authorize
- unflag_messages(criterion: Union[str, dict] = None) Any
Mark messages as not flagged
- Parameters
criterion – mark messages matching criterion
- Returns
successful operations (int), matching messages (int)
Example:
${unflagged} ${oftotal} Unflag Messages SUBJECT rpa
- wait_for_message(criterion: str = '', timeout: float = 5.0, interval: float = 1.0, readonly: bool = True) Any
Wait for email matching criterion to arrive into mailbox.
- Parameters
criterion – message filter to wait for, defaults to “”
timeout – total time in seconds to wait for email, defaults to 5.0
interval – time in seconds for new check, defaults to 1.0
readonly – set False if you want to mark matching messages as read
- Returns
list of messages
Example:
@{emails} Wait For Message SUBJECT "rpa task" timeout=300 interval=10