correspond.channels.mail#
Email: IMAP to read and listen, SMTP to send, with the standard library.
References
email:: the whole folder (INBOXunless configured), which is whatlistenwatches.email:<address>: the correspondence with one address: its messages in the folder, and sends to it.?folder=<name>after either picks the folder for this reference alone, so one process reads several (Gmail serves labels as folders:email:?folder=Newsletters/AI).?from=<sender>,<sender>onemail:keeps the messages from any of several senders, each an address or a whole domain (@example.org). Both together:email:?folder=News&from=ada@example.org,@example.net. A value is percent-encoded where it has a space,&,?or%(email:?folder=%5BGmail%5D/All%20Mail), and so is an address with one of those. A folder may be named as written (Énergie) or as the server lists it in modified UTF-7 (&AMk-nergie); both are one reference. On a command line, quote a reference with?or&:correspond read 'email:?folder=News'.?gmail=<search>adds Gmail’s own search syntax (X-GM-RAW) on a server that advertisesX-GM-EXT-1, and is refused elsewhere:email:?gmail=category:promotions+newer_than:7d. As in Gmail’s own addresses,+is a space (a plus sign is%2B). It narrows the other keys; it replaces none of them, so?from=still checks each From exactly. Listening delivers a message only if it matches when the listen first passes it: a search whose answer changes later (is:starred, a label added afterwards,is:unread) misses the mail that comes to match after newer mail has moved the cursor on.
A message’s conversation is the correspondence with its sender (email:<address>), in
whichever folder it was read; native["folder"] says which.
Message ids are Message-ID headers, angle brackets included. A draft’s reply_to is
one, and the send carries In-Reply-To and References. Reading never marks a message
seen.
Authenticity is claimed unless the topmost Authentication-Results header was
added by a server you trust (trusted_authserv_ids) and records dmarc=pass for the
From domain: then it is domain. Only the topmost header counts, even when the trusted
server added several: a lower one carrying the same authserv-id may have been written by the
sender (not every server strips those), so a result recorded lower down fails safe as
claimed.
>>> Email().parse_ref("Ada@Example.org").encoded
'email:ada@example.org'
>>> Email().parse_ref("?from=@Example.NET,ada@example.org&folder=News/AI").encoded
'email:?folder=News/AI&from=@example.net,ada@example.org'
Module Attributes
Words that, as a part of an address's local part ( |
Functions
|
|
Classes
|
A mailbox over IMAP and SMTP. |
- class correspond.channels.mail.Email(*, imap=None, smtp=None, run=<function run>)[source]#
Bases:
objectA mailbox over IMAP and SMTP.
- audience(ref, *, draft=None)[source]#
Who reads an email: its address plus the draft’s
ccandbcc, asked of nothing but the config.Scope
named, nevercomplete: any address may be an alias, a shared mailbox or an auto-forward, which nothing here can see. A recipient whose domain is not inown_domainsmakes itexternal; a list-shaped address (underlistsin the config, or a local part naming a group, seeLIST_LOCAL_PARTS) adds a class andlist_expansion, and, when every address is in an own domain, leavesexternalunknown, since a list can have outside members. A Bcc address is a class of its own, so moving it to Cc changes the hash. Every email is pushed to its recipients, can be forwarded, and cannot be recalled.- Return type:
- property capabilities: Capabilities#
Read and listen to a folder per reference; send with threading headers.
- parse_ref(id)[source]#
""for the folder, or an address; either may add?folder=(and the folder?from=).- Return type:
- poll(ref, *, cursor=None, limit=None)[source]#
New messages since
cursor(<uidvalidity>:<uid>); a first poll, or a changed UIDVALIDITY, looks back a day.
- prepare(ref, draft)[source]#
The draft as it will go out:
notifyaddresses checked and put in Cc (out of Bcc). Pure.- Return type:
- read(ref, *, since=None, limit=None)[source]#
Messages in the reference’s folder (from its address or senders, if it names any), oldest first; never marked seen.
- send(ref, draft, *, dry_run=False)[source]#
Send to
ref’s address, withIn-Reply-ToandReferenceswhen replying;ccin a header,bcconly on the envelope.A
draft.notifyaddress that is neither the To address nor already in Cc is added to Cc (and so leaves Bcc, which would hide it); the plan lists it undercc_added.- Return type:
- correspond.channels.mail.LIST_LOCAL_PARTS = ('list', 'all', 'team', 'dev', 'announce', 'info')#
Words that, as a part of an address’s local part (
dev-team@), mark it as a possible mailing list.