mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
4a56d2d087
Introducing a new plugin for enhanced email organization: Search Filters, inspired by similar features in Gmail (Search Filters) and Outlook (Rules). The plugin allows you to define custom search queries that automatically perform one or more actions on matching emails based on their priority level (1-10). Available actions include marking as seen, flagging/starring, and moving to a designated folder. This plugin is designed to work seamlessly with both old and new emails in your inbox, taking into account the specified search query criteria. However, please be aware of an outstanding bug that affects the display of unread email counts beside folders; this issue has yet to be resolved. I have developed this plugin as a freelance project for a client on their custom server setup. Unfortunately, I never received any feedback or response from my client after completion of the work. Nonetheless, I hope that sharing it here will benefit others and contribute to the ongoing advancement of this open-source project. Please note: This plugin is offered as-is with no warranties or guarantees. Make sure to thoroughly test and verify its functionality before using it in a production environment. Thank you to everyone who has contributed to making this project a reality. |
||
---|---|---|
.. | ||
add-x-originating-ip-header | ||
attachments-force-open | ||
auto-domain-grab | ||
avatars | ||
backup | ||
black-list | ||
cache-apcu | ||
cache-memcache | ||
cache-redis | ||
change-password | ||
change-password-cpanel | ||
change-password-froxlor | ||
change-password-hestia | ||
change-password-hmailserver | ||
change-password-ispconfig | ||
change-password-poppassd | ||
change-smtp-ehlo-message | ||
compact-composer | ||
contact-group-excel-paste | ||
custom-login-mapping | ||
custom-system-folders | ||
demo-account | ||
example | ||
haveibeenpwned | ||
imap-contacts-suggestions | ||
kolab | ||
ldap-contacts-suggestions | ||
ldap-identities | ||
ldap-login-mapping | ||
ldap-mail-accounts | ||
login-autoconfig | ||
login-cpanel | ||
login-external | ||
login-external-sso | ||
login-gmail | ||
login-o365 | ||
login-oauth2 | ||
login-override | ||
login-proxyauth-example | ||
login-register | ||
login-remote | ||
mailbox-detect | ||
nextcloud | ||
override-smtp-credentials | ||
proxy-auth | ||
recaptcha | ||
search-filters | ||
set-remote-addr | ||
smtp-use-from-adr-account | ||
snowfall-on-login-screen | ||
two-factor-auth | ||
video-on-login-screen | ||
view-ics | ||
white-list | ||
wysiwyg-example | ||
README.md |
Also see https://github.com/the-djmaze/snappymail/tree/master/plugins/example
PHP
class Plugin extends \RainLoop\Plugins\AbstractPlugin
{
public function __construct();
/** Returns static::NAME */
public function Name(): string;
/** Returns /README file contents or static::DESCRIPTION */
public function Description(): string;
/** When $bLangs is boolean it sets the value, else returns current value */
public function UseLangs(?bool $bLangs = null): bool;
/** When true the result is empty string, else the error message */
public function Supported(): string;
/** Initialize settings */
public function Init(): void;
public function FilterAppDataPluginSection(bool $bAdmin, bool $bAuth, array &$aConfig): void;
/** Returns array of all plugin Property options for use in Admin -> Extensions -> Plugin cog wheel */
protected function configMapping(): array;
/** With this function you hook to an event
* $sHookName see chapter "Hooks" below for available names
* $sFunctionName the name of a function in this class
*/
final protected function addHook(string $sHookName, string $sFunctionName): self;
final protected function addCss(string $sFile, bool $bAdminScope = false): self;
final protected function addJs(string $sFile, bool $bAdminScope = false): self;
final protected function addTemplate(string $sFile, bool $bAdminScope = false): self;
final protected function addJsonHook(string $sActionName, string $sFunctionName): self;
/**
* You may register your own service actions.
* Url is like /?{actionname}/etc.
* Predefined actions of \RainLoop\ServiceActions that can't be registered are:
* - admin
* - AdminAppData
* - AppData
* - Append
* - Backup
* - BadBrowser
* - CspReport
* - Css
* - Json
* - Lang
* - Mailto
* - NoCookie
* - NoScript
* - Ping
* - Plugins
* - ProxyExternal
* - Raw
* - Sso
* - Upload
* - UploadBackground
* - UploadContacts
*/
final protected function addPartHook(string $sActionName, string $sFunctionName): self
final public function Config(): \RainLoop\Config\Plugin;
final public function Manager(): \RainLoop\Plugins\Manager;
final public function Path(): string;
final public function ConfigMap(bool $flatten = false): array;
/**
* Returns result of Actions->DefaultResponse($sFunctionName, $mData) or json_encode($mData)
*/
final protected function jsonResponse(string $sFunctionName, $mData): mixed;
final public function jsonParam(string $sKey, $mDefault = null): mixed;
final public function getUserSettings(): array;
final public function saveUserSettings(array $aSettings): bool;
}
JavaScript
class PluginPopupView extends rl.pluginPopupView
{
// Happens when DOM is created
onBuild(dom) {}
// Happens before showModal()
beforeShow(...params) {}
// Happens after showModal()
onShow(...params) {}
// Happens after showModal() animation transitionend
afterShow() {}
// Happens when user hits Escape or Close key
// return false to prevent closing, use close() manually
onClose() {}
// Happens before animation transitionend
onHide() {}
// Happens after animation transitionend
afterHide() {}
}
PluginPopupView.showModal();
Hooks
$Plugin->addHook('hook.name', 'functionName');
Login
login.credentials.step-1
params:
string &$sEmail
login.credentials.step-2
params:
string &$sEmail
string &$sPassword
login.credentials
params:
string &$sEmail
string &$sImapUser
string &$sPassword
string &$sSmtpUser
login.success
params:
\RainLoop\Model\MainAccount $oAccount
IMAP
imap.before-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
imap.after-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
imap.before-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
\MailSo\Imap\Settings $oSettings
imap.after-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Imap\ImapClient $oImapClient
bool $bSuccess
\MailSo\Imap\Settings $oSettings
imap.message-headers
params:
array &$aHeaders
Allows you to fetch more MIME headers for messages.
Sieve
sieve.before-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
sieve.after-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
sieve.before-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
\MailSo\Sieve\Settings $oSettings
sieve.after-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Sieve\SieveClient $oSieveClient
bool $bSuccess
\MailSo\Sieve\Settings $oSettings
SMTP
smtp.before-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
smtp.after-connect
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
smtp.before-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
\MailSo\Smtp\Settings $oSettings
smtp.after-login
params:
\RainLoop\Model\Account $oAccount
\MailSo\Smtp\SmtpClient $oSmtpClient
bool $bSuccess
\MailSo\Smtp\Settings $oSettings
Json service actions
Called by RainLoop\ServiceActions::ServiceJson() {actionname} is one of the RainLoop\Actions::Do{ActionName}(), or an extension action as "Plugin{ActionName}" added with Plugin::addJsonHook() and called in JavaScript using rl.pluginRemoteRequest().
json.before-{actionname}
params: none
json.after-{actionname}
params:
array &$aResponse
json.action-post-call
Obsolete, use json.after-{actionname}
json.action-pre-call
Obsolete, use json.before-{actionname}
filter.json-response
Obsolete, use json.after-{actionname}
Others
filter.account
params:
\RainLoop\Model\Account $oAccount
filter.action-params
params:
string $sMethodName
array &$aCurrentActionParams
filter.app-data
params:
bool $bAdmin
array &$aAppData
filter.application-config
params:
\RainLoop\Config\Application $oConfig
filter.build-message
params:
\MailSo\Mime\Message $oMessage
Happens before send/save message
filter.build-read-receipt-message
params:
\MailSo\Mime\Message $oMessage
\RainLoop\Model\Account $oAccount
filter.domain
params:
\RainLoop\Model\Domain $oDomain
filter.fabrica
params:
string $sName
mixed &$mResult
\RainLoop\Model\Account $oAccount
filter.http-paths
params:
array &$aPaths
filter.language
params:
string &$sLanguage
bool $bAdmin
Allows you to set a different language
filter.message-html
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sTextConverted
Happens before send/save message
filter.message-plain
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sTextConverted
Happens before send/save message
filter.message-rcpt
Called by DoSendMessage and DoSendReadReceiptMessage
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\EmailCollection $oRcpt
filter.read-receipt-message-plain
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sText
filter.result-message
params:
\MailSo\Mime\Message $oMessage
Happens when reading message
filter.save-message
params:
\MailSo\Mime\Message $oMessage
Happens before save message
filter.send-message
params:
\MailSo\Mime\Message $oMessage
Happens before send message
filter.send-message-stream
params:
\RainLoop\Model\Account $oAccount
resource &$rMessageStream
int &$iMessageStreamSize
filter.send-read-receipt-message
params:
\MailSo\Mime\Message $oMessage
\RainLoop\Model\Account $oAccount
filter.smtp-from
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
string &$sFrom
filter.smtp-hidden-rcpt
params:
\RainLoop\Model\Account $oAccount
\MailSo\Mime\Message $oMessage
array &$aHiddenRcpt
filter.smtp-message-stream
Called by DoSendMessage and DoSendReadReceiptMessage
params:
\RainLoop\Model\Account $oAccount
resource &$rMessageStream
int &$iMessageStreamSize
filter.upload-response
params:
array &$aResponse
json.attachments
params:
\SnappyMail\AttachmentsAction $oData
json.suggestions-input-parameters
params:
string &$sQuery
int &$iLimit
\RainLoop\Model\Account $oAccount
main.content-security-policy
params:
\SnappyMail\HTTP\CSP $oCSP
Allows you to edit the policy, like:
`$oCSP->script[] = "'strict-dynamic'";`
main.default-response
Obsolete, use json.after-{actionname}
main.default-response-data
Obsolete, use json.after-{actionname}
main.default-response-error-data
Obsolete, use json.after-{actionname}
main.fabrica
params:
string $sName
mixed &$mResult
JavaScript Events
mailbox
mailbox.inbox-unread-count
mailbox.message-list.selector.go-up
mailbox.message-list.selector.go-down
mailbox.message.show
Use to show a specific message.
dispatchEvent(
new CustomEvent(
'mailbox.message.show',
{
detail: {
folder: 'INBOX',
uid: 1
},
cancelable: false
}
)
);
audio
audio.start
audio.stop
audio.api.stop
Misc
rl-layout
event.detail value is one of:
0. NoPreview
1. SidePreview
2. BottomPreview
rl-view-model.create
event.detail = the ViewModel class
Happens immediately after the ViewModel constructor.
See accessible properties as https://github.com/the-djmaze/snappymail/blob/master/dev/Knoin/AbstractViews.js
rl-view-model
event.detail = the ViewModel class
Happens after the full build (vm.onBuild()) and contains viewModelDom
rl-vm-visible
event.detail = the ViewModel class
Happens after the model is made visible (vm.afterShow())
sm-admin-login
event.detail = FormData
cancelable using preventDefault()
sm-admin-login-response
event.detail = { error: int, data: {JSON response} }
sm-user-login
event.detail = FormData
cancelable using preventDefault()
sm-user-login-response
event.detail = { error: int, data: {JSON response} }
sm-show-screen
event.detail = 'screenname'
cancelable using preventDefault()
squire-toolbar
event.detail = { squire: SquireUI, actions: object }
`actions` is the toolbar structure.
```javascript
block-of-buttons: {
button-name: {
select: ['selectbox options'],
html: 'button text',
cmd: () => `command to execute`,
key: 'keyboard shortcut',
matches: 'HTML elements that match'
}
}
```
See [SquireUI.js](https://github.com/the-djmaze/snappymail/blob/master/dev/External/SquireUI.js)
for all default toolbar actions.
JavaScript rl
object
rl.Enums.StorageResultType
rl.Enums.StorageResultType.Abort
rl.Enums.StorageResultType.Error
rl.Enums.StorageResultType.Success
rl.Utils.htmlToPlain(html)
Converts HTML to text
rl.Utils.plainToHtml(plain)
Converts text to HTML
rl.addSettingsViewModel(SettingsViewModelClass, template, labelName, route)
Examples in
- ./change-password/js/ChangePasswordUserSettings.js
- ./example/js/ExampleUserSettings.js
- ./kolab/js/settings.js
- ./two-factor-auth/js/TwoFactorAuthSettings.js
rl.addSettingsViewModelForAdmin(SettingsViewModelClass, template, labelName, route)
Examples in
- ./example/js/ExampleAdminSettings.js:34: rl.addSettingsViewModelForAdmin(ExampleAdminSettings, 'ExampleAdminSettingsTab',
rl.adminArea()
Returns true or false when in '?admin' area
rl.app.Remote.abort(action)
rl.app.Remote.get(action, url)
rl.app.Remote.getPublicKey(fCallback)
rl.app.Remote.post(action, fTrigger, params, timeOut)
rl.app.Remote.request(action, fCallback, params, iTimeout, sGetAdd)
rl.app.Remote.setTrigger(trigger, value)
rl.app.Remote.streamPerLine(fCallback, sGetAdd, postData)
rl.app.folderList
A knockout observable array of all folders/mailboxes
rl.fetch(resource, init, postData)
rl.fetchJSON(resource, init, postData)
rl.i18n(key, valueList, defaulValue)
rl.loadScript(src)
rl.logoutReload(url)
rl.pluginPopupView
class AbstractViewPopup