Search by

commercekings / module-notification

commercekings

Notification subscriptions (opt-out on their own, consent-based with commercekings/module-consent-notification) and shared email delivery for CommerceKings modules in Magento 2: one subscribe endpoint, guest contacts, one message queue consumer, optional recipient cooldown, store-emulated sending an

Package info

github.com/commercekings/module-notification

Type:magento2-module

pkg:composer/commercekings/module-notification

Statistics

Installs: 9

Dependents: 7

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.1 2026-10-20 21:55 UTC

This package is auto-updated.

Last update: 2026-10-20 21:56:38 UTC


README

Works with Magento 2.4.4+ · Luma and Hyvä · PHP 8.1–8.5 · RabbitMQ or MySQL queue

License Release Checks

Thousands of notifications a minute or a handful a day – your store never slows down.

  • Fast storefront. Every notification is sent in the background by a queue consumer, never during a page view. Optional shopper subscriptions are one quick write.
  • Marketing and service messages. Reminders shoppers opt into, or order and staff messages that need no subscription.
  • Email, SMS, WhatsApp, Viber. Email built in; a provider module adds a messaging service. Phone numbers, consent for a number (a checkbox, stored as evidence), STOP replies and quiet hours are part of Notification.
  • Inbox-ready at volume. Optional RFC 8058 one-click unsubscribe, as Gmail and Yahoo require from bulk senders.
  • Do not contact. One click in a marketing email (or a STOP reply) stops all marketing to that address on that channel (a STOP to the SMS number doesn't stop email), whoever signs them up again; order messages still arrive.
  • Quiet hours. Marketing is held at night (on by default for texts, 20:00–08:00) and sent after – in the store's time zone, or the recipient's.
  • Scales with you. Add consumers when traffic grows; RabbitMQ or Magento's MySQL queue.
  • Private by default. Cooldown, stops and consents keep keyed hashes, never addresses; unused contacts are removed.

A feature (e.g. abandoned cart) says what and when; Notification handles who and how.

Provider modules: Twilio, Infobip · Features: Abandoned Cart (+ SMS)

The model

  • A notification type is one kind of message, registered by a feature. It decides when to send and builds the content.
  • A subscription is a shopper's sign-up for a type, e.g. reminders for one cart. Marketing types need one; service messages don't. Its address is a contact (one per website, channel and address) or, on email types, a customer's account email.
  • A permission decides who may subscribe: everyone (opt-out), only with consent (opt-in, with the privacy bundle), or – per type – an address consent: a checkbox for one number. The subscriber provides the unsubscribe link.
  • The queue carries <type>|<reference>. One consumer sends every type, so nothing is sent during a page view.
  • The delivery state keeps each feature's send history per type and reference, e.g. per cart and reminder type (sent, queued, retries), so a new sign-up does not send twice.
  • The sender checks a delivery against Do not contact, quiet hours and the cooldown, builds its content in the store's language, then hands it to a provider.
  • A channel is where a delivery goes: email, SMS, WhatsApp, Viber, or a code a provider module brings. A normalizer gives each channel one recipient form; SMS, WhatsApp and Viber numbers are E.164.
  • A provider delivers on one channel, chosen in the admin when there are several. Magento email is built in. Install one provider module per channel: recipient time zones and opt-in confirmations are per module.

Installation

Usually a feature brings it. On its own:

composer require commercekings/module-notification:^0.1
bin/magento setup:upgrade

Alone it runs opt-out: a subscription stays until it is removed, and features show their notice. Add commercekings/privacy-bundle for opt-in: a subscription then needs a consent for the feature's purpose, withdrawing it removes the subscription, and notices are off by default. Text messages are always opt-in: a type with an address consent needs the number's checkbox in either setup.

Settings

Stores > Configuration > CommerceKings > Notifications:

Group Fields (default)
Delivery Provider per channel (Magento email); Cooldown in days (7, global, 0 = off); One-click unsubscribe (No)
Do not contact "Stop these emails" link (Yes; always on in opt-out mode); Lifts after days without attempts (90)
Quiet hours Enabled (Yes); From – To (20:00 – 08:00, may cross midnight); Channels (all but email)
Consent for an address Checkbox text for text messages, WhatsApp and Viber, per store view; Keep withdrawn consents (1825 days)

Before going live

  • Run the consumer commerceKingsNotificationSend with --max-messages=1000 and restart it after each deployment.
  • Recommended: rate-limit the anonymous routes POST /rest/<store>/V1/ck-notification/subscriptions and …/address-consents per IP (e.g. 10 a minute) in your web server, proxy or CDN, and optionally with commercekings/module-rate-limit. Without one, a script can make the shop message any address – a paid text to any number – up to the feature's hourly cap.

Details: operations.

Extending

Types work with or without subscriptions: with them for messages shoppers sign up for, without for service messages and staff alerts. The public API (@api):

For Use
A notification type Api\NotificationTypeInterface (Model\TypePool "types"), Api\QueueInterface, Api\SenderInterface with Data\Delivery
Its send history Api\DeliveryStateInterface
Sign-ups Api\SubscriptionTypeInterface (Model\SubscriptionTypePool "types"), Api\SubscriptionManagementInterface and its commercekings_notification_subscription_saved event, Api\SubscriptionRepositoryInterface, Api\SubscriptionGuardInterface, Api\SubscriptionRemovalInterface
Who may subscribe Api\SubscriptionPermissionInterface, Api\SubscriberInterface; per type Model\TypePermission, Model\TypeSubscriber, Model\AddressConsent (virtual types)
A checkbox consent Api\AddressConsentManagementInterface, address-consent.phtml with ViewModel\AddressConsent
A channel or service Api\ProviderInterface (Model\ProviderPool "providers"), Api\RecipientNormalizerInterface (Model\RecipientNormalizerPool "normalizers"), Model\Config\Source\Provider (virtual type "channel"), Model\KeyedHash
Replies and timing Api\StopListInterface, Api\QuietHoursInterface, Api\QuietHoursZoneInterface (Model\QuietHours "zones"), Api\CooldownInterface
Housekeeping and UI Api\ContactReferenceInterface (Model\ContactReferencePool "references"), Api\OptOutNoticeInterface

How to use them, including messaging for provider modules: for module authors.

Limitations

  • A failed send is not retried by Notification; the feature decides (abandoned cart queues the cart again).
  • Quiet hours have one window per store view for all selected channels.
  • Stops, stop links, consents and the cooldown are keyed with Magento's encryption key. After encryption:key:change nothing needs to be run while the old key stays in env.php; the cooldown restarts (details).

Tested (as of 0.1.0)

  • Automated tests: 252 unit, 31 integration and 16 JavaScript tests (unit and JavaScript tests run on every push).
  • Line coverage: 93.8% with unit and integration tests combined.
  • End to end on Magento 2.4.9: email reminders through Magento's mail (caught by a test mail server), with RabbitMQ and with the MySQL queue; SMS and WhatsApp against a simulated Twilio API – opt-in confirmation, STOP and START, quiet hours, provider errors and timeouts.
  • Load: 100,000 abandoned carts through the sender, about 3 messages a second per worker, growing linearly, none sent twice; 300 of 300 texts delivered to a simulated provider.
  • Install: a fresh install of every CommerceKings package from GitHub on an empty Magento database, verified.
  • Not tested: a STOP reply from a real phone (STOP is tested with the providers' webhook formats).

More

How it works · For module authors · Operations · Stop list · Compatibility · Changes

Disclaimer

These modules help you ask for, record and respect your shoppers' choices – they don't make your store compliant on their own. You are responsible for your store's privacy: what you collect, the wording you show, your privacy policy and whether your setup meets the laws that apply to you (e.g. GDPR, ePrivacy, email and SMS marketing rules). Get legal advice if you are unsure.

Need it installed, set up or customized? Get in touch →