Skip to main content

Synchronize Wix contacts and memberships to managed Listmonk lists.

Project description

wix-monk

wix-monk synchronizes Wix contacts and pricing-plan membership into selected Listmonk lists. It treats list eligibility and permission to email as separate decisions.

Preference rules

The synchronization is intentionally conservative:

  1. A Listmonk global blocklist is never cleared.
  2. A Listmonk list unsubscribe is never changed back to confirmed.
  3. A Wix UNSUBSCRIBED status unsubscribes existing managed memberships.
  4. Only explicit Wix SUBSCRIBED contacts are added as confirmed by default.
  5. Unknown consent or poor deliverability removes managed membership without recording a user unsubscribe.
  6. Eligibility changes remove only lists declared in the config. Other Listmonk lists and attributes are preserved.
  7. Subscribers previously sourced from Wix but no longer returned by Wix are removed from managed lists. Their subscriber record and unsubscribe history are retained.

This means an active paid membership can qualify a contact for a list, but it cannot override that person's communication preference.

Consent status handling defaults to allowing only SUBSCRIBED, denying UNSUBSCRIBED, and treating all other Wix statuses as unknown. It can be overridden globally with the top-level consent configuration or for one list with a list-level consent block. For example, to include Wix members whose status is NOT_SET without doing so for other lists:

{
  "name": "Members",
  "criteria": {"field": "is_member", "equals": true},
  "consent": {
    "subscribed_statuses": ["SUBSCRIBED", "NOT_SET"]
  }
}

An explicit UNSUBSCRIBED remains denied unless it is deliberately removed from unsubscribed_statuses. Existing Listmonk list unsubscribes and global blocklisting are always preserved.

Setup

Python 3.11 or newer is required. Install the project in a virtual environment:

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -e .

Copy config.example.json to config.json, then set the required environment variables:

export WIX_API_KEY='...'
export WIX_SITE_ID='...'
export LISTMONK_URL='https://listmonk.example.org'
export LISTMONK_USERNAME='...'
export LISTMONK_PASSWORD='...'

WIX_ACCOUNT_ID is optional. It is mostly there for possible future use or for Wix endpoints that require an account-level identifier. The current site-level sync and discovery calls use WIX_SITE_ID.

Run a dry-run first:

wix-monk sync --config config.json --dry-run

Run the sync interactively:

wix-monk sync --config config.json

Apply without prompting:

wix-monk sync --config config.json --yes

Missing configured lists are reported during a dry run and created when the sync is applied. They default to private, single opt-in lists tagged wix-monk. The optional config keys type, optin, description, and tags customize their creation. Existing lists with the same exact name are reused.

Dry-run and apply output include a section for each managed list with Wix eligibility and consent counts, planned membership changes, and current versus resulting confirmed membership.

All lists use the same declarative expression language. For nested all / any / not filters, supported fields and operators, regex matching, consent overrides, exact pricing-plan recipes, and report definitions, see FILTERING.md.

If you need a global contact filter, add a top-level criteria key in config.json. It is combined with every list-specific criteria expression.

To inspect live Wix values, list observed pricing plans, summarize members, audit duplicate member/contact records, test one expression, or create a reusable JSON snapshot, see DISCOVERY.md.

Filters can use normalized names, email addresses, phone numbers, address components, ZIP/postal codes, Wix labels, segments, locale, source type, membership state, and active pricing plans. An explicit snapshot --json --include-contacts export is available for authorized local inspection; the default snapshot remains aggregate-only.

Pricing-plan lists can be restricted by exact plan names:

{
  "name": "Annual civic league plans",
  "criteria": {
    "field": "active_plan_names",
    "contains_any": [
      "Annual Lago Mar Civic League Membership",
      "Civic League Annual Dues",
      "2025 Lago Mar Civic League Membership"
    ]
  }
}

Plan IDs are preferable for long-term configuration because a Wix plan can be renamed. Use the active_plan_ids field with contains, contains_any, or contains_all. Active plan IDs and names are written to the subscriber's Listmonk attributes.

A pricing-plan order counts as active when Wix reports ACTIVE, or when a CANCELED order remains usable until its future NEXT_PAYMENT_DATE end date. PENDING, PAUSED, DRAFT, and ENDED orders do not qualify.

Duplicate Wix contacts are merged by normalized email. Member-linked contacts take precedence for identity fields, any explicit Wix unsubscribe wins for consent, and orders are joined through both contact and member IDs. The merged Wix contact/member/order IDs and active plan names are retained as Listmonk attributes for auditing.

Development

python3 -m unittest discover -s tests -v

Optional development checks:

# Required when running directly from a source checkout
export PYTHONPATH=src

python3 -m pip install -e '.[dev]'
ruff check wix_monk tests
pyflakes wix_monk tests
vulture wix_monk tests --min-confidence 80

Module responsibilities and dependency rules are documented in ARCHITECTURE.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wix_monk-0.1.0.tar.gz (52.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wix_monk-0.1.0-py3-none-any.whl (39.1 kB view details)

Uploaded Python 3

File details

Details for the file wix_monk-0.1.0.tar.gz.

File metadata

  • Download URL: wix_monk-0.1.0.tar.gz
  • Upload date:
  • Size: 52.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for wix_monk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 71b248dfb324a7bd1e53f01c37f49303ca6cf224e8ec17cb89cfd13b932b8e97
MD5 a08e9e7c3793367e8d4c4c6b2f67386b
BLAKE2b-256 cebde9361a86b3c8b7c6db211ad9d1872d469775b0685afbcab36759c3f7100d

See more details on using hashes here.

File details

Details for the file wix_monk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wix_monk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for wix_monk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 87afa5d3b83253a5322b1ff0f04180fdb1612285298da55620f82dbb8d9e6f7f
MD5 7392779f28e3608adba9afcf3d9cc3a8
BLAKE2b-256 a19aeee8138ccbb3e6827f1ef38c6198db6cf7b04ab6f56eea80e3abeed4ba43

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page