Extension:ContactManager
![]() Release status: stableCategory:Stable extensions |
|
---|---|
Implementation | HookCategory:Hook extensions, Special pageCategory:Special page extensions |
Description | A complete email client, contact manager and bulk email app for MediaWiki based on VisualData |
Author(s) | thomas-topway-it (thomas-topway-ittalk) |
Latest version | 1.2.5 (2025-06-07) |
MediaWiki | 1.35.3+Category:Extensions with manual MediaWiki version |
License | GNU General Public License 2.0 or later |
Download | Category:Extensions in Wikimedia version control |
Example | demo |
|
|
|
|
|
|
Quarterly downloads | 0 |
Translate the ContactManager extension if it is available at translatewiki.net | |
Issues | Open tasks · Report a bug |
ContactManager is a complete webmail based on MediaWiki and VisualData . Thanks to the flexibility of MediaWiki, the power of json-schema and the modularity of VisualData, it also aims to function as Contact manager (hence the name), and email marketing software, comparable to Mailchimp or MailUP.
ContactManager is also the first wiki-application based on VisualData, and as such represents both a test and a demo of its advanced features, like forms with preload-data, navigation using the parser function queryLink, TinyMCE integration, queries in form inputs (case insensitive), printouts with base64 modifier, form fields interactively shown based on conditions, form buttons, and much more. Of course it also competes with efforts in creating web-applications based on SemanticMediaWiki and PageForms, like SemanticActions or Eikolo and aims to introduce some advancement or contributions for this challenge.
Key-features:
- multiple mailboxes (IMAP and SMTP)
- all IMAP search criteria supported
- email filters (all email metadata supported)
- multiple mailers (all mailers supported by Symfony are supported: smtp, sendmail, native, Amazon SES, Mandrill, Mailgun, Mailjet, OhMySMTP, Postmark, SendGrid, Sendinblue)
- automatically retrieves contacts from sent/received email
- automatically create conversations from sent/received email (based on the email recipients, not subjects)
- can send email to categories of contacts, with substitutions
- Twig templates
- autocomplete
to
,cc
andbcc
using standard VisualData form queries - fully configurable using VisualData's schemas, templates and Mediawiki articles
- TinyMCE integration
see a demo here -- send an email to info at wikisphere.org and see how it works
UI elements
After the installation the extension creates the following links in the sidepanel:
Installation
- install PHP-Imap on your server. This on ubuntu is done with the command
sudo apt install php7.1-imap
(replace "7.1" with your php version)
- install Extension:VisualData#Installation following the related instructions.
- Download ContactManager and place the file(s) in a directory called
ContactManager
in yourextensions/
folder. - Run
composer update --no-dev
in the extension's folder, to install the required PHP libraries - Add the following code at the bottom of your LocalSettings.php
wfLoadExtension( 'ContactManager' );
- Run
php ./extensions/ContactManager/maintenance/ImportData.php
(this will import on the wiki the articles in theContactMananger
namespace, templates and schemas required by the extension) Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.
![]() | This extension requires VisualData 1.0.9+, Extension:UrlGetParameters and Extension:Tabs (Extension:SubpageNavigation is also recommended) |
Install the following extensions:
- Extension:UrlGetParameters
- Extension:Tabs or Extension:TabberNeue (recommended: download Extension:Tabs from here or here)
- Extension:TemplateStyles
Enable StringFunctions:
$wgPFEnableStringFunctions = true;
The basic configuration should appear as follows:
wfLoadExtension( 'VisualData' ); // wfLoadExtension( 'TabberNeue' ); // $wgTabberNeueEnableAnimation = false; wfLoadExtension( 'Tabs' ); wfLoadExtension( 'UrlGetParameters' ); wfLoadExtension( 'TemplateStyles' ); wfLoadExtension( 'ContactManager' ); $wgVisualDataEditDataNamespaces = [ 0, 4, 2226, 2230, 2260 ]; $wgNamespacesWithSubpages[2260] = true; $wgPFEnableStringFunctions = true; // *** disable display of sub-pages which can be too expensive $wgSubpageNavigationDisablePaths = [ 'ContactManager:Mailboxes', 'ContactManager:Contacts', ];
Create two entries in the crontab file as follows:
* * * * * php www-data $IP/maintenance/run.php "$IP/extensions/ContactManager/maintenance/CheckMessages.php" > /dev/null 2>&1 * * * * * php www-data $IP/maintenance/runJobs.php --type ContactManagerJob --memory-limit default >> $IP/ContactManagerJob.log 2>&1
(this assumes that the username of the webserver is "www-data" and it can execute the related files, replace $IP with the absolute path of your mediawiki install)
The first script creates the jobs to check for new email messages if are due, and the second executes the queued jobs each minute.
Here is a tutorial to manage crontabs.
In order to create a crontab for a specific user (i.e. "www-data") use the following command:
sudo crontab -e -u www-data
In this case the entries in the crontab should appear as follows:
* * * * * php $IP/maintenance/run.php "$IP/extensions/ContactManager/maintenance/CheckMessages.php" > /dev/null 2>&1 * * * * * php $IP/maintenance/runJobs.php --type ContactManagerJob --memory-limit default >> $IP/ContactManagerJob.log /dev/null 2>&1
(replace $IP with the absolute path of your mediawiki install)
(Optional but recommended) Ensure that the MediaWiki install path is owned by the webserver (Apache2 on Ubuntu)
sudo chown www-data:www-data $IP -R
(replace $IP with the absolute path of your mediawiki install)
Grant execute permission to the file owner: (set to 777 if you skipped the previous step)
sudo chmod 755 $IP/extensions/ContactManager/maintenance/CheckMessages.php
(replace $IP with the absolute path of your mediawiki install)
Create a directory named ContactManagerFiles
under the MW install path or specify another path using the parameter $wgContactManagerAttachmentsFolder
in LocalSettings. Grant the webserver permission to modify it, using:
sudo chown www-data:www-data $IP/ContactManagerFiles
(replace $IP with the absolute path of your mediawiki install)
This will ensure that attachments, if enabled, can be saved and handled by the extension.
Recommended: ensure that mysqld restarts on failure
sudo mkdir -p /etc/systemd/system/mariadb.service.d sudo vi /etc/systemd/system/mariadb.service.d/override.conf
then add:
[Service] Restart=on-failure RestartSec=5s
and run:
sudo systemctl daemon-reload sudo systemctl edit mariadb
Workflow
The extension creates a set of pages in the ContactManager
namespace (plus a number of templates with the "ContactManager/" prefix) by which to create/edit mailboxes, add mailers, manage messages, message headers, jobs, conversations and contacts for each mailbox, send messages, and navigate all the articles, schemas, templates and modules created by the extension.
Here is all you need to have a full-fledged "knowledge-webmail" up & running in few minutes.
1) Create a mailbox
Create a mailbox in the page "ContactManager:Mailboxes"
Just insert the desired name for the mailbox and a list of legitimate email addresses in the form "name <email>" (or just email), as well as the reply-to field.
After creating a mailbox the app redirects you to the following page:
This is the main control-panel for each mailbox, by which you can manage jobs, view/update mailbox info, folders, define rules to retrieve messages, read message headers and contents, manage conversations and contacts and compose messages.
2) Set mailbox credentials
Edit Manual:LocalSettings.php and create a key in the global parameter $wgContactManagerIMAP
(used to receive email) and $wgContactManagerSMTP
(used to send email), with the name of the created mailbox, as follows:
$wgContactManagerIMAP = [ 'mailbox_1' => [ 'server' => '', 'username' => '', 'password' => '', 'port' => 993, ], // ... ]; $wgContactManagerSMTP = [ 'mailbox_1' => [ 'server' => '', 'username' => '', 'password' => '', 'port' => 465 ], // ... ];
("mailbox_1" should be replaced with the name of the mailbox set in the first step)
Use PHP's getenv in order to store the password as environment variables for security reasons.
![]() | Note that some email providers, like gmail and yahoo, require to create an app-password to be used instead of your regular password. Find out more |
![]() | Attention Despite gmail's app password is shown with spaces after creation, it must be entered in the configuration object without, otherwise won't work !! |
3) Define jobs
Press the buttons "Get mailbox info" and "Get folders" as shown below.
Note that each button is composed by the edit button on the right and the main button on the left. The first sets the button properties, and the second activates it. The first 2 buttons should be pre-filled with the mailbox name and job name, so you can activate both of them immediately. If crontab has been set correctly as shown in the install instructions, they will be executed and completed within 1-3 minutes.
By contrast, if crontab has not been set, you need to execute the following command from the command line
php maintenance/runJobs.php --type ContactManagerJob --memory-limit -1
Once that the list of folders has been retrieved from the mailbox and stored in the json-data associated to the article, press the edit button besides the primary button "Get messages", in order to set-up the related properties.
The form allows to define which folders to download from the mailbox, the local folder name, the search criteria for each folder, whether or not to retrieve message contents, the fetch method (search criteria, or by UIDs) to assign categories, check messages each n minutes, set an arbitrary number of filters for both header and messages, with related actions, and more !
It is recommended to first search messages since a specific date (for instance the last calendar year, using fetch
search
) and once done set fetch
UIDs incremental
and check email every
10 minutes) to keep your knowledge-mailbox constantly updated !!
In the first case is necessary to activate the job by pressing the main button ("Get messages") after saving the properties. In the second case is not necessary to activate the job each time since it's created each n minutes by the maintenance script activated by crontab.
All the IMAP search criteria are supported and accessible/editable through the form, for each separate folder.
- ALL
- ANSWERED
- BCC
- BEFORE
- BODY
- CC
- DELETED
- FLAGGED
- FROM
- KEYWORD
- NEW
- OLD
- ON
- RECENT
- SEEN
- SINCE
- SUBJECT
- TEXT
- TO
- UNANSWERED
- UNDELETED
- UNFLAGGED
- UNKEYWORD
- UNSEEN
An arbitrary number of filters for both headers and messages can be also set through the form in order to skip the matched messages based on a specific condition, save them to a specific path or assign one or more categories. Regexes are supported for text fields, date inputs for date fields and numeric inputs for numeric fields.
Supported filters for headers
- subject
- from
- to
- date
- message_id
- references
- in_reply_to
- size
- uid
- msgno
- recent
- flagged
- answered
- deleted
- seen
- draft
- udate
Supported filters for messages:
- id
- imapPath
- mailboxFolder
- isSeen
- isAnswered
- isRecent
- isFlagged
- isDeleted
- isDraft
- date
- headersRaw
- headers/date
- headers/Date
- headers/subject
- headers/Subject
- headers/message_id
- headers/toaddress
- headers/fromaddress
- headers/ccaddress
- headers/reply_toaddress
- headers/senderaddress
- mimeVersion
- xVirusScanned
- organization
- contentType
- xMailer
- contentLanguage
- xSenderIp
- priority
- importance
- sensitivity
- autoSubmitted
- precedence
- failedRecipients
- subject
- fromHost
- fromName
- fromAddress
- senderHost
- senderName
- senderAddress
- xOriginalTo
- toString
- ccString
- messageId
- textPlain
- textHtml
- visibleText
- attachments/id
- attachments/contentId
- attachments/type
- attachments/encoding
- attachments/subtype
- attachments/description
- attachments/name
- attachments/sizeInBytes
- attachments/disposition
- attachments/charset
- attachments/emlOrigin
- attachments/fileInfoRaw
- attachments/fileInfo
- attachments/mime
- attachments/mimeEncoding
- attachments/fileExtension
- attachments/mimeType
4) Manage mailbox
After defining the rules to retrieve messages, activating the job by pressing the main/left side of the button, and retrieving them either executing the job by command line or through crontab, the mailbox overview page will be filled interactively with retrieved headers, messages, conversations, and contacts !
Here is how it appears after a few minutes:
![]() | Despite retrieving even thousands of email headers takes only a few minutes, retrieving email contents may take many hours depending on the mailbox size and criteria/filters used |
While conversations, contacts and messages are being retrieved, you can immediately categorize contacts in order to bulk-send email messages to categories, also with substitutions, and manage them as better fits your needs.
The contact page of a recipient is accessible from the following tables or pages:
- conversations
- read email (field from)
- contacts
A contact page looks as follows, to edit it press the "Edit" button as in the picture, then press "validate" and add one or more categories:
This page is created automatically by the extension based on the received and sent contacts, completed with parsed name, first and last seen dates, languages, and more.
5) Create additional mailers
A "mailer" is a program that sends email messages, that can either reside on the server (like sendmail) or be provided as a SaaS, like SendGrid, mailgun and more. Thanks to the integration with symfony mailer, ContactManager supports all the providers supported by Symfony. They can be used to send bulk email messages and they support natively templates and substitutions.
In order to create an additional mailer (either sendmail or one of the third party providers) go the page "ContactManager:Mailers", choose the provider, and assign to it a name using the following form.
Once created the page shows an editable table:
6) Set-up the credentials for the created mailer
Each mailer can use SMTP, HTTP and/or API transport, and requires its specific set of credentials, according to the following table.
Provider | SMTP | HTTP | API |
---|---|---|---|
Amazon SES | username/password | access_key/secret_key | access_key/secret_ke |
Gmail | username/app-password | n/a | n/a |
Mandrill | username/password | KEY | KEY |
Mailgun | username/password | KEY/DOMAIN | KEY/DOMAIN |
Mailjet | access_key/secret_key | n/a | access_key/secret_key |
Postmark | ID | n/a | KEY |
Sendgrid | KEY | n/a | KEY |
Sendinblue | username/password | n/a | KEY |
OhMySMTP | API_TOKEN | n/a | API_TOKEN |
(source: https://symfony.com/doc/5.x/mailer.html)
Correspondingly, ContactManager will search an object in LocalSettings.php
with the following structure.
$wgContactManagerAMAZON = [ 'mailer_1' => [ 'smtp' => [ 'username' => '', 'password' => '' ], 'http' => [ 'access_key' => '', 'secret_key' => '' ], 'api' => [ 'access_key' => '', 'secret_key' => '' ] ], // ... ]; // ... $wgContactManagerSENDGRID = [ 'mailer_2' => [ 'smtp' => [ 'username' => '', 'password' => '', ], 'api' => [ 'KEY' => '', ] ], // ... ];
where $wgContactManagerAMAZON
is the name of the global parameter composed with uppercase name of the provider as suffix, "mailer_n" is the chosen provider name, and the required keys reflect the table above for each provider and transport.
Therefore the approach is to use an object for each provider, each of them containing one or more accounts, for better readability compared to using a single object for all of them.
![]() | Attention currently substitutions of the properties of the recipient's schema are only supported using SendGrid |
7) Bulk-send email to conversation's recipients or categorized contacts
Go to the page ContactManager:Compose
, select a mailbox and enter a test category (with articles corresponding to ContactManager's contacts, as explained in the 4th step, or with any VisualData's schema which includes a property of type email) in the "bcc categories" field.
The form, shown below, allows to:
- send email using different mailers
- select the from field among those registered under each mailer
- select existing recipients as to, cc, and bcc, with auto-complete, and add new recipients
- send to categories of contacts
- exclude specific recipients from a category
- select between plain-text and html (plain-text will be encapsulated in a Twig template, by contrast to html)
- select a Twig template (if content-type is text)
- add attachments (not yet tested or fully implemented)
- set offset and limit when sending to large amount of recipients
Substitutions, in the form %first_name%
(based on the schema associated to each recipient) are allowed only using a mailer (currently sendgrid) since they are performed after sending the email, to avoid to send from the MediaWiki server one email for each recipient. For the same reason, substitutions of schema properties are not allowed in the Twig template, which is used as a common envelope for the body content.
The same form is also used as a popup when answering from the Inbox or sending email to the participants of a conversation !
Rights and privileges
Groups
The extension creates the following groups: (they are assignable to users through the standard special page Special:UserRights). Only users within these groups can create ContactManager's jobs, and see the UI links in the side panel. However, this does not prevent to access the relevant pages and the ContactManager namespace. If you need to protect them use Extension:PageOwnership.
group | description |
---|---|
contactmanager-admin | let users to manage mailboxes |
The extension creates the following user rights.
right | description |
---|---|
contactmanager-can-manage-mailboxes | Can manage mailboxes |
Group rights
group | contactmanager-can-manage-mailboxes |
---|---|
sysop | v |
bureaucrat | v |
contactmanager-admin | v |
Known issues
- attachments are only partially implemented
Road map
- webhooks to record email tracking (when used with mailers)
- implement/complete implementation of attachments
- Twilio integration
Support & bugs
For professional support please write at the email address posted here