Hi,
How do I process messages once I listed them? I am able to list messages with keyword from Email.ImapSmtp
library with list messages
. How do I extract text or better images?
I am in robot framework, not python.
Kind regards,
Markus
Hi,
How do I process messages once I listed them? I am able to list messages with keyword from Email.ImapSmtp
library with list messages
. How do I extract text or better images?
I am in robot framework, not python.
Kind regards,
Markus
Hi Markus, thanks for your question!
We’ll test this one, and get back to you.
Hi, @Markus!
It seems that the current implementation is a bit low-level, sorry about that!
This is not a complete example yet but gives some hints on how to loop through message contents, attachments, etc.
*** Settings ***
Documentation Example Robot listing messages from Gmail
Library RPA.Email.ImapSmtp smtp_server=smtp.gmail.com smtp_port=587 imap_server=imap.gmail.com
*** Variables ***
${USERNAME} xxx
${PASSWORD} yyy
*** Tasks ***
List messages
Authorize account=${USERNAME} password=${PASSWORD}
${folder_list}= Get Folder List
${number_of_inbox_messages}= Select Folder folder_name=INBOX
${messages}= List Messages criterion=SUBJECT "Message generated by robot"
${message}= Set Variable ${messages}[0]
FOR ${part} IN @{message.walk()}
Log ${part.get_payload()}
END
Content-Type: application/octet-stream MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename= test.txt SGVsbG8h
MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This is the body of the email.
The underlying email.message.Message
is probably this, if I am not totally mistaken:
https://docs.python.org/3/library/email.compat32-message.html
As you can see, it is quite low-level. There is an additional EmailMessage
class that supposedly makes reading messages easier (https://docs.python.org/3/library/email.message.html), but you kind of need to implement some Python code for that (or maybe there is a library for that somewhere already).
This is something we definitely want to improve in the future.
// Jani
Hej @jani,
Those were the right advises. Got myself a robot keyword parsing attachments of messages returned by RPA.Email.ImapSmtp.List Messages
Thank you!
Excellent, @Markus!
Would you feel comfortable sharing that parsing keyword you implemented? Would be interested to see how you did it.
Sure! I only need the binary of the payload.
from robot.api.deco import library, keyword
from robot.api import logger
from typing import List, Dict
from email.message import Message
import os
@library
class MailServiceLibrary:
@keyword(name="get attachments from message as binary")
def get_attachments_from_email(self, message: Message, attachment_suffix: str = '') -> Dict:
attachments = {}
# process message parts
for part in message.walk():
logger.debug(f'------ {part.get_content_type()}')
if part.get_content_type() == 'application/octet-stream':
filename = part.get_filename()
logger.debug(f'Found attachment:\t{filename}')
if not attachment_suffix or MailServiceLibrary._extension_does_match_specified_suffix(filename, suffix=attachment_suffix):
payload = part.get_payload(decode=True)
attachments[filename] = payload
else:
logger.info(f'No {attachment_suffix} file. Skip attachment:\t{filename}')
return attachments
@staticmethod
def _extension_does_match_specified_suffix(filename: str, suffix: str) -> bool:
_, file_extension= os.path.splitext(filename)
return suffix.lower() == file_extension[1:].lower()
i use criterion=SUBJECT “Message generated by robot” to search, but why result list include all of the email in inbox?
Hi, @nixuewei!
That is strange. I tested this now with rpaframework
2.4.0, and it works correctly for me. If I give a subject that does not match anything, no results. If the subject matches, I only get the matched results.
Can you share your robot (without credentials)?
It also depends on your Mailserver. I use Greenmail for testing which does not support all imap criteria (for example SUBJECT). Which Mailprovider do you use? Maybe it does not support SUBJECT and uses ALL as fallback.