201 lines
5.3 KiB
ReStructuredText
201 lines
5.3 KiB
ReStructuredText
Welcome to MailBot's documentation!
|
|
=======================================
|
|
|
|
MailBot is a little python library that let's you execute previously registered
|
|
callbacks on reception of emails.
|
|
|
|
This allows you to do fancy things like doing API calls, running scripts,
|
|
sending notifications, ...
|
|
|
|
|
|
Features
|
|
--------
|
|
|
|
MailBot does its best to:
|
|
|
|
* be fully tested
|
|
* apply the pep8 recommendations
|
|
* be lightweight, concise and readable
|
|
|
|
MailBot connects to a mail server using the IMAP protocol, thanks to the
|
|
excellent `IMAPClient from Menno Smits
|
|
<http://imapclient.readthedocs.org/en/latest/>`_.
|
|
|
|
|
|
Other resources
|
|
---------------
|
|
|
|
Fork it on: http://github.com/novagile/mailbot/
|
|
|
|
Documentation: http://mailbot.rtfd.org/
|
|
|
|
|
|
Installing
|
|
----------
|
|
|
|
From PyPI::
|
|
|
|
pip install mailbot
|
|
|
|
From github::
|
|
|
|
pip install -e http://github.com/novagile/mailbot/
|
|
|
|
|
|
Registering callbacks
|
|
---------------------
|
|
|
|
:file:`callbacks.py`:
|
|
|
|
.. code-block:: python
|
|
|
|
from mailbot import register, Callback
|
|
|
|
|
|
class MyCallback(Callback):
|
|
|
|
def callback(self):
|
|
print("Mail received: {O}".format(self.subject))
|
|
|
|
register(MyCallback)
|
|
|
|
By default, callbacks will be executed on each and every mail received, unless
|
|
you specify it differently, either using the 'rules' attribute on the callback
|
|
class, or by registering with those rules:
|
|
|
|
|
|
Providing the rules as a parameter
|
|
----------------------------------
|
|
|
|
Here's a callback that will only be triggered if the subject matches the
|
|
pattern 'Hello ' followed by a word, anywhere in the subject (it uses
|
|
``re.search``):
|
|
|
|
.. code-block:: python
|
|
|
|
from mailbot import register, Callback
|
|
|
|
|
|
class MyCallback(Callback):
|
|
rules = {'subject': [r'Hello (\w)']}
|
|
|
|
def callback(self):
|
|
print("Mail received for {0}".format(self.matches['subject'][0]))
|
|
|
|
register(MyCallback)
|
|
|
|
This callback will be triggered on a mail received with the subject "Hello
|
|
Bryan", but won't if the subject is "Bye Bryan".
|
|
|
|
|
|
Providing the rules when registering
|
|
------------------------------------
|
|
|
|
The similar functionality can be achieved using a set of rules when
|
|
registering:
|
|
|
|
.. code-block:: python
|
|
|
|
from mailbot import register, Callback
|
|
|
|
|
|
class MyCallback(Callback):
|
|
|
|
def callback(self):
|
|
print("Mail received for %s!" self.matches['subject'][0])
|
|
|
|
register(MyCallback, rules={'subject': [r'Hello (\w)']})
|
|
|
|
|
|
How does it work?
|
|
-----------------
|
|
|
|
When an email is received on the mail server the MailBot is connected to
|
|
(using the IMAP protocol), it'll check all the registered callbacks and their
|
|
rules.
|
|
|
|
If each provided rule (either as a class parameter or using the register)
|
|
matches the mail's subject, from, to, cc and body, the callback will be
|
|
triggered.
|
|
|
|
|
|
Specifying rules
|
|
----------------
|
|
|
|
Rules are regular expressions that will be tested against the various email
|
|
data:
|
|
|
|
* ``subject``: tested against the subject
|
|
* ``from``: tested against the mail sender
|
|
* ``to``: tested against each of the recipients in the "to" field
|
|
* ``cc``: tested against each of the recipients in the "cc" field
|
|
* ``body``: tested against the (text/plain) body of the mail
|
|
|
|
If no rule are provided, for example for the "from" field, then no rule will be
|
|
applied, and emails from any sender will potentially trigger the callback.
|
|
|
|
For each piece of data (subject, from, to, cc, body), the callback class,
|
|
once instantiated with the mail, and the ``check_rules`` method called, will
|
|
have the attribute ``self.matches[item]`` set with all the matches from the
|
|
given patterns, if any
|
|
|
|
Here are example subjects for the subject rules:
|
|
[``r'^Hello (\w), (.*)'``, ``r'[Hh]i (\w)!``]
|
|
|
|
* 'Hello Bryan, how are you?': self.matches['subject'] == ['Bryan', 'how are you?']
|
|
* 'Hi Bryan, how are you?': self.matches['subject'] == ['Bryan']
|
|
* 'aloha, hi Bryan!': self.matches['subject'] == ['Bryan']
|
|
* 'aloha Bryan': rules not respected, callback not triggered,
|
|
self.matches['subject'] == None
|
|
|
|
|
|
Rules checking
|
|
--------------
|
|
|
|
A callback will be triggered if the following applies:
|
|
|
|
* for each item/rule, **any** of the provided regular expressions matches
|
|
* **all** the rules (for all the provided items) are respected
|
|
|
|
Notice the "any" and the "all" there:
|
|
|
|
* for each rule, there may be several regular expressions. If any of those
|
|
match, then the rule is respected.
|
|
* if one rule doesn't match, the callback won't be triggered. Non existent
|
|
rules don't count, so you could have a single rule on the subject, and none
|
|
on the other items (from, to, cc, body).
|
|
|
|
As an example, let's take an email with the subject "Hello Bryan", from
|
|
"John@doe.com":
|
|
|
|
.. code-block:: python
|
|
|
|
from mailbot import register, Callback
|
|
|
|
|
|
class MyCallback(Callback):
|
|
rules = {'subject': [r'Hello (\w)', 'Hi!'], 'from': ['@doe.com']}
|
|
|
|
def callback(self):
|
|
print("Mail received for {0}".format(self.matches['subject'][0]))
|
|
|
|
register(MyCallback)
|
|
|
|
All the rules are respected, and the callback will be triggered
|
|
|
|
* subject: even though 'Hi!' isn't found anywhere in the subject, the other
|
|
regular expression matches
|
|
* from: the regular expression matches
|
|
* to, cc, body: no rules provided, so they aren't taken into account
|
|
|
|
The last bullet point also means that if register a callback with no rules at
|
|
all, it'll be triggered on each and every email, making it a "catchall
|
|
callback".
|
|
|
|
|
|
Contents
|
|
--------
|
|
|
|
.. toctree::
|
|
:maxdepth: 2
|