exchangelib icon indicating copy to clipboard operation
exchangelib copied to clipboard

Implement inbox filtering rules

Open mcv21 opened this issue 7 years ago • 12 comments

Hi,

It would be really nice to be able to manage inbox rules (i.e. for mail filtering from exchangelib). I've had a bit of a look in the code base, but don't really know what I'm doing here. I think this would need:

  • a Conditions class (which I think can be built using existing field types)
  • an Exceptions class (which would need calling something else!) similar to the above
  • an Actions class some of the elements of which are easy, some of which are harder
  • a Rules class which contains the above and some simpler elements

And then support the services GetInboxRules, CreateRuleOperation and SetRuleOperation. It feels like this ought to be fairly straightforward plumbing for someone who is familiar with the code base, but I don't really know where to start. I'd be happy to test some code that did these things and write a UI on top of them, or perhaps could try some of the sub-tasks given a few more hints of the way to make the plumbing work...?

Thanks, and sorry for a slightly vague request!

mcv21 avatar Sep 06 '17 11:09 mcv21

Unless you intend to automate the creation of filtering rules for many users, I'm not sure it's worth the effort.

The interface to create rules in Outlook or OWA is not too bad, and certainly quicker than coding the same in Python, even if we implemented this. If you don't have access to an Exchange client that can create filters, you could still create a Python script that periodically checks your inbox and processes new messages using any logic you like, not just restricted to the DSL that Exchange rules allow.

ecederstrand avatar Sep 07 '17 15:09 ecederstrand

I want to use server-side filtering (rather than client-side), because I access my mail from several different IMAP clients. From my POV, mail filtering is part of my infrastructure, so I want to be able to keep it in version control and so on. I'm moving from a Sieve-based system where that was easy; it's not so easy with Exchange, but want to produce something similar for an Exchange-based system.

As you say, the Exchange rules system is relatively simplistic, so I'm happy about producing a front-end as it were; but obviously that needs exchangelib to support the relevant API operations.

-- The Wellcome Trust Sanger Institute is operated by Genome Research Limited, a charity registered in England with number 1021457 and a company registered in England with number 2742969, whose registered office is 215 Euston Road, London, NW1 2BE.

mcv21 avatar Sep 08 '17 11:09 mcv21

Ok. Thanks for the clarification. I'll probably have other priorities for now, but contributions are always welcome.

Until someone goes about implementing this, you can still make a poor-man's filter tool by creating a cron job that runs every few minutes and does something like this:

a = Account(...)
tz = EWSTimeZone.localzone()
last_visit = tz.localize(EWSDateTime.now()) - timedelta(minutes=10)
for item in a.inbox.filter(is_read=False, datetime_received__gt=last_visit):
    if item.subject.startswith('V!agra Pi11s'):
        item.move(to_folder=a.junk)

This moves the items server-side, so it will be reflected in all your clients.

ecederstrand avatar Sep 08 '17 11:09 ecederstrand

To extend this, the combination with OOF would be great.

BlackDuck888 avatar Feb 19 '18 08:02 BlackDuck888

Being able to read / write InboxRules would not only be helpful to create new rules, but also in migrating accounts. Support for GetInboxRules and GetUserConfiguration (and the corresponding Add...s and Update...s) would be a great addition. The same goes for GetDelegate.

mleisi avatar Jun 23 '19 19:06 mleisi

so is it implemented or still we have to wait some more time, because it would be really helpful if we can have server side filters applied on the emails.

manish59 avatar Oct 03 '19 18:10 manish59

It's not implemented yet, and I have no immediate plans to do so.

Contributions are most welcome, of course.

ecederstrand avatar Oct 04 '19 05:10 ecederstrand

Thanks for the reply, I really appreciate the work you have done so far on exchangelib, can you point to me atleast where should i start if I want to implement that.

Thanks, Manish

On Thu, Oct 3, 2019 at 10:55 PM Erik Cederstrand [email protected] wrote:

It's not implemented yet, and I have no immediate plans to do so.

Contributions are most welcome, of course.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ecederstrand/exchangelib/issues/233?email_source=notifications&email_token=AD2AH5CBALHS6B2V7SJN543QM3LENA5CNFSM4DZY2LHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAKQN5I#issuecomment-538248949, or mute the thread https://github.com/notifications/unsubscribe-auth/AD2AH5H6AQCZHOKXJYGNZNDQM3LENANCNFSM4DZY2LHA .

manish59 avatar Oct 04 '19 16:10 manish59

A first step is to implement the GetInboxRues and UpdateInboxRules services. There are multiple examples in https://github.com/ecederstrand/exchangelib/tree/master/exchangelib/services that you can use as a template.

While implementing these services, you'll need to implement some of the XML elements that are used, e.g. the Rule and Action elements. There are examples in https://github.com/ecederstrand/exchangelib/blob/master/exchangelib/properties.py you can use as templates.

Then we probably want some syntactic sugar so you don't have to create the service directly. The service acts on a single account, and we want a nice interface to list, create, update and delete rules. I think something like this would be nice, unless you have better ideas:

a = Account(...)

# a.inbox_rules should fetch and cache rules from th server
for rule in a.inbox_rules:
    print(rule)

# Create rule. a.inbox_rules.add() should create the rule on the server
rule = Rule(
    is_enabled=True,
    priority=1,
    actions=Actions(move_to_folder=a.trash, mark_as_read=True, ...),
    ...
)
a.inbox_rules.add(rule)
a.inbox_rules.update(rule)
a.inbox_rules.remove(rule)

# It would be nice to have these shortcuts, too. Requires a `Rule.account` attribute
rule.is_enabled=False
rule.save()  # Updates the rule on the server

rule.delete()

Finally, you'll need some test cases that cover the new functionality. I tend to only write tests for the exposed API, i.e. the .add(), .update(), .remove(), save() and .delete() methods.

I think you can assume that the rules actually work when they have been created on the server, so it's not required to test e.g. that the move_to_folder action is applied on incoming mail.

ecederstrand avatar Oct 05 '19 12:10 ecederstrand

Do you have any plan for adding inbox rule functions in this lib?

devindaiyu avatar Dec 13 '19 10:12 devindaiyu

It's not something I'm planning to work on anytime soon. Contributions are welcome, of course :-)

ecederstrand avatar Dec 13 '19 10:12 ecederstrand

Forked it, working on it, no promises though :p Need to monitor which #@*%$ users are using evil forward rules to their gmail or whatnot.

ruggdoll avatar May 10 '20 22:05 ruggdoll