Skip to content

feat: one platform — email campaigns, templates, automations and flow… - #549

Closed
onlypromarketer wants to merge 2 commits into
ArnasDon:mainfrom
onlypromarketer:feat/one-platform-email
Closed

onlypromarketer wants to merge 2 commits into
ArnasDon:mainfrom
onlypromarketer:feat/one-platform-email

Conversation

@onlypromarketer

Copy link
Copy Markdown

…s inside the CRM

Combine wacrm (WhatsApp CRM) and listmonk (email engine) into a single product. listmonk runs headless behind the CRM's API and is never exposed publicly; every email capability is a native page or builder step in wacrm.

Email section

  • Campaigns: list, compose, edit, preview, test-send, start/pause/cancel
  • Lists: create, and sync CRM contacts in as subscribers (phone + contact id carried in attribs; unsubscribed lists never re-added)
  • Subscribers: browse, search (SQL-injection-safe against listmonk's raw query parameter)
  • Templates: CRUD + preview for transactional emails and newsletter layouts
  • Settings: SMTP + sender identity, with the password-mask round-trip handled so a save never overwrites the stored secret with bullets

Email inside the WhatsApp builders

  • Automations: new steps send_email and add_to_mailing_list
  • Flows: new send_email node (canvas, edges, validation, engine)
  • Both send via listmonk's tx API in external mode; contacts without an email are skipped, not failed
  • Migration 040 widens the flow_nodes.node_type CHECK

Deployment (deploy/)

  • docker-compose.yml: single hostname, Caddy auto-HTTPS, engine sealed off, recipient-facing unsubscribe/tracking routes proxied under the CRM domain
  • docker-compose.local.yml: same stack on localhost
  • setup-api-user.sh: creates listmonk's API user and performs the restart its in-memory user cache requires
  • README: setup, local Mailpit testing, why listmonk is a separate service (AGPL vs MIT), why Mautic was evaluated and not added

Verified end to end: a signed inbound WhatsApp webhook started a flow and an automation that delivered two personalised emails through SMTP to a local inbox, added the contact to a mailing list, and skipped cleanly for an email-less contact. 876 tests pass.

Summary

What changed

Test plan

  • npm run typecheck clean.
  • npm run lint — no new errors beyond the pre-existing backlog.
  • npm run build succeeds.
  • Feature / fix manually exercised in the browser (or the reason it can't be).

Related

…s inside the CRM

Combine wacrm (WhatsApp CRM) and listmonk (email engine) into a single
product. listmonk runs headless behind the CRM's API and is never
exposed publicly; every email capability is a native page or builder
step in wacrm.

Email section
- Campaigns: list, compose, edit, preview, test-send, start/pause/cancel
- Lists: create, and sync CRM contacts in as subscribers (phone +
  contact id carried in attribs; unsubscribed lists never re-added)
- Subscribers: browse, search (SQL-injection-safe against listmonk's
  raw query parameter)
- Templates: CRUD + preview for transactional emails and newsletter
  layouts
- Settings: SMTP + sender identity, with the password-mask round-trip
  handled so a save never overwrites the stored secret with bullets

Email inside the WhatsApp builders
- Automations: new steps send_email and add_to_mailing_list
- Flows: new send_email node (canvas, edges, validation, engine)
- Both send via listmonk's tx API in external mode; contacts without an
  email are skipped, not failed
- Migration 040 widens the flow_nodes.node_type CHECK

Deployment (deploy/)
- docker-compose.yml: single hostname, Caddy auto-HTTPS, engine sealed
  off, recipient-facing unsubscribe/tracking routes proxied under the
  CRM domain
- docker-compose.local.yml: same stack on localhost
- setup-api-user.sh: creates listmonk's API user and performs the
  restart its in-memory user cache requires
- README: setup, local Mailpit testing, why listmonk is a separate
  service (AGPL vs MIT), why Mautic was evaluated and not added

Verified end to end: a signed inbound WhatsApp webhook started a flow
and an automation that delivered two personalised emails through SMTP
to a local inbox, added the contact to a mailing list, and skipped
cleanly for an email-less contact. 876 tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…template

Repository identity now reflects what this is: a self-hosted WhatsApp +
email marketing platform maintained by ProMarketer, forked from the
ArnasDon/wacrm template and credited as such.

- README rewritten for the combined product; upstream hosting-partner
  promotion and referral links removed; upstream and listmonk credited.
- package.json / mcp-server metadata: name, description, author,
  homepage, repository and issue links point here. Version 1.0.0.
- CHANGELOG: 1.0.0 entry covering the email platform work, required
  migration and new environment variables; inherited history kept.
- LICENSE: upstream MIT notice retained (as the licence requires);
  ProMarketer added for its portions.
- .github: CODEOWNERS, dependabot reviewers, security and conduct
  contacts, issue-template links; referral image deleted.
- CONTRIBUTING rewritten for a product repo, including how to pull
  upstream fixes.
- In-app title and page metadata renamed from "CRM Template for
  WhatsApp" to "WhatsApp + Email CRM" (en/ko).
- Invite-link generation no longer falls back to the upstream
  project's website when the deployment URL cannot be derived; it uses
  NEXT_PUBLIC_SITE_URL, then the local dev origin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ArnasDon

Copy link
Copy Markdown
Owner

Thanks for sharing this. Per CONTRIBUTING.md this repository is a template: forks are expected to diverge, and upstream only takes small, scoped fixes (security, correctness, docs) opened against current main. This PR is a whole-fork snapshot (rebrand/stack/deploy changes, colliding migration numbers, and it now conflicts with main), so I am closing it rather than reviewing file by file. If there is a specific bug fix in here that applies to the upstream template, please open it as its own small PR — those land quickly.

This one also replaces LICENSE and README with ProMarketer branding, which is fine for your fork but cannot be merged upstream.

@ArnasDon ArnasDon closed this Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants