Zarafa dagent/spooler plugin howto and API documentation
From Zarafa wiki
Contents |
Introduction
ZCP 7.1 offers a new python plugin framework for the Zarafa Spooler and Dagent. This framework makes it easier for advanced system administrators and developers to integrate systems with the spooler and dagent. The advanced system administrator and developer can easily add new functionality or change some behaviours of the existing system. The plugin framework is based on the programming language Python which means that you need to create your own hook in python.
This wiki article contains a howto and API documentation.
How it works
If the plugin framework in the spooler or dagent is enabled it will search for python files in the directory plugin_path and look for a specific type of plugin. If the plugins are found it will be verified and loaded. Everytime the spooler or dagent is called it will execute the hooks based on priority. Plugins can validate and change a message on different stages of the spooler and dagent process.
Design a new Hook
What do you need to know before starting develop python plugins for zarafa dagent and spooler.
- The basics of python
- Read the zarafa python-mapi documentation
If you want to do more advanced development with MAPI its recommend to read the Microsofts MAPI documentation on the internet. This described the different properties, interfaces and some examples in C++. It's relative easy to convert the C++ to the python model because python-mapi implements MAPI as it is described by Microsoft but with the Python design rules.
If you start a new plugin you need atleast the following headers in the new plugin.
Plugin default imports.
import MAPI from MAPI.Util import * from MAPI.Time import * from MAPI.Struct import * from plugintemplates import *
Creating a Plugin for the Dagent
To create a new plugin in the dagent the plugin must inherent from the class IMapiDAgentPlugin. This class has the following functions which can be override.
| Function name | Description |
|---|---|
| PostConverting | Hook direct after the convert from rfc822 to MAPI |
| PreDelivery | Hook before delivery (per reciepient) |
| PreRuleProcess | Hook in to the MAPI rules, to add, modify or remove user rules |
| PostDelivery | Hook after delivery (per reciepient) |
| SendNewMailNotify | Hook to report the end-user if there is a new mail or not |
The zarafa dagent need to extend from the plugin class 'IMapiDAgentPlugin' and override one or more functions of the class.
Example which log the subject of a email:
class MyDagentPlugin(IMapiDAgentPlugin):
def PostConverting(self, session, addrbook, store, folder, message):
props = message.GetProps([PR_SUBJECT], 0)
self.logger.logInfo("My dagent test, the subject is '%s'" % props[0].Value)
return MP_CONTINUE,
Creating a Plugin for the Spooler
To create a new plugin in the spooler the plugin must inherent from the class IMapiSpoolerPlugin. This class has the following functions which can be override.
| Function name | Description |
|---|---|
| PreSending | Hook before sending a MAPI message as a rfc822 mail |
The Zarafa spooler must be extend from the plugin class 'IMapiSpoolerPlugin' and override one or more functions of the class.
Example which log the subject of a email:
class MySpoolerPlugin(IMapiSpoolerPlugin):
def PreSending(self, session, addrbook, store, folder, message):
props = message.GetProps([PR_SUBJECT], 0)
self.logger.logInfo("My spooler test, the subject is: '%s'" % props[0].Value)
return MP_CONTINUE,
Priority of a plugin
Every plugin hook can have a priority which have by default the priority 9999. To change the priority of a hook you need to add an attribute prio<hookname> with the value as priority, for example:
class MyDagentPlugin(IMapiDAgentPlugin): prioPostConverting = 10 def PostConverting(self, session, addrbook, store, folder, message): DoSomeThing()
Log system
The python plugin framework has an internal log system which forward the log information to the Zarafa spooler and Zarafa dagent log. The logger has the following log functions:
| Function name | level | Description |
|---|---|---|
| logFatal | 1 | An (unhandleable) error that results in a hook 'crash' |
| logError | 2 | A handleable error but needs attention |
| logWarn | 3 | A warning |
| logNotice | 4 | Generic information about plugin operation |
| logInfo | 5 | Detailed information about plugin operation |
| logDebug | 6 | Low-level information for developers |
Example log:
self.logger.logFatal("Unable to find file '%s'" % (filename) )
self.logger.logInfo("Message includes %d attachment(s)" % (cntattach) )
API documentation
Dagent api class IMapiDAgentPlugin
Attributes
prioPostConverting
The priority of the PostConverting call. Default 9999
prioPreDelivery
The priority of the PreDelivery call. Default 9999
prioPostDelivery
The priority of the PostDelivery call. Default 9999
prioPreRuleProcess
The priority of the PreRuleProcess call. Default 9999
prioSendNewMailNotify
The priority of the SendNewMailNotify call. Default 9999
Functions
Hook direct after the convert from rfc822 to MAPI
def PostConverting(self, session, addrbook, store, folder, message)
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox
Hook before delivery (per reciepient)
def PreDelivery(self, session, addrbook, store, folder, message)
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox
Hook after delivery (per reciepient)
def PostDelivery(self, session, addrbook, store, folder, message)
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox
Hook in to the MAPI rules, to add, modify or remove user rules
def PreRuleProcess(self, session, addrbook, store, rulestable)
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox
Hook to report the end-user if there is a new mail or not.
def SendNewMailNotify(self, session, addrbook, store, folder, message)
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox
Return values
The return codes for the dagent plugin.
| Exit code | Description |
|---|---|
| MP_CONTINUE | Continue to the next hook |
| MP_FAILED | Whole process failed |
| MP_STOP_SUCCESS | Stop with the message processing go to the next recipient. Recpient return code OK |
| MP_STOP_FAILED | Stop with the message processing go to the next recipient. Recpient return code failed |
| MP_EXIT | Break all the hook calls and go futher with the mail process |
| MP_RETRY_LATER | Stop Process and retry later |
Spooler api class IMapiSpoolerPlugin
Attributes
prioPreSending
The priority of the PreSending call. Default 9999
Hook before sending a MAPI message as a rfc822 mail
def PreSending(self, session, addrbook, store, folder, message):
session
The current MAPI session
addrbook
The addressbook of the user
store
The users mailbox where the email will be deliverd
folder
The Folder where the email is created
message
The actual message which will be deliverd in the mailbox