Отправляйте уведомления и отслеживайте вовлечённость
This module integrates Bloomreach (Exponea) as a notification and analytics provider for Medusa v2. It enables you to send transactional emails and SMS messages through the Bloomreach platform, as well as track customer events and behavior for powerful engagement and marketing automation.
With this plugin, you can:
This module/plugin is compatible with versions >= 2.4.0 of .
Before using this integration, you need:
For more details, see the Bloomreach Authentication Documentation.
npm install @igorppbr/medusa-v2-bloomreach-notification1import { Modules } from "@medusajs/framework/utils"2
3export default defineConfig({4 // ... other config5 modules: [6 {7 resolve: "@medusajs/medusa/notification",8 options: {9 providers: [10 // default provider11 {12 resolve: "@medusajs/medusa/notification-local",13 id: "local",14 options: {15 name: "Local Notification Provider",16 channels: ["feed"]17 }18 },19 {20 resolve: "@igorppbr/medusa-v2-bloomreach/providers/notifications",21 id: "bloomreach-notification",22 options: {23 channels: ["email", "sms"], // Specify the channels you want to support24 notifications: {25 key_id: process.env.BLOOMREACH_API_KEY_ID,26 secret: process.env.BLOOMREACH_API_SECRET,27 project_id: process.env.BLOOMREACH_PROJECT_ID,28 integration_id: process.env.BLOOMREACH_INTEGRATION_ID,29 from_email: "noreply@yourdomain.com",30 from_name: "Your Company Name",31 from_sms: "+1234567890", // Required if using SMS channel32 language: "en", // Optional: default language for templates33 transfer_identity: "enabled", // Optional: 'enabled', 'disabled', or 'first_click'34 template_mappings: { // Optional: map Medusa template names to Bloomreach template IDs35 "order-confirmation": "60758e2d18883e1048b817a8",36 "order-shipped": "60758e2d18883e1048b817a9"37 },38 campaign_mappings: { // Optional: map template names to campaign names39 "order-confirmation": "Order Confirmation Campaign",40 "order-shipped": "Order Shipped Campaign"41 }42 }43 }44 }45 ]46 }47 },48 {49 resolve: "@medusajs/medusa/analytics",50 options: {51 providers: [52 {53 resolve: "@igorppbr/medusa-v2-bloomreach/providers/analytics",54 id: "bloomreach-analytics",55 options: {56 notifications: {57 key_id: process.env.BLOOMREACH_API_KEY_ID,58 secret: process.env.BLOOMREACH_API_SECRET,59 project_id: process.env.BLOOMREACH_PROJECT_ID60 }61 }62 }63 ]64 }65 }66 ],67 plugins: [68 {69 resolve: "@igorppbr/medusa-v2-bloomreach",70 options: {},71 },72 ]73})Note: Adding the plugin is required for Medusa to load the event subscribers that handle notifications and analytics tracking.
1BLOOMREACH_API_KEY_ID=your_api_key_id2BLOOMREACH_API_SECRET=your_api_secret3BLOOMREACH_PROJECT_ID=your_project_id4BLOOMREACH_INTEGRATION_ID=your_integration_idImportant: Never commit your API credentials to version control. Always use environment variables.
| Option | Type | Required | Description |
|---|---|---|---|
| string | Yes | Your Bloomreach API Key ID | |
| string | Yes | Your Bloomreach API Secret | |
| string | Yes | Your Bloomreach Project ID | |
| string | Yes | Your email/SMS integration ID | |
| string | Yes | Default sender email address | |
| string | Yes | Default sender name for emails | |
| string | Conditional | Required if using SMS channel - sender phone number | |
| string | No | Default language code (e.g., "en", "es") | |
| string | No | Link tracking behavior: "enabled", "disabled", or "first_click" | |
| object | No | Map Medusa template names to Bloomreach template IDs | |
| object | No | Map template names to campaign names |
Track customer behavior and events for analytics and personalization:
1import { Modules } from "@medusajs/framework/utils"2
3// In a workflow, subscriber, or API route4const analyticsModuleService = container.resolve(Modules.ANALYTICS)5
6await analyticsModuleService.track({7 event: "product_viewed",8 actor_id: "customer123",9 properties: {10 product_id: "prod_abc",11 product_name: "Amazing Widget",12 price: 99.99,13 category: "electronics"14 }15})Create a workflow to track order events:
1// src/workflows/track-order-placed.ts2import { createWorkflow, createStep, WorkflowResponse } from "@medusajs/framework/workflows-sdk"3import { Modules } from "@medusajs/framework/utils"4import { useQueryGraphStep } from "@medusajs/medusa/core-flows"5
6type WorkflowInput = {7 order_id: string8}9
10type StepInput = {11 order: any12}13
14const trackOrderPlacedStep = createStep(15 "track-order-placed-step",16 async ({ order }: StepInput, { container }) => {17 const analyticsModuleService = container.resolve(Modules.ANALYTICS)18
19 await analyticsModuleService.track({20 event: "order_placed",21 actor_id: order.customer_id,22 properties: {23 order_id: order.id,24 order_number: order.display_id,25 total: order.total,26 currency: order.currency_code,27 items: order.items.map((item) => ({28 variant_id: item.variant_id,29 product_id: item.product_id,30 quantity: item.quantity,31 price: item.unit_price32 }))33 }34 })35 }36)37
38export const trackOrderPlacedWorkflow = createWorkflow(39 "track-order-placed-workflow",40 ({ order_id }: WorkflowInput) => {41 const { data: orders } = useQueryGraphStep({42 entity: "order",43 fields: ["*", "customer.*", "items.*"],44 filters: { id: order_id }45 })46
47 trackOrderPlacedStep({ order: orders[0] })48
49 return new WorkflowResponse(void 0)50 }51)Then create a subscriber to execute the workflow:
1// src/subscribers/order-placed-analytics.ts2import { SubscriberArgs, type SubscriberConfig } from "@medusajs/medusa"3import { trackOrderPlacedWorkflow } from "../workflows/track-order-placed"4
5export default async function orderPlacedAnalyticsHandler({6 event: { data },7 container,8}: SubscriberArgs<{ id: string }>) {9 await trackOrderPlacedWorkflow(container).run({10 input: { order_id: data.id }11 })12}13
14export const config: SubscriberConfig = {15 event: "order.placed",16}Once configured, you can send email notifications using the Notification Module:
1import { Modules } from "@medusajs/framework/utils"2
3// In a workflow, subscriber, or API route4const notificationModuleService = container.resolve(Modules.NOTIFICATION)5
6await notificationModuleService.createNotifications({7 to: "customer@example.com",8 channel: "email",9 template: "order-confirmation",10 data: {11 order_number: "12345",12 customer_name: "John Doe",13 order_total: "$99.99"14 }15})1import { Modules } from "@medusajs/framework/utils"2
3const notificationModuleService = container.resolve(Modules.NOTIFICATION)4
5await notificationModuleService.createNotifications({6 to: "+1234567890",7 channel: "sms",8 template: "order-shipped",9 data: {10 order_number: "12345",11 tracking_number: "ABC123XYZ"12 }13})Create a subscriber to send order confirmation emails:
1// src/subscribers/order-placed.ts2import { Modules } from "@medusajs/framework/utils"3import { SubscriberArgs, type SubscriberConfig } from "@medusajs/medusa"4import { trackOrderPlacedWorkflow } from "../workflows/track-order-placed"5
6export default async function orderPlacedHandler({7 event: { data },8 container,9}: SubscriberArgs<{ id: string }>) {10 // Notifications11 try {12 const notificationModuleService = container.resolve(Modules.NOTIFICATION)13 const query = container.resolve("query")14
15 // Get order details16 const { data: [order] } = await query.graph({17 entity: "order",18 fields: ["*", "customer.*", "items.*"],19 filters: { id: data.id }20 })21
22 // Send email notification23 await notificationModuleService.createNotifications({24 to: order.customer.email,25 channel: "email",26 template: "order-confirmation",27 data: {28 customer_name: `${order.customer.first_name} ${order.customer.last_name}`,29 order_number: order.display_id,30 order_total: order.total,31 items: order.items32 }33 })34 } catch (error) {35 console.error("[Bloomreach] Error sending order notification:", error)36 }37
38 // Track analytics39 try {40 await trackOrderPlacedWorkflow(container).run({41 input: { order_id: data.id }42 })43 } catch (error) {44 console.error("[Bloomreach] Error tracking order analytics:", error)45 }46}47
48export const config: SubscriberConfig = {49 event: "order.placed",50}1Hello {{ first_name }},2
3Your order #{{ order_number }} has been confirmed!4Total: {{ order_total }}Error: "API key is required in the provider's options"
Error: "From SMS is required in the provider's options to send SMS notifications"
Email/SMS not being sent
Template not found
This package includes a Bloomreach SDK with the following functions:
Sends a transactional email through Bloomreach.
1const messageId = await sendTransactionalEmail(2 key_id,3 secret,4 project_id,5 integration_id,6 template_id,7 campaign_name,8 {9 email: "customer@example.com",10 customer_ids: { registered: "user123" },11 language: "en"12 },13 { firstName: "John", orderTotal: "99.99" },14 sender_address,15 sender_name,16 transfer_identity17)Sends a transactional SMS through Bloomreach.
1const messageId = await sendTransactionalSms(2 key_id,3 secret,4 project_id,5 campaign_name,6 {7 template_id: "template789",8 params: { order_number: "12345" }9 },10 {11 phone: "+1234567890",12 customer_ids: { registered: "user123" },13 language: "en"14 },15 integration_id16)Tracks a customer event in Bloomreach.
1await addEvent(2 key_id,3 secret,4 project_id,5 { registered: "user@example.com" },6 "purchase",7 {8 total_price: 149.99,9 voucher_code: "SAVE20",10 product_ids: ["prod1", "prod2"],11 currency: "USD"12 },13 Math.floor(Date.now() / 1000) // Optional timestamp in seconds14)We welcome contributions to this project! If you have suggestions, improvements, or bug fixes, please follow these steps:
Fork the Repository
Create a personal copy of the repository by forking it on GitHub.
Create a New Branch
Create a new branch for your changes:
git checkout -b my-feature-branchMake Your Changes
Implement your changes in the codebase.
Test Your Changes
Ensure that your changes work as expected and do not break existing functionality.
Submit a Pull Request
Push your changes to your forked repository and submit a pull request to the main repository.
If you need help or have questions about the Bloomreach Engagement Integration, please reach out to us:
This project is licensed under the MIT License.