Install and enable
Activating MailWizard — the licence step, the three tables, the fifteen permission keys, the hourly cron job, the mail transport it depends on, and a smoke test that proves a campaign really sends.
Activation is a few minutes of clicking and one command on the server. The part that actually decides whether campaigns send is the mail configuration underneath it, and that is not something MailWizard checks or reports on. Work through this page in order and finish with the smoke test — a MailWizard install that is broken looks exactly like one that is working until an operator notices a campaign has been Active for six hours with zero recipients sent.
Before you activate
- Bicrypto core installed and running — see Installing Bicrypto
- Outbound mail works: a password-reset email from your install arrives in a real inbox
- The
cronPM2 app is running — campaigns are sent by a scheduled job and nothing else - Redis reachable, because the cron scheduler runs on BullMQ
- The MailWizard purchase code from your MashDiv dashboard to hand
- A shell on the server — installing the release ends with one command run there
The mail check is the one people skip. MailWizard does not own a transport, a queue or a sending domain — it calls the platform's mailer. If that is misconfigured, every recipient on every campaign fails, and the only place the reason appears is the cron log.
Activation
The order is fixed: activate the licence, install the release, apply it, then
switch it on. The switch on the MailWizard card stays disabled until the licence
is activated, and nothing Install downloads takes effect until pnpm updator
has run.
-
Open the Extension Manager — Admin → System → Extension Manager, at
/admin/system/extension. On the Extensions tab, or by searching for MailWizard, find the MailWizard card — product ID45613491— and click it. Until its licence is activated the card reads Activate and its switch is disabled, with the tooltip Activate license first.- The MailWizard card — click it to open the product page
- Its switch stays disabled until the licence is activated
-
Activate the licence — the product page shows a License Required chip; press Activate License. Paste the purchase code from your MashDiv dashboard, optionally an email address for update notifications, and press Activate License. The screen confirms License Activated! and returns you to the product page a couple of seconds later. If the server has no outbound access, the License File tab on the same screen takes the licence certificate downloaded from your MashDiv dashboard instead.
- Paste the purchase code here
- Activate License — then wait for the redirect back to the product page
- The offline route, for a server with no outbound HTTPS
-
Install the release — back on the product page, now licensed, the Overview tab has a release panel. If it offers Install v…, press it; if it says Up to date on a product you have only just licensed, press Check for Updates once, then install whatever it offers. The Releases tab holds the notes for the version being offered — read them first.
Install downloads the release, verifies it and extracts it over the project root. It runs no migrations, builds nothing and restarts nothing, so finish it from a shell on the server:
pnpm updatorThat is the finalise chain — stop, dependencies, schema, seed data, frontend build, start — and it is what creates the three tables below and brings the
cronprocess back up on the new code. If the panel still says Up to date after the check there is nothing to download; go straight to the next step.- Check for Updates, then Install v… when it is offered
- Releases — the notes for the version you are about to install
- The Enabled switch — step 4, not yet
-
Switch it on — turn the Enabled switch on, in the product page heading or on the MailWizard card in the Extension Manager, which is usable now that the licence is verified. This is what puts Email Marketing in the admin navigation and hands
processMailwizardCampaignsto the scheduler, which picks it up within about a minute without a restart. The addon's internal name ismailwizard; that is the category its job sits under at/admin/system/cronand the name that appears in the cron log. -
Confirm the menu appears — Extensions → Business Tools → Email Marketing in the admin navigation, landing on
/admin/mailwizard/campaign. -
Confirm the addon's own header — the MailWizard screens carry their own three-item nav: Campaigns, Templates, Blocks.
Turning the Enabled switch off — on the product page, or on the MailWizard
card in the Extension Manager — stops the campaign cron within about a minute:
the scheduler re-checks which add-ons are enabled on a 60-second loop and
deregisters the job without a restart. Campaigns, templates and blocks are left
alone, so switching back on picks up exactly where you were, and the licence
stays in place, so it needs no reactivation. A campaign left ACTIVE when you
disable the addon simply stops progressing.
What activation creates
Three tables, created automatically by the model sync when pnpm updator runs
in step 3:
| Table | Holds |
|---|---|
mailwizard_template |
Templates: the exported HTML (content) and the editor's design JSON (design) |
mailwizard_block |
Reusable blocks: a name, an optional category, and one or more editor rows as JSON |
mailwizard_campaign |
Campaigns: name, subject, status, speed, template link, and the whole recipient list as a JSON string in targets |
All three are paranoid — deletes are soft — and all three keep their bodies in
TEXT('long') columns, because a single template with an inlined image passes
64 KB without difficulty.
The recipient list living inside the campaign row is the single most consequential design decision in this addon. It is why there is no per-recipient reporting, why the analytics screen cannot chart delivery, and why a campaign has a hard recipient ceiling. See Building and sending a campaign.
If you build from source, run pnpm types:generate once the tables exist.
Permissions
Fifteen keys are seeded — five actions across three objects. Assign them to roles
at /admin/crm/role; Super Admin holds them all automatically.
| Key | Grants |
|---|---|
access.mailwizard.campaign |
Opening the Campaigns screen and the addon's menu entry |
view.mailwizard.campaign |
Reading campaigns, including the recipient list |
create.mailwizard.campaign |
Creating a campaign |
edit.mailwizard.campaign |
Editing, changing status, updating targets, retrying failures |
delete.mailwizard.campaign |
Deleting campaigns, singly or in bulk |
access.mailwizard.template |
Opening the Templates screen |
view.mailwizard.template |
Reading templates, and the template dropdown on the campaign form |
create.mailwizard.template |
Creating and importing templates |
edit.mailwizard.template |
Saving from the visual editor |
delete.mailwizard.template |
Deleting templates |
access.mailwizard.block |
Opening the Blocks screen |
view.mailwizard.block |
Reading blocks, and the editor's Blocks panel |
create.mailwizard.block |
Creating a block, including Save as block in the template editor |
edit.mailwizard.block |
Editing a saved block |
delete.mailwizard.block |
Deleting blocks |
The Add Targets dialog reads the platform's own user list through
/api/admin/crm/user, which is gated by view.user — a core CRM permission, not
a MailWizard one. A role holding every key in the table above and not view.user
opens the picker to an empty list with no error, so the operator concludes there
are no users to email.
access.* keys gate the admin pages; the view / create / edit / delete
keys gate the API. Both matter: granting only the page key produces a screen
that loads and then reports permission errors on every request.
The one cron job
Check it at /admin/system/cron, category mailwizard.
| Job | Every | Does |
|---|---|---|
processMailwizardCampaigns |
60 minutes | Picks up every ACTIVE campaign and sends up to speed emails from each |
That is the entire sending mechanism. There is no queue worker, no second job and no other trigger — the Start button on a campaign only sets its status.
Scheduled jobs run in the cron PM2 app. If that process is stopped, crashed or
never started, every campaign sits at ACTIVE and 0% forever, and nothing in the
MailWizard screens says so. pm2 list is the check. See
Processes and ports.
The Campaigns screen has one indicator for this: the Stalled Sends figure
counts campaigns that are ACTIVE but have not been written to in over an hour.
On a healthy install that number is zero.
Mail transport
MailWizard sends through whichever transport APP_EMAILER selects. It does not
have settings of its own — there is no MailWizard settings screen.
nodemailer-service, nodemailer-smtp, nodemailer-sendgrid or local.The From address and sender name are also global, and there is no per-campaign override:
| Transport | From address comes from | Sender name comes from |
|---|---|---|
nodemailer-service |
APP_NODEMAILER_SERVICE_SENDER |
APP_EMAIL_SENDER_NAME, else NEXT_PUBLIC_SITE_NAME, else Support |
nodemailer-smtp |
NEXT_PUBLIC_APP_EMAIL if set, else APP_NODEMAILER_SMTP_SENDER |
same |
nodemailer-sendgrid |
APP_SENDGRID_SENDER |
same |
local |
NEXT_PUBLIC_APP_EMAIL, else no-reply@localhost |
same |
Two consequences worth planning for. First, every campaign appears to come from
the same address as your transactional email — a bounce storm on a marketing
send damages the reputation of the address your password resets go out on.
Second, DKIM signing configured through APP_NODEMAILER_DKIM_* only applies to
the local sendmail transport. On SMTP, service or SendGrid, signing is your
provider's job and must be set up in DNS.
The platform's global outbound kill switch is checked by the notification queue
and by the templated sendEmail path. The MailWizard send loop calls the mailer
directly and never consults it. Setting MAIL_DISABLED=true on a staging copy of
production silences the rest of the platform and leaves any ACTIVE campaign
sending real email to real customers.
Before restoring a production database onto a test box, set every campaign to
PENDING or CANCELLED — or switch MailWizard off in the Extension Manager
outright.
Smoke test
Prove the whole chain end to end before you point a campaign at real customers. Use your own mailbox as the only recipient.
-
Create a template — Templates → Create, name it
Smoke test, drop a text block onto the canvas with a recognisable sentence in it, and save. Reopen it from the list; the canvas should show what you built, not a blank page. -
Create a campaign — Campaigns → Create. Name and subject anything, pick the
Smoke testtemplate, set Emails per hour to1. -
Add exactly one recipient — click Add Targets, search for your own account by first name (the search matches first name only), tick it, and Add selected. Save the campaign.
-
Start it — on the campaign page press Start. The status becomes
ACTIVE. -
Run the job rather than waiting an hour — open
/admin/system/cron, findprocessMailwizardCampaignsunder themailwizardcategory and trigger it. -
Check the outcome — the recipient card should badge Sent, progress should read 100%, and the campaign status should be
COMPLETED. The email should be in your inbox.
If the recipient badges Failed, the reason is written onto the recipient card itself — that text comes straight from the mail transport and is almost always an authentication or connection error rather than anything to do with MailWizard. Troubleshooting works through the common ones.
Upgrading an existing install
Open the MailWizard product page from Admin → System → Extension Manager and press Install v… on its Overview tab — press Check for Updates first if the panel reads Up to date — then finish it from a shell on the server:
pnpm updatorThat restarts the backend and the cron process, so the campaign job and the
admin routes pick up the new build. Two things to check afterwards.
Re-save any template created with the visual editor before v6.1.0
The old create flow discarded the design and the HTML it was given and stored a
literal {} as the body, while reporting success. Every campaign using such a
template delivered an empty email. Editing always saved correctly, so opening the
template and saving once repairs it.
The Templates list flags these for you: a template whose design cannot be parsed carries an HTML only badge, and one with no body carries No content.
Recipient lists are size-checked from v6.1.0
Saving a campaign whose recipient list exceeds 10,000 characters is refused. Campaigns that already hold a longer list keep sending — only saving is blocked, which means you cannot edit them at all. Plan to split them before you need to change one.
New permissions are seeded on start. If you added roles between versions, revisit
/admin/crm/role after upgrading — the block permissions in particular did not
exist before v6.2.0, and a role without them sees an empty Blocks panel in the
editor.