diff --git a/docker-compose.yml b/docker-compose.yml index bf68f6e..631f2c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,8 +31,15 @@ services: - DB_POSTGRESDB_USER=n8n - DB_POSTGRESDB_PASSWORD=${N8N_DB_PASSWORD:-***REDACTED_DB_PASS***} - TWENTY_API_KEY=${TWENTY_API_KEY} - - RESEND_API_KEY=${RESEND_API_KEY} - LISTMONK_CREDENTIALS=${LISTMONK_CREDENTIALS} + - N8N_SMTP_HOST=***REDACTED_SMTP_HOST*** + - N8N_SMTP_PORT=587 + - N8N_SMTP_USER=${SMTP_USER} + - N8N_SMTP_PASS=${SMTP_PASS} + - N8N_SMTP_SENDER=${SMTP_SENDER:-***REDACTED_EMAIL***} + - N8N_EMAIL_MODE=smtp + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - n8n-cosmolocal-data:/home/node/.n8n labels: diff --git a/n8n-workflows/02-lead-nurturing.json b/n8n-workflows/02-lead-nurturing.json index e0fd98d..0ad4ee1 100644 --- a/n8n-workflows/02-lead-nurturing.json +++ b/n8n-workflows/02-lead-nurturing.json @@ -48,31 +48,24 @@ }, { "parameters": { - "method": "POST", - "url": "https://api.resend.com/emails", - "sendHeaders": true, - "headerParameters": { - "parameters": [ - { - "name": "Authorization", - "value": "Bearer {{ $env.RESEND_API_KEY }}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - "sendBody": true, - "specifyBody": "json", - "jsonBody": "={\n \"from\": \"Cosmolocal Foundation <***REDACTED_EMAIL***>\",\n \"to\": [\"{{ $json.email }}\"],\n \"subject\": \"Welcome to the Cosmolocal Foundation\",\n \"html\": \"

Welcome, {{ $json.firstName }}!

Thank you for connecting with the Cosmolocal Foundation. We're building a world where local communities thrive within regenerative economies, connected through global knowledge-sharing and commons-based collaboration.

\\\"What is heavy should be local, and what is light should be global and shared.\\\"

Here's what we're working on:

We'll be in touch with updates on our progress and opportunities to get involved.

Warm regards,
The Cosmolocal Foundation Team

cosmolocal.world

\"\n}", + "fromEmail": "={{ $env.N8N_SMTP_SENDER }}", + "toEmail": "={{ $json.email }}", + "subject": "Welcome to the Cosmolocal Foundation", + "emailType": "html", + "html": "

Welcome, {{ $json.firstName }}!

Thank you for connecting with the Cosmolocal Foundation. We're building a world where local communities thrive within regenerative economies, connected through global knowledge-sharing and commons-based collaboration.

\"What is heavy should be local, and what is light should be global and shared.\"

Here's what we're working on:

We'll be in touch with updates on our progress and opportunities to get involved.

Warm regards,
The Cosmolocal Foundation Team

cosmolocal.world

", "options": {} }, "id": "send-welcome-email", "name": "Send Welcome Email (Day 0)", - "type": "n8n-nodes-base.httpRequest", - "typeVersion": 4.2, - "position": [680, 300] + "type": "n8n-nodes-base.emailSend", + "typeVersion": 2.1, + "position": [680, 300], + "credentials": { + "smtp": { + "id": "mailcow-smtp", + "name": "Mailcow SMTP" + } + } }, { "parameters": { @@ -87,31 +80,24 @@ }, { "parameters": { - "method": "POST", - "url": "https://api.resend.com/emails", - "sendHeaders": true, - "headerParameters": { - "parameters": [ - { - "name": "Authorization", - "value": "Bearer {{ $env.RESEND_API_KEY }}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - "sendBody": true, - "specifyBody": "json", - "jsonBody": "={\n \"from\": \"Cosmolocal Foundation <***REDACTED_EMAIL***>\",\n \"to\": [\"{{ $('Extract Contact Fields').item.json.email }}\"],\n \"subject\": \"Our Strategic Priorities — How We're Building Change\",\n \"html\": \"

Hi {{ $('Extract Contact Fields').item.json.firstName }},

We wanted to share more about our strategic approach to systemic transformation.

The Cosmolocal Foundation is executing on eight key initiatives:

  1. Mapping Regenerative Communities — Cataloging eco-villages, circular economy hubs, and governance initiatives worldwide
  2. Web3 Funding — Quadratic funding, DAOs, and Collaborative Finance for local projects
  3. Open Resources — A global knowledge commons of governance models and production blueprints
  4. Education & Advocacy — Engaging policymakers to scale cosmolocal principles
  5. Pilots & Grants — Funding projects that demonstrate scalable solutions
  6. Cosmolocal Certification — Blockchain-verified standards for cosmolocal initiatives
  7. Global Alliances — Bioregional collaboration on governance and mutual aid
  8. Impact Research — Evidence-based scaling through the Cosmolocal Research Institute

Want to learn more or get involved? Reply to this email — we'd love to hear from you.

Best,
The Cosmolocal Foundation Team

\"\n}", + "fromEmail": "={{ $env.N8N_SMTP_SENDER }}", + "toEmail": "={{ $('Extract Contact Fields').item.json.email }}", + "subject": "Our Strategic Priorities — How We're Building Change", + "emailType": "html", + "html": "

Hi {{ $('Extract Contact Fields').item.json.firstName }},

We wanted to share more about our strategic approach to systemic transformation.

The Cosmolocal Foundation is executing on eight key initiatives:

  1. Mapping Regenerative Communities — Cataloging eco-villages, circular economy hubs, and governance initiatives worldwide
  2. Web3 Funding — Quadratic funding, DAOs, and Collaborative Finance for local projects
  3. Open Resources — A global knowledge commons of governance models and production blueprints
  4. Education & Advocacy — Engaging policymakers to scale cosmolocal principles
  5. Pilots & Grants — Funding projects that demonstrate scalable solutions
  6. Cosmolocal Certification — Blockchain-verified standards for cosmolocal initiatives
  7. Global Alliances — Bioregional collaboration on governance and mutual aid
  8. Impact Research — Evidence-based scaling through the Cosmolocal Research Institute

Want to learn more or get involved? Reply to this email — we'd love to hear from you.

Best,
The Cosmolocal Foundation Team

", "options": {} }, "id": "send-followup-email", "name": "Send Follow-up Email (Day 3)", - "type": "n8n-nodes-base.httpRequest", - "typeVersion": 4.2, - "position": [1120, 300] + "type": "n8n-nodes-base.emailSend", + "typeVersion": 2.1, + "position": [1120, 300], + "credentials": { + "smtp": { + "id": "mailcow-smtp", + "name": "Mailcow SMTP" + } + } }, { "parameters": { @@ -126,31 +112,24 @@ }, { "parameters": { - "method": "POST", - "url": "https://api.resend.com/emails", - "sendHeaders": true, - "headerParameters": { - "parameters": [ - { - "name": "Authorization", - "value": "Bearer {{ $env.RESEND_API_KEY }}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - "sendBody": true, - "specifyBody": "json", - "jsonBody": "={\n \"from\": \"Cosmolocal Foundation <***REDACTED_EMAIL***>\",\n \"to\": [\"{{ $('Extract Contact Fields').item.json.email }}\"],\n \"subject\": \"Join the Movement — Ways to Participate\",\n \"html\": \"

Hi {{ $('Extract Contact Fields').item.json.firstName }},

We believe in the power of collaboration. Here are ways you can participate in the cosmolocal movement:

Visit cosmolocal.world to explore our work, or simply reply to this email to start a conversation.

Together we can build regenerative economies that serve communities and the planet.

In solidarity,
The Cosmolocal Foundation Team

\"\n}", + "fromEmail": "={{ $env.N8N_SMTP_SENDER }}", + "toEmail": "={{ $('Extract Contact Fields').item.json.email }}", + "subject": "Join the Movement — Ways to Participate", + "emailType": "html", + "html": "

Hi {{ $('Extract Contact Fields').item.json.firstName }},

We believe in the power of collaboration. Here are ways you can participate in the cosmolocal movement:

Visit cosmolocal.world to explore our work, or simply reply to this email to start a conversation.

Together we can build regenerative economies that serve communities and the planet.

In solidarity,
The Cosmolocal Foundation Team

", "options": {} }, "id": "send-engagement-email", "name": "Send Engagement Email (Day 10)", - "type": "n8n-nodes-base.httpRequest", - "typeVersion": 4.2, - "position": [1560, 300] + "type": "n8n-nodes-base.emailSend", + "typeVersion": 2.1, + "position": [1560, 300], + "credentials": { + "smtp": { + "id": "mailcow-smtp", + "name": "Mailcow SMTP" + } + } }, { "parameters": { diff --git a/n8n-workflows/04-follow-up-reminders.json b/n8n-workflows/04-follow-up-reminders.json index 5090a95..2131d37 100644 --- a/n8n-workflows/04-follow-up-reminders.json +++ b/n8n-workflows/04-follow-up-reminders.json @@ -101,7 +101,7 @@ }, { "parameters": { - "jsCode": "const items = $input.all();\nconst contactList = items.map(item => \n `- **${item.json.fullName}** (${item.json.email}) — ${item.json.daysSinceUpdate} days since last update`\n).join('\\n');\n\nconst count = items.length;\n\nreturn [{\n json: {\n subject: `[Cosmolocal CRM] ${count} contact${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} follow-up`,\n htmlBody: `

Stale Contact Report

The following ${count} contact${count !== 1 ? 's have' : ' has'} not been updated in 14+ days:

${items.map(i => ``).join('')}
NameEmailDays Stale
${i.json.fullName}${i.json.email}${i.json.daysSinceUpdate}

Open CRM to follow up.

Automated by n8n — automate.cosmolocal.world

`,\n count\n }\n}];" + "jsCode": "const items = $input.all();\nconst count = items.length;\n\nconst tableRows = items.map(i => `${i.json.fullName}${i.json.email}${i.json.daysSinceUpdate}`).join('');\n\nreturn [{\n json: {\n subject: `[Cosmolocal CRM] ${count} contact${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} follow-up`,\n htmlBody: `

Stale Contact Report

The following ${count} contact${count !== 1 ? 's have' : ' has'} not been updated in 14+ days:

${tableRows}
NameEmailDays Stale

Open CRM to follow up.

Automated by n8n — automate.cosmolocal.world

`,\n count\n }\n}];" }, "id": "build-report", "name": "Build Report Email", @@ -111,31 +111,24 @@ }, { "parameters": { - "method": "POST", - "url": "https://api.resend.com/emails", - "sendHeaders": true, - "headerParameters": { - "parameters": [ - { - "name": "Authorization", - "value": "Bearer {{ $env.RESEND_API_KEY }}" - }, - { - "name": "Content-Type", - "value": "application/json" - } - ] - }, - "sendBody": true, - "specifyBody": "json", - "jsonBody": "={\n \"from\": \"CRM Bot \",\n \"to\": [\"***REDACTED_EMAIL***\"],\n \"subject\": \"{{ $json.subject }}\",\n \"html\": \"{{ $json.htmlBody }}\"\n}", + "fromEmail": "={{ $env.N8N_SMTP_SENDER }}", + "toEmail": "***REDACTED_EMAIL***", + "subject": "={{ $json.subject }}", + "emailType": "html", + "html": "={{ $json.htmlBody }}", "options": {} }, "id": "send-reminder-email", "name": "Send Reminder to Team", - "type": "n8n-nodes-base.httpRequest", - "typeVersion": 4.2, - "position": [1560, 240] + "type": "n8n-nodes-base.emailSend", + "typeVersion": 2.1, + "position": [1560, 240], + "credentials": { + "smtp": { + "id": "mailcow-smtp", + "name": "Mailcow SMTP" + } + } }, { "parameters": {}, diff --git a/n8n-workflows/README.md b/n8n-workflows/README.md index e098545..9a3ffc3 100644 --- a/n8n-workflows/README.md +++ b/n8n-workflows/README.md @@ -9,9 +9,12 @@ API keys are passed as **Docker environment variables** in `docker-compose.yml` | Variable | Description | Where to find | |----------|-------------|---------------| | `TWENTY_API_KEY` | Twenty CRM API key | crm.cosmolocal.world > Settings > API Keys | -| `RESEND_API_KEY` | Resend email API key | `ssh netcup "cat ~/.resend_credentials"` | +| `SMTP_USER` | Mailcow SMTP username | e.g. `***REDACTED_EMAIL***` | +| `SMTP_PASS` | Mailcow SMTP password | Mailcow admin panel at ***REDACTED_SMTP_HOST*** | | `LISTMONK_CREDENTIALS` | Listmonk `user:pass` | Internal Docker service credentials | +Email is sent via **Mailcow SMTP** (`***REDACTED_SMTP_HOST***:587` STARTTLS). After importing workflows, create an SMTP credential in n8n named "Mailcow SMTP" with the host/user/pass above. + To set keys, create `/opt/websites/cosmolocal-website/.env` on the server and redeploy. ## Workflows