mail
#
Description#
Plugin to:
Monitor one or more mailboxes, and emit events when new messages are received, seen, flagged or unflagged.
Send mail messages.
Search for messages in a mailbox.
Example accounts configuration:
mail: # Display name to be used for outgoing emails. Default: # the `from` parameter will be used from `MailPlugin.send <https://docs.platypush.tech/platypush/plugins/mail.html#platypush.plugins.mail.MailPlugin.send>`_, # and, if missing, the username from the account configuration # will be used. display_name: My Name # How often we should poll for updates (default: 60 seconds) poll_interval: 60 # Connection timeout (default: 20 seconds) # Can be overridden on a per-account basis timeout: 20 # Domain to be used for outgoing emails. Default: inferred # from the account configuration domain: example.com accounts: - name: "My Local Account" username: me@mydomain.com password: my-password # The default flag sets this account as the default one # for mail retrieval and sending if no account is # specified on an action. If multiple accounts are set # and none is set as default, and no account is specified # on an action, then the first configured account will be # used. default: true # Alternatively, you can run an external command # to get the password # password_cmd: "pass show mail/example.com" # Path to a custom certfile if the mail server uses a # self-signed certificate # certfile: /path/to/certfile # Path to a custom keyfile if the mail server requires # client authentication. It requires certfile to be set # too # keyfile: /path/to/keyfile incoming: # Supported protocols: imap, imaps server: imaps://mail.example.com:993 outgoing: # The `incoming` and `outgoing` configurations can # override the global `username` and `password` and # other authentication parameters of the account username: me password: my-smtp-password # Supported protocols: smtp, smtps, smtp+starttls, server: smtps://mail.example.com:465 # These folders will be monitored for new messages monitor_folders: - All Mail - name: "GMail" username: me@gmail.com # Access token, if the mail server supports OAuth2 # access_token: my-access-token # OAuth mechanism, if the mail server supports OAuth2 # (default: XOAUTH2) # oauth_mechanism: XOAUTH2 # OAuth vendor, if the mail server supports OAuth2 # oauth_vendor: GOOGLE incoming: # Defaults to port 993 for IMAPS if no port is # specified on the URL server: imaps://imap.gmail.com outgoing: # Defaults to port 465 for SMTPS if no port is # specified on the URL server: smtps://smtp.gmail.com monitor_folders: - INBOX - Sent
Configuration#
mail:
# [Required]
# List of available mailboxes/accounts.
accounts: # type=List[Dict[str, Any]]
# [Optional]
# Timeout for the mail server connection (default: 20
# seconds).
# timeout: 20.0 # type=float
# [Optional]
# How often the plugin should poll for new messages
# (default: 60 seconds).
# poll_interval: 60.0 # type=float
# [Optional]
# How long we should wait for any running
# threads/processes to stop before exiting (default: 5 seconds).
# stop_timeout: 5 # type=Optional[float]
# [Optional]
# If set to True then the plugin will not monitor
# for new events. This is useful if you want to run a plugin in
# stateless mode and only leverage its actions, without triggering any
# events. Defaults to False.
# disable_monitor: False # type=bool
Dependencies#
pip
pip install dnspython imapclient
Alpine
apk add py3-dnspython
Debian
apt install python3-dnspython
Fedora
yum install python-dnspython
Arch Linux
pacman -S python-dnspython
Triggered events#
Actions#
Module reference#
- class platypush.plugins.mail.MailPlugin(accounts: List[Dict[str, Any]], timeout: float = 20.0, poll_interval: float = 60.0, **kwargs)[source]#
Bases:
RunnablePlugin
Plugin to:
Monitor one or more mailboxes, and emit events when new messages are received, seen, flagged or unflagged.
Send mail messages.
Search for messages in a mailbox.
- __init__(accounts: List[Dict[str, Any]], timeout: float = 20.0, poll_interval: float = 60.0, **kwargs)[source]#
Example accounts configuration:
mail: # Display name to be used for outgoing emails. Default: # the `from` parameter will be used from :meth:`.send`, # and, if missing, the username from the account configuration # will be used. display_name: My Name # How often we should poll for updates (default: 60 seconds) poll_interval: 60 # Connection timeout (default: 20 seconds) # Can be overridden on a per-account basis timeout: 20 # Domain to be used for outgoing emails. Default: inferred # from the account configuration domain: example.com accounts: - name: "My Local Account" username: me@mydomain.com password: my-password # The default flag sets this account as the default one # for mail retrieval and sending if no account is # specified on an action. If multiple accounts are set # and none is set as default, and no account is specified # on an action, then the first configured account will be # used. default: true # Alternatively, you can run an external command # to get the password # password_cmd: "pass show mail/example.com" # Path to a custom certfile if the mail server uses a # self-signed certificate # certfile: /path/to/certfile # Path to a custom keyfile if the mail server requires # client authentication. It requires certfile to be set # too # keyfile: /path/to/keyfile incoming: # Supported protocols: imap, imaps server: imaps://mail.example.com:993 outgoing: # The `incoming` and `outgoing` configurations can # override the global `username` and `password` and # other authentication parameters of the account username: me password: my-smtp-password # Supported protocols: smtp, smtps, smtp+starttls, server: smtps://mail.example.com:465 # These folders will be monitored for new messages monitor_folders: - All Mail - name: "GMail" username: me@gmail.com # Access token, if the mail server supports OAuth2 # access_token: my-access-token # OAuth mechanism, if the mail server supports OAuth2 # (default: XOAUTH2) # oauth_mechanism: XOAUTH2 # OAuth vendor, if the mail server supports OAuth2 # oauth_vendor: GOOGLE incoming: # Defaults to port 993 for IMAPS if no port is # specified on the URL server: imaps://imap.gmail.com outgoing: # Defaults to port 465 for SMTPS if no port is # specified on the URL server: smtps://smtp.gmail.com monitor_folders: - INBOX - Sent
- Parameters:
accounts – List of available mailboxes/accounts.
poll_interval – How often the plugin should poll for new messages (default: 60 seconds).
timeout – Timeout for the mail server connection (default: 20 seconds).
- add_flags(messages: List[int], flags: str | List[str], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Add a set of flags to the specified set of message IDs.
- Parameters:
messages – List of message IDs.
flags –
List of flags to be added. Examples:
['Flagged'] ['Seen', 'Deleted'] ['Junk']
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- copy_messages(messages: List[int], destination: str, source: str = 'INBOX', account: str | int | Account | None = None)[source]#
Copy a set of messages IDs from a folder to another.
- Parameters:
messages – List of message IDs.
source – Source folder.
destination – Destination folder.
account – Account name or index (default: default account).
- create_folder(folder: str, account: str | int | Account | None = None)[source]#
Create a folder on the server.
- Parameters:
folder – Folder name.
account – Account name or index (default: default account).
- delete_folder(folder: str, account: str | int | Account | None = None)[source]#
Delete a folder from the server.
- Parameters:
folder – Folder name.
account – Account name or index (default: default account).
- delete_messages(messages: List[int], folder: str = 'INBOX', expunge: bool = True, account: str | int | Account | None = None)[source]#
Set a specified set of message IDs as deleted.
- Parameters:
messages – List of message IDs.
folder – IMAP folder (default:
INBOX
).expunge – If set then the messages will also be expunged from the folder, otherwise they will only be marked as deleted (default:
True
).account – Account name or index (default: default account).
- expunge_messages(messages: List[int], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
When
messages
is not set, remove all the messages fromfolder
marked asDeleted
.- Parameters:
folder – IMAP folder (default:
INBOX
).messages – List of message IDs to expunge (default: all those marked as
Deleted
).account – Account name or index (default: default account).
- flag_message(message: int, folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Add a flag/star to the specified set of message ID.
- Parameters:
message – Message ID.
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- flag_messages(messages: List[int], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Add a flag/star to the specified set of message IDs.
- Parameters:
messages – List of message IDs.
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- get_folders(folder: str = '', pattern: str = '*', account: str | int | Account | None = None) List[Dict[str, str]] [source]#
Get the list of all the folders hosted on the server or those matching a pattern.
- Parameters:
folder – Base folder (default: root).
pattern – Pattern to search (default: None).
account – Account name or index (default: default account).
- Returns:
Example:
[ { "name": "INBOX", "flags": "\\Noinferiors", "delimiter": "/" }, { "name": "Archive", "flags": "\\Noinferiors", "delimiter": "/" }, { "name": "Spam", "flags": "\\Noinferiors", "delimiter": "/" } ]
- get_message(id: int, folder: str = 'INBOX', account: str | int | Account | None = None, with_body: bool = True) Mail [source]#
Get the full content of a message given the ID returned by
search()
.- Parameters:
id – Message ID.
folder – Folder name (default:
INBOX
).account – Account name or index (default: default account).
with_body – If set then the body/payload will be included in the response (default:
True
).
- Returns:
A message in the same format as
search()
, with an addedpayload
attribute containing the body/payload. Example response:{ "id": 123, "date": "2024-01-13T21:04:50", "size": 3833, "from": { "you@example.com": { "name": "Me", "route": null, "email": "you@example.com" } }, "to": { "me@example.com": { "name": "Me", "route": null, "email": "me@example.com" } }, "cc": { "they@example.com": { "name": "They", "route": null, "email": "they@example.com" } }, "bcc": { "boss@example.com": { "name": "Boss", "route": null, "email": "boss@example.com" } }, "subject": "Test email", "content": { "headers": { "Return-Path": "<you@example.com>", "Delivered-To": "me@example.com", "Date": "Sat, 13 Jan 2024 20:04:50 +0000", "To": "Me <me@example.com>", "Cc": "They <they@example.com>", "Bcc": "Boss <boss@example.com", "From": "You <you@example.com>", "Subject": "Test email", "Message-ID": "<0123456789@client>", "MIME-Version": "1.0", "Content-Type": "multipart/mixed;\r\n boundary=\"0123456789\"" }, "body": "This is the email body", "attachments": [ { "filename": "signature.asc", "headers": { "Content-Type": "application/pgp-signature; name=signature.asc", "Content-Transfer-Encoding": "base64", "Content-Disposition": "attachment; filename=signature.asc" }, "body": "-----BEGIN PGP SIGNATURE-----\r\n\r\n....\r\n\r\n-----END PGP SIGNATURE-----\r\n" }, { "filename": "image.jpg", "body": "/9j/4gIcSUNDX1BST0ZJTEUAA...", "headers": { "Content-Type": "image/jpeg; Name=\"image.jpg\"", "MIME-Version": "1.0", "Content-Transfer-Encoding": "base64", "Content-Disposition": "attachment; filename=\"profile_pic.jpg\"" } } ] }, "seq": 123, "internal_date": "2024-01-13T21:05:12", "message_id": "<0123456789@client>", "reply_to": { "you@example.com": { "name": "You", "route": null, "email": "you@example.com" } }, "sender": { "you@example.com": { "name": "You", "route": null, "email": "you@example.com" } } }
- get_messages(ids: Collection[int], folder: str = 'INBOX', account: str | int | Account | None = None, with_body: bool = True) Dict[int, Mail] [source]#
Get the full content of a list of messages given their IDs returned by
search()
.- Parameters:
ids – IDs of the messages to retrieve.
folder – Folder name (default:
INBOX
).account – Account name or index (default: default account).
with_body – If set then the body/payload will be included in the response (default:
True
).
- Returns:
A dictionary in the format
{id -> msg}
, wheremsg
is in the same format assearch()
, with an addedpayload
attribute containing the body/payload. Seeget_message()
for an example message format.
- get_sub_folders(folder: str = '', pattern: str = '*', account: str | int | Account | None = None) List[Dict[str, str]] [source]#
Get the list of all the sub-folders hosted on the server or those matching a pattern.
- Parameters:
folder – Base folder (default: root).
pattern – Pattern to search (default: None).
account – Account name or index (default: default account).
- Returns:
Example:
[ { "name": "INBOX", "flags": "\\Noinferiors", "delimiter": "/" }, { "name": "Archive", "flags": "\\Noinferiors", "delimiter": "/" }, { "name": "Spam", "flags": "\\Noinferiors", "delimiter": "/" } ]
- move_messages(messages: List[int], destination: str, source: str = 'INBOX', account: str | int | Account | None = None)[source]#
Move a set of messages IDs from a folder to another.
- Parameters:
messages – List of message IDs.
source – Source folder.
destination – Destination folder.
account – Account name or index (default: default account).
- remove_flags(messages: List[int], flags: str | List[str], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Remove a set of flags to the specified set of message IDs.
- Parameters:
messages – List of message IDs.
flags –
List of flags to be added. Examples:
['Flagged'] ['Seen', 'Deleted'] ['Junk']
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- rename_folder(old_name: str, new_name: str, account: str | int | Account | None = None)[source]#
Rename a folder on the server.
- Parameters:
old_name – Previous name
new_name – New name
account – Account name or index (default: default account).
- restore_messages(messages: List[int], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Remove the
Deleted
flag from the specified set of message IDs.- Parameters:
messages – List of message IDs.
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- search(criteria: str | List[str] = 'ALL', folder: str = 'INBOX', attributes: List[str] | None = None, account: str | int | Account | None = None) List[Mail] [source]#
Search for messages on the server that fit the specified criteria.
If no criteria is specified, then all the messages in the folder will be returned.
- Parameters:
criteria –
It should be a sequence of one or more criteria items. Each criterion item may be either unicode or bytes (default:
ALL
). Example values:['UNSEEN'] ['FROM', 'me@example.com'] ['TO', 'me@example.com'] ['SMALLER', 500] ['NOT', 'DELETED'] ['TEXT', 'foo bar', 'FLAGGED', 'SUBJECT', 'baz'] ['SINCE', '2020-03-14T12:13:45+00:00']
It is also possible (but not recommended) to pass the combined criteria as a single string. In this case IMAPClient won’t perform quoting, allowing lower-level specification of criteria. Examples of this style:
'UNSEEN' 'SMALLER 500' 'NOT DELETED' 'TEXT "foo bar" FLAGGED SUBJECT "baz"' 'SINCE 03-Apr-2005'
To support complex search expressions, criteria lists can be nested. The following will match messages that are both not flagged and do not have “foo” in the subject:
['NOT', ['SUBJECT', 'foo', 'FLAGGED']]
See RFC 3501#section-6.4.4 for more details.
folder – Folder to search (default:
INBOX
).attributes – Attributes that should be retrieved, according to RFC 3501 (default:
ALL
=[FLAGS INTERNALDATE RFC822.SIZE ENVELOPE]
). Note thatBODY
will be ignored if specified here for performance reasons - useget_message()
if you want to get the full content of a message known its ID fromsearch()
.account – Account name or index (default: default account).
- Returns:
List of messages matching the criteria. Example:
[ { "id": 702, "seq": 671, "flags": [ "nonjunk" ], "internal_date": "2020-08-30T00:31:52+00:00", "size": 2908738, "bcc": {}, "cc": {}, "date": "2020-08-30T00:31:52+00:00", "from": { "test123@gmail.com": { "name": "A test", "route": null, "email": "test123@gmail.com" } }, "message_id": "<SOMETHING@mail.gmail.com>", "in_reply_to": "<SOMETHING@mail.gmail.com>", "reply_to": {}, "sender": { "test123@gmail.com": { "name": "A test", "route": null, "email": "test123@gmail.com" } }, "subject": "Test email", "to": { "me@gmail.com": { "name": null, "route": null, "email": "me@gmail.com" } } } ]
- search_flagged_messages(folder: str = 'INBOX', account: str | int | Account | None = None) List[Mail] [source]#
Shortcut for
search()
that returns only the flagged/starred messages.
- search_starred_messages(folder: str = 'INBOX', account: str | int | Account | None = None) List[Mail] [source]#
Shortcut for
search()
that returns only the starred messages.
- search_unseen_messages(folder: str = 'INBOX', account: str | int | Account | None = None) List[Mail] [source]#
Shortcut for
search()
that returns only the unread messages.
- send(to: str | List[str], from_: str | None = None, cc: str | List[str] | None = None, bcc: str | List[str] | None = None, subject: str = '', body: str = '', body_type: str = 'plain', attachments: List[str] | None = None, headers: Dict[str, str] | None = None, account: str | int | Account | None = None, **kwargs)[source]#
Send an email through the specified SMTP sender.
- Parameters:
to – Receiver(s), as comma-separated strings or list.
from – Sender email address (
from
is also supported).cc – Carbon-copy addresses, as comma-separated strings or list
bcc – Blind carbon-copy addresses, as comma-separated strings or list
subject – Mail subject.
body – Mail body.
body_type – Mail body type, as a subtype of
text/
(e.g.html
) (default:plain
).attachments – List of attachment files to send.
headers – Key-value map of headers to be added.
account – Account name/index to be used (default: default account).
- set_flags(messages: List[int], flags: str | List[str], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Set a set of flags to the specified set of message IDs.
- Parameters:
messages – List of message IDs.
flags –
List of flags to be added. Examples:
['Flagged'] ['Seen', 'Deleted'] ['Junk']
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- sort(folder: str = 'INBOX', sort_criteria: str | List[str] = 'ARRIVAL', criteria: str | List[str] = 'ALL', account: str | int | Account | None = None) List[int] [source]#
Return a list of message ids from the currently selected folder, sorted by
sort_criteria
and optionally filtered bycriteria
. Note that SORT is an extension to the IMAP4 standard, so it may not be supported by all IMAP servers.- Parameters:
folder – Folder to be searched (default:
INBOX
).sort_criteria –
It may be a sequence of strings or a single string. IMAPClient will take care any required conversions. Valid sort_criteria values:
.. code-block:: python ['ARRIVAL'] ['SUBJECT', 'ARRIVAL'] 'ARRIVAL' 'REVERSE SIZE'
criteria – Optional filter for the messages, as specified in
search()
.account – Account name or index (default: default account).
- Returns:
A list of message IDs that fit the criteria.
- start()#
Start the plugin.
- stop()#
Stop the plugin.
- unflag_message(message: int, folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Remove a flag/star from the specified set of message ID.
- Parameters:
message – Message ID.
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- unflag_messages(messages: List[int], folder: str = 'INBOX', account: str | int | Account | None = None)[source]#
Remove a flag/star from the specified set of message IDs.
- Parameters:
messages – List of message IDs.
folder – IMAP folder (default:
INBOX
).account – Account name or index (default: default account).
- wait_stop(timeout=None)#
Wait until a stop event is received.