# PODNAME: Mail::MtPolicyd::Cookbook::BasicModule
# ABSTRACT: how to write your own mtpolicyd plugin

__END__

=pod

=encoding UTF-8

=head1 NAME

Mail::MtPolicyd::Cookbook::BasicModule - how to write your own mtpolicyd plugin

=head1 VERSION

version 2.05

=head1 How to write your own mtpolicyd plugin

mtpolicyd makes use of L<Moose>. If you're not yet familiar with L<Moose> you should start reading the L<Moose::Intro> first.

=head2 Basic skeleton of a mtpolicyd plugin

A plugin in mtpolicyd is basically a class which inherits from L<Mail::MtPolicyd::Plugin> and is located below the Mail::MtPolicyd::Plugin:: namespace:

  package Mail::MtPolicyd::Plugin::HelloWorld;

  use Moose;
  use namespace::autoclean;

  # VERSION
  # ABSTRACT: a mtpolicyd plugin which just returns a hello world reject

  extends 'Mail::MtPolicyd::Plugin';

  use Mail::MtPolicyd::Plugin::Result;

  sub run {
    my ( $self, $r ) = @_;

    return Mail::MtPolicyd::Plugin::Result->new(
      action => 'reject Hello World!',
      abort => 1,
    );
  }

  __PACKAGE__->meta->make_immutable;

  1;

Every plugin must implement a run() method. mtpolicyd will call run() every time your module is called from the configuration to process a request.
A L<Mail::MtPolicyd::Request> object containing the current request is passed to the method.
The run() method must return undef or a <Mail::MtPolicyd::Plugin::Result> object.
If undef is return mtpolicyd will continue with the next plugin.
If a result is returned mtpolicyd will push the result to the list of results and abort processing the request if abort is set.

After you placed the module with your lib search path you should be able to use the plugin within mtpolicyd.conf:

  <Plugin hello-world>
    module = "HelloWorld"
  </Plugin>

For now our plugin will just return an "reject Hello World!" action to the MTA.

=head2 Adding configuration options

All options defined in the configuration file will be passed to the object constructor new() when creating an object of your plugin class.

The parameter "module" is not passed to the object constructor because it contains the name of your class.

You can defined configuration parameters by adding attributes to your class.

You're class already inherits 3 attributes from the Plugin base class:

=over

=item name (required)

Which contains the name of your <Plugin> section.

=item log_level (default: 4)

Which contains the level used when your plugin calls $self->log( $r, '...');.

=item on_error (default: undef)

Tells mtpolicyd what to do when the plugin dies.

If set to "continue" mtpolicyd will continue processing and just leaves a line in the log.

=back

Add a new attribute to your plugin class:

  has 'text' => ( is => 'rw', isa => 'Str', default => 'Hello World!');

Return this string instead of the hard coded string:

      action => 'reject '.$self->text,

The string is now configurable from the configuration:

  <Plugin hello-world>
    module = "HelloWorld"
    text = "Hello Universe!"
  </Plugin>

=head1 AUTHOR

Markus Benning <ich@markusbenning.de>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2014 by Markus Benning <ich@markusbenning.de>.

This is free software, licensed under:

  The GNU General Public License, Version 2, June 1991

=cut
