medusa-plugin-ecomail
v1.1.0
Published
Ecomail integration plugin for Medusa v2 - email marketing and transaction tracking
Maintainers
Readme
medusa-plugin-ecomail
Ecomail integration plugin for Medusa v2 - email marketing and transaction tracking.
Features
- 📧 Subscriber Management - Add, update, and manage Ecomail subscribers
- 🛒 E-commerce Tracking - Automatically track order transactions in Ecomail
- 🎯 Smart Subscription - Intelligent handling of new subscribers, updates, and resubscriptions
- 🎨 Admin UI - Built-in admin panel for testing and managing subscribers
- 🔄 Auto-sync - Automatic synchronization of customer data with Ecomail lists
Compatibility
This plugin is compatible with Medusa v2 (>= 2.11.2).
Installation
npm install medusa-plugin-ecomail
# or
yarn add medusa-plugin-ecomailConfiguration
Basic Configuration (Default Mode)
Add the plugin to your medusa-config.ts:
import { defineConfig } from '@medusajs/framework/utils'
export default defineConfig({
plugins: [
{
resolve: 'medusa-plugin-ecomail',
options: {
ecomailListId: process.env.ECOMAIL_LIST_ID,
ecomailToken: process.env.ECOMAIL_TOKEN,
shopDomain: process.env.SHOP_DOMAIN, // optional
},
},
],
})Default Behavior: All customers are automatically synced to Ecomail when they place an order.
GDPR-Compliant Configuration
For GDPR compliance, enable explicit consent requirement:
import { defineConfig } from '@medusajs/framework/utils'
export default defineConfig({
plugins: [
{
resolve: 'medusa-plugin-ecomail',
options: {
ecomailListId: process.env.ECOMAIL_LIST_ID,
ecomailToken: process.env.ECOMAIL_TOKEN,
shopDomain: process.env.SHOP_DOMAIN, // optional
requireExplicitConsent: true, // Only sync with explicit consent
consentMetadataKey: 'ecomail_consent', // optional, this is the default
},
},
],
})GDPR Behavior: Only customers who explicitly consent are synced to Ecomail.
Environment Variables
Add these to your .env file:
ECOMAIL_LIST_ID=your_list_id
ECOMAIL_TOKEN=your_api_token
SHOP_DOMAIN=your-shop.com # optionalConfiguration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| ecomailListId | string | Yes | - | Your Ecomail list ID |
| ecomailToken | string | Yes | - | Your Ecomail API token |
| shopDomain | string | No | '' | Your shop domain for transaction tracking |
| requireExplicitConsent | boolean | No | false | Require explicit consent before syncing customers |
| consentMetadataKey | string | No | 'ecomail_consent' | Metadata key to check for consent |
Automatic Syncing
The plugin automatically syncs customers to Ecomail when orders are placed. No additional code is required!
How It Works
- Customer places an order →
order.placedevent fires - Plugin checks consent (if
requireExplicitConsentis enabled) - Syncs customer data to Ecomail list
- Tracks transaction for e-commerce analytics
Consent Handling
Default Mode (requireExplicitConsent: false)
All customers are automatically synced to Ecomail when they place an order. No consent checking is performed.
GDPR Mode (requireExplicitConsent: true)
Only customers who explicitly consent are synced. The plugin checks for consent in order or customer metadata.
How to pass consent from your storefront:
When completing checkout, include the consent flag in the order metadata:
// Example: Next.js/React storefront
const completeCheckout = async () => {
await sdk.store.cart.complete(cartId, {
metadata: {
ecomail_consent: userAcceptedNewsletter, // true or false
},
})
}// Example: In a custom checkout flow
await fetch('/store/checkout/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cart_id: cartId,
metadata: {
ecomail_consent: true, // User checked the newsletter box
},
}),
})The plugin checks for consent in this order:
- Order metadata (
order.metadata.ecomail_consent) - Customer metadata (
customer.metadata.ecomail_consent)
If consent is true, the customer is synced. If false or missing (in GDPR mode), the sync is skipped.
Customizing the Consent Key
You can use a different metadata key for consent:
{
resolve: 'medusa-plugin-ecomail',
options: {
// ... other options
requireExplicitConsent: true,
consentMetadataKey: 'marketing_consent', // Use your own key
}
}Then pass it from your storefront:
metadata: {
marketing_consent: true
}Usage
In Your Code
Import and use the Ecomail service in your custom modules, subscribers, or workflows:
import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'
// In a subscriber or workflow
const ecomailService = container.resolve<EcomailService>(ECOMAIL_MODULE)
// Add a subscriber
await ecomailService.addSubscriber({
email: '[email protected]',
name: 'John',
surname: 'Doe',
city: 'Prague',
country: 'CZ',
})
// Smart add/update (checks if exists, handles resubscriptions)
await ecomailService.addSubscriberToListIfNotAdded({
email: '[email protected]',
name: 'John',
surname: 'Doe',
})
// Track an order transaction
await ecomailService.addTransaction(order, customer)Admin Panel
The plugin adds an Ecomail settings page to your Medusa admin panel where you can:
- Test subscriber operations (Check, Add, Update, Smart Add)
- View subscriber details
- Verify plugin configuration
Access it at: Settings → Ecomail
API Reference
EcomailService Methods
addSubscriber(data: SubscriberDataT)
Adds a new subscriber to the Ecomail list.
Parameters:
data.email(required) - Subscriber emaildata.name- First namedata.surname- Last namedata.city- Citydata.country- Country codedata.zip- Postal codedata.company- Company namedata.street- Street addressdata.phone- Phone number
getExistingSubscriber(email: string)
Retrieves an existing subscriber from the list.
updateSubscriber(data: SubscriberDataT)
Updates an existing subscriber's data.
addSubscriberToListIfNotAdded(data: SubscriberDataT)
Smart method that:
- Adds subscriber if they don't exist
- Updates subscriber if they exist and are subscribed
- Resubscribes if they exist but are unsubscribed
addTransaction(order: OrderDTO, customer: CustomerDTO)
Tracks an e-commerce transaction in Ecomail with order details and items.
Custom Integration Examples
Using the Service Directly
While the plugin automatically syncs on order placement, you can also use the service directly for custom scenarios:
// Example: Add subscriber on customer registration
import { SubscriberArgs } from '@medusajs/framework'
import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'
export default async function customerCreatedHandler({
event: { data },
container,
}: SubscriberArgs<{ id: string }>) {
const ecomailService = container.resolve<EcomailService>(ECOMAIL_MODULE)
const customerService = container.resolve('customerService')
const customer = await customerService.retrieve(data.id)
await ecomailService.addSubscriberToListIfNotAdded({
email: customer.email,
name: customer.first_name,
surname: customer.last_name,
})
}
export const config = {
event: 'customer.created',
}Manual Sync from API Route
// Example: Custom API route for newsletter subscription
import { MedusaRequest, MedusaResponse } from '@medusajs/framework'
import { ECOMAIL_MODULE } from 'medusa-plugin-ecomail'
import type EcomailService from 'medusa-plugin-ecomail'
export async function POST(req: MedusaRequest, res: MedusaResponse) {
const ecomailService = req.scope.resolve<EcomailService>(ECOMAIL_MODULE)
const { email, name, surname } = req.body
await ecomailService.addSubscriberToListIfNotAdded({
email,
name,
surname,
})
res.json({ success: true })
}TypeScript Types
type EcomailModuleOptions = {
ecomailListId: string
ecomailToken: string
shopDomain?: string
requireExplicitConsent?: boolean
consentMetadataKey?: string
}
type SubscriberDataT = {
email: string
name?: string
surname?: string
city?: string
country?: string
zip?: string
company?: string
street?: string
phone?: string
[key: string]: string | undefined
}Testing
Testing Consent Modes
Default Mode (sync everyone):
- Configure plugin without
requireExplicitConsentor set it tofalse - Place a test order
- Verify customer appears in Ecomail list
- Verify transaction is tracked
GDPR Mode (require consent):
- Configure plugin with
requireExplicitConsent: true - Place order WITH consent (
metadata.ecomail_consent: true)- Customer should be synced ✓
- Place order WITHOUT consent (
metadata.ecomail_consent: false)- Customer should NOT be synced ✓
- Place order with NO metadata
- Customer should NOT be synced ✓
Testing via Admin Panel
The plugin includes an admin panel (Settings → Ecomail) where you can:
- Test adding subscribers manually
- Check if a subscriber exists
- Update subscriber information
- Verify your Ecomail connection
Error Handling
The plugin is designed to be resilient:
- Ecomail sync failures do not break the order flow
- All errors are logged for debugging
- Orders complete successfully even if Ecomail is unavailable
Development
# Build the plugin
yarn build
# Development mode with watch
yarn devResources
License
MIT
Author
Gramino
Made with ❤️ for the Medusa community
