3 cm_perl -- A Perl Plugin for Claws Mail
7 This plugin provides an extended filtering engine for the email
8 client Claws Mail. It allows for the use of full Perl power
13 To get started, you can use the B<matcherrc2perlfilter.pl> script
14 in the B<tools>-directory to translate your old filtering rules to
15 Perl. Simply execute the script and follow the instructions.
16 (note that with recent versions of Claws Mail, this script might not
17 work due to upstream syntax changes. This will get updated in the
18 future. Send me an email if you have problems getting started).
20 However, you might want to consider reading the rest of this
21 manual and rewriting your rules if you choose to use the plugin,
22 since the Perl code produced by this script is not exactly
25 Don't speak Perl? No problem, L<"perldoc perlintro"|perlintro>
26 should give you enough information to do fancy stuff.
30 The Perl plugin expects a Perl script file called B<perl_filter>
31 in Claws Mail' config directory (usually $HOME/.claws-mail --
32 try `claws-mail --config-dir' if you're unsure). If that file
33 doesn't exist on plugin start, an empty one is created. This
34 file, which doesn't need to start with a sha-bang (!#/bin/perl),
35 holds the Perl instructions for your email filters. To encourage
36 some good manners, the code is executed in a C<use strict;>
39 Both Claws Mail' filtering B<conditions> and B<actions> are
40 mapped to Perl functions with corresponding names, wherever this
43 =head1 FUNCTION LISTING
45 For a detailed function description, see section L</"FUNCTION
46 DESCRIPTIONS">, below.
50 =item Standard Filtering Conditions
52 all, marked, unread, deleted, new, replied,
53 forwarded, locked, ignore_thread, colorlabel,
54 match, matchcase, regexp, S<regexpcase, test,
55 size_greater, size_smaller, size_equal,
56 score_greater, score_lower, score_equal, age_greater,
57 age_lower, partial, tagged
59 =item Standard Filtering Actions
61 mark, unmark, dele, mark_as_unread, mark_as_read,
62 lock, unlock, move, copy, color, execute,
63 hide, set_score, change_score, stop, forward,
64 forward_as_attachment, redirect, set_tag, unset_tag,
69 header, body, filepath, extract_addresses,
70 move_to_trash, abort, addr_in_addressbook,
71 from_in_addressbook, get_attribute_value, SA_is_spam,
72 exit, manual, make_sure_folder_exists,
73 filter_log, filter_log_verbosity,
78 =head1 FUNCTION DESCRIPTIONS
80 In general, after the filtering invoked by the Perl script, the
81 mail is passed on to Claws' internal filtering engine, I<unless>
82 a B<final> rule was hit. Final rules stop not only the Perl
83 filtering script at the point of their occurrence, but also
84 prevent processing that email by Claws' internal filtering engine
85 (this might sound confusing, but you are already familiar with
86 that concept from standard filters: After an email was
87 e.g. I<move>d, the following rules don't apply anymore).
89 Also, be careful with the way you quote. In particular, remember
90 that the @-sign has a special meaning in Perl, and gets
91 interpolated inside double quotes. See L<perlop/"Quote and
92 Quote-like Operators"> to learn more about quoting and
96 =head2 Standard Filtering Conditions
102 Returns a true value. Available for completeness only.
106 Returns a true value if the marked flag is set, false otherwise.
110 Returns a true value if the unread flag is set, false otherwise.
114 Returns a true value if the deleted flag is set, false otherwise.
118 Returns a true value if the new flag is set, false otherwise.
122 Returns a true value if the replied flag is set, false otherwise.
126 Returns a true value if the forwarded flag is set, false otherwise.
130 Returns a true value if the locked flag is set, false otherwise.
134 Returns a true value if the "Ignore Thread" flag is set, false otherwise.
136 =item colorlabel COLOR
140 Returns a true value if message has the color COLOR. COLOR can be
141 either a numeric value between 0 and 7 (with colors corresponding
142 to the internal filtering engine), or the english color name as
143 it is introduced in the filtering dialog (that is, one of: none,
144 orange, red, pink, sky blue, blue, green or brown, while upper
145 and lower case letters make no difference). If COLOR is omitted,
148 =item size_greater SIZE
150 Returns a true value if message size is greater than SIZE, false otherwise.
152 =item size_smaller SIZE
154 Returns a true value if message size is smaller than SIZE, false otherwise.
156 =item size_equal SIZE
158 Returns a true value if message size is equal to SIZE, false otherwise.
160 =item score_greater SCORE
162 Returns a true value if message score is greater than SCORE, false otherwise.
164 =item score_lower SCORE
166 Returns a true value if message score is lower than SCORE, false otherwise.
168 =item score_equal SCORE
170 Returns a true value if message score is equal to SCORE, false otherwise.
172 =item age_greater AGE
174 Returns a true value if message age is greater than AGE, false otherwise.
178 Returns a true value if message age is lower than AGE, false otherwise.
182 Returns a true value if message has only partially been
183 downloaded, false otherwise.
187 Returns a true value if the messages has one or more tags.
191 Corresponds the 'test' internal filtering rule. In particular, it
192 accepts the same symbols, namely:
234 Filename -- should not be modified
238 =item match WHERE WHAT
240 =item matchcase WHERE WHAT
242 =item regexp WHERE WHAT
244 =item regexpcase WHERE WHAT
246 The matching functions have a special syntax. The first argument
247 is either any of to_or_cc, body_part, headers_part, headers_cont,
248 message, to, from, subject, cc, newsgroups, inreplyto,
249 references, or tag (those strings may or may not be quoted), the
250 pattern matching works on that area. If it is any other string
251 (which must then be quoted), this string is taken to be the name
254 The second argument is the string to look for. For match,
255 matchcase, regexp and regexpcase we have case sensitive normal
256 matching, case insensitive normal matching, case sensitive
257 regular expression matching and case insensitive regular
258 expression pattern matching, respectively.
260 The functions return true if the pattern was found, false
263 Just as with the built-in filtering engine, the message body is
264 searched and provided as is - no character-set analysis is
265 done. Likewise, no HTML-tags are stripped. It should be possible
266 to use external modules or programs for these tasks though. If
267 you're doing that, drop me a message with your experiences.
269 With Perl having its strengths in pattern matching, using Perl's
270 builtin operators are usually a better option than using these
275 =head2 Standard Filtering Actions
277 The actions return a true value upon success, and 'undef' when an
278 error occurred. I<Final> message rules are indicated. (See above
279 for a sketch what a final rule is)
293 Delete the message. Note the name change of Claws Mail'
294 "delete" to "dele". This is because "delete" is one of Perl's
295 builtin commands which cannot be redefined (if it can, tell me
298 This is a I<final> rule.
302 Mark the message as read
306 Mark the message as unread
314 Remove the message lock
316 =item move DESTINATION
318 Move the message to folder DESTINATION. The folder notation is
319 the same that Claws Mail uses. You can copy & paste from the
320 move dialog of the normal filtering, until you get a feeling for
323 This is a I<final> rule.
325 =item copy DESTINATION
327 Copy the message to folder DESTINATION. The folder notation is
328 the same that Claws Mail uses. You can copy & paste from the
329 move dialog of the normal filtering, until you get a feeling for
332 =item execute COMMAND
334 This is the same as the test - rule from section L</"Standard
335 Filtering Conditions"> execpt that it always returns a true
342 =item set_score SCORE
344 Set message score to SCORE
346 =item change_score SCORE
348 Change message score by SCORE
352 Stop Perl script at this point. Note that this is B<not> a final
353 rule, meaning that the email gets passed on to the internal
354 filtering engine. See "abort" below if you don't want that.
356 =item forward ACCOUNT, EMAIL
358 Forward the message to email address EMAIL, using the account ID
359 ACCOUNT as sender account. So far, you have to create a rule
360 in the normal filtering engine to find out that number.
362 =item forward_as_attachment, ACCOUNT EMAIL
364 Forward the message to email address EMAIL in an attachment,
365 using the account ID ACCOUNT as sender account. So far, you
366 have to create a rule in the normal filtering engine to find out
369 =item redirect ACCOUNT, EMAIL
371 Redirect the message to EMAIL, using the account ID ACCOUNT as
372 sender account. So far, you have to create a rule in the normal
373 filtering engine to find out that number.
377 Apply tag TAG. TAG must exist.
399 If ARG is not given, returns a list of all header field names of
402 If ARG is given, returns 'undef' if the header field ARG does not
403 exist in the email. Otherwise, it returns
407 =item in scalar context
409 The value of the header field ARG.
411 =item in list context
413 A list of all available header field values. This is useful if a
414 header field occurs more than once in an email (eg the Received -
419 The header field "References" forms a special case. In a scalar context,
420 it returns the first reference. In a list context, it returns a list of
425 Returns the email body in a scalar.
429 Returns the file and path of the email that is currently filtered
430 (corresponds to the %F arguemnt in the 'test' rule).
432 =item extract_addresses
434 Extracts email addresses from a string and gives back a list of
435 addresses found. Currently an email address is found using the
436 regular expression '[-.+\w]+\@[-.+\w]+'. This will not find all
437 valid email addresses. Feel free to send me a better regexp.
441 Move the email message to default trash folder.
443 This is a I<final> rule.
447 Stop Perl script at this point.
449 In contrast to 'stop', this is a I<final> rule.
451 =item addr_in_addressbook EMAIL, ADDRESSBOOK
453 =item addr_in_addressbook EMAIL
455 Returns a true value if the email address EMAIL is in the addressbook
456 with the name ADDRESSBOOK. If ADDRESSBOOK is not given, returns
457 true if the email address is in any addressbook.
459 =item from_in_addressbook ADDRESSBOOK
461 =item from_in_addressbook
463 Checks if the email address found in the From-header is in
464 addressbook ADDRESSBOOK (or any, if omitted). It is implemented
467 my ($from) = extract_addresses(header("from"));
468 return 0 unless $from;
469 return addr_in_addressbook($from,@_);
471 so the same restrictions as to extract_addresses apply.
473 =item get_attribute_value EMAIL, ATTRIBUTE, ADDRESSBOOK
475 =item get_attribute_value EMAIL, ATTRIBUTE
477 Looks through the addressbook ADDRESSBOOK (or all addressbooks,
478 if omitted) for a contact with the an email address EMAIL. If
479 found, the function checks if this contact has a user attribute
480 with name ATTRIBUTE. It returns the value of this attribute, or
481 an empty string if it was not found. As usual, 'undef' is
482 returned if an error occurred.
488 not test 'spamc -c < %F > /dev/null'
492 Has been redefined to be an alias to 'stop'. You shouldn't use
493 Perl's own 'exit' command, since it would exit Claws Mail.
497 Returns a true value if the filter script was invoked manually,
498 that is, via the Tools menu.
500 =item make_sure_folder_exists IDENTIFIER
502 Returns a true value if the folder with id IDENTIFIER (e.g. #mh/Mail/foo/bar)
503 exists or could be created.
505 =item make_sure_tag_exists TAG
507 Returns a true value if the tag TAG exists or could be created.
509 =item filter_log SECTION, TEXT
511 =item filter_log TEXT
513 Writes TEXT to the filter logfile. SECTION can be any of
531 If the SECTION is omitted, "LOG_MANUAL" is assumed.
533 =item filter_log_verbosity VERBOSITY
535 =item filter_log_verbosity
537 Changes the filter log verbosity for the current mail. VERBOSITY
560 For the meaning of those numbers, read section L</"LOGGING">. If
561 VERBOSITY is omitted, the filter logfile verbosity is not changed.
563 This function returns the filter_log_verbosity number before the
574 This scalar keeps its value between filtered mail messages. On
575 plugin start, it is initialized to the empty string.
581 To keep track of what has been done to the mails while filtering,
582 the plugin supports logging. Three verbosity levels are
593 log only manual messages, that is, messages introduced by the
594 C<filter_log> command in filter scripts
598 log manual messages and filter actions
602 log manual messages, filter actions and filter matches
606 The messages are logged in Claws Mail' log window.
607 The default log level is 2. Log level 3 is not
608 recommended, because the matcher functions log a message if they
609 succeeded, and thus, if you have negative checks, you'll get
610 confusing entries. If you want to keep track of matching, do it
611 manually, using C<filter_log>, or do it by temporary enabling
612 matcher logging using C<filter_log_verbosity>.
614 The first time you unload this plugin (or shut down
615 Claws Mail), a section called B<[PerlPlugin]> will be created
616 in Claws Mail' configuration file B<clawsrc>, containing
619 * filter_log_verbosity
621 If you want to change the default behaviour, you can edit this
622 line. Make sure Claws Mail is not running while you do
625 It will be possible to access these setting via the GUI, as soon
626 as I find the time to write a corresponding GTK plugin, or
627 somebody else is interested in contributing that.
631 This section lists a small example of a Perl script file. I'm
632 sure you get the idea..
634 #-8<----------------------------------------------------
639 # Learn ham messages, and move them to specified folder. This is
640 # useful for making sure a bayes filter sees ham as well.
642 execute('put command to learn ham here');
646 # Two-stage spam filter. Every email that scores higher than 15
647 # on SpamAssassin gets moved into the default trash folder.
648 # All mails lower than that, but higher than SpamAssassin's
649 # 'required_hits' go into #mh/mail/Spam.
651 my $surely_spam = 15;
652 my $filepath = filepath;
653 my $spamc = `spamc -c < $filepath`;
654 my ($value,$threshold) = ($spamc =~ m|([-.,0-9]+)/([-.,0-9]+)|);
655 if($value >= $surely_spam) {
659 if($value >= $threshold) {mark_as_read; move '#mh/mail/Spam';}
662 # Perl script execution starts here.
664 # Some specific sorting
665 learn_and_move '#mh/mail/MailLists/Claws Mail/user'
666 if matchcase('sender','claws-mail-users-admin@lists.sourceforge.net');
667 learn_and_move '#mh/mail/MailLists/Sylpheed'
668 if matchcase('list-id','sylpheed.good-day.net');
670 # Implement incoming folders using addressbook
671 # attributes. Target folders for specific email addresses are
672 # stored directly in the addressbook. This way, if an email
673 # address changes, we only have to update the addressbook, not
674 # the filter rules! Besides that, we can greatly unclutter the
677 # get the email address in the from header
678 my $fromheader = header "from";
679 my ($from) = extract_addresses $fromheader;
681 # check if this email address has an associated attribute
682 # called "incoming_folder". If if has, the value of this
683 # attribute is supposed to be the target folder.
684 my $value = get_attribute_value $from, "incoming_folder";
685 learn_and_move($value) if $value;
687 # An example of a whitelist: If the from-address is in my
688 # "office" addressbook, move the mail to folder #mh/mail/office
689 learn_and_move '#mh/mail/office' if from_in_addressbook("office");
691 # If the from-address is in any other addressbook, move the
692 # mail to folder #mh/mail/inbox/known
693 learn_and_move '#mh/mail/inbox/known' if from_in_addressbook;
695 # Feed the remaining mails through SpamAssassin.
698 # mails that make it to the end of the script are passed on to
699 # the internal filtering engine. If the internal rules don't say
700 # otherwise, the mails end up in the default inbox.
701 #-8<----------------------------------------------------
710 Do B<not> use this plugin together with other filtering plugins,
711 especially the B<Spamassassin> and B<ClamAV> plugins. They are
712 registered on the same hook and the order in which the plugins
713 are executed is not guaranteed.
717 The filter script is not (yet) updated automatically when a
718 folder gets renamed. The same applies for folder names in
719 addressbook user attributes.
723 This plugin has only be tested with POP3 accounts. If you have
724 experiences with IMAP or newsgroup accounts, drop me a message.
728 Warning during compile time:
730 *** Warning: Linking the shared library perl_plugin.la against the
732 /usr/lib/perl5/5.8.3/i586-linux-thread-multi/auto/DynaLoader/DynaLoader.a
735 Ideas to solve this one are welcome :-)
739 Please report comments, suggestions and bugreports to the address
740 given in the L</AUTHOR> section of this document.
743 =head1 LICENSE and (no) WARRANTY
745 This program is free software; you can redistribute it and/or
746 modify it under the terms of the GNU General Public
747 License as published by the Free Software Foundation;
748 either version 3 of the License, or (at your option) any later
751 This program is distributed in the hope that it will be useful,
752 but WITHOUT ANY WARRANTY; without even the implied warranty of
753 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
754 GNU General Public License for more details.
756 You should have received a copy of the GNU General Public License
757 along with this program. If not, see http://www.gnu.org/licenses/.
761 claws-mail(1), perl(1)
766 Holger Berndt <berndth@gmx.de>