From 90be376d4fcc36adb92f49601c1120dbf327bc08 Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Tue, 30 Dec 2025 15:17:18 +0100 Subject: [PATCH 1/3] chore: update medusa-plugin-notification-emails to version 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 914ecb4..34fbf67 100755 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@changesets/cli": "^2.29.8", - "@codee-sh/medusa-plugin-notification-emails": "0.1.1", + "@codee-sh/medusa-plugin-notification-emails": "0.2.1", "@medusajs/admin-sdk": "2.8.8", "@medusajs/cli": "2.8.8", "@medusajs/framework": "2.8.8", From 0e65c488a620ef85e1ed4ec18387a75121abe6d7 Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Tue, 30 Dec 2025 15:17:53 +0100 Subject: [PATCH 2/3] refactor: Slack Templates is replaced by external plugin --- .../services/base-action-service.ts | 4 +- .../services/email-action-service.ts | 32 +++-- .../services/slack-action-service.ts | 72 ++++------ .../types/modules/inventory/inventory.ts | 8 ++ src/providers/slack/service.ts | 51 ++++--- src/templates/slack/inventory-level/index.ts | 1 - .../slack/inventory-level/inventory-level.ts | 135 ------------------ .../inventory-level/translations/en.json | 19 --- .../inventory-level/translations/index.ts | 9 -- .../inventory-level/translations/pl.json | 19 --- src/templates/slack/order/base-order.ts | 87 ----------- src/templates/slack/order/index.ts | 6 - src/templates/slack/order/order-archived.ts | 25 ---- src/templates/slack/order/order-canceled.ts | 25 ---- src/templates/slack/order/order-completed.ts | 25 ---- src/templates/slack/order/order-placed.ts | 25 ---- src/templates/slack/order/order-updated.ts | 25 ---- src/templates/slack/order/order.ts | 78 ---------- .../slack/order/translations/en.json | 39 ----- .../slack/order/translations/index.ts | 9 -- .../slack/order/translations/pl.json | 39 ----- src/templates/slack/product-variant/index.ts | 1 - .../slack/product-variant/product-variant.ts | 82 ----------- .../product-variant/translations/en.json | 19 --- .../product-variant/translations/index.ts | 9 -- .../product-variant/translations/pl.json | 14 -- src/templates/slack/product/index.ts | 1 - src/templates/slack/product/product.ts | 81 ----------- .../slack/product/translations/en.json | 19 --- .../slack/product/translations/index.ts | 9 -- .../slack/product/translations/pl.json | 14 -- src/templates/slack/types.ts | 23 --- src/utils/types/index.ts | 1 - .../notifications/steps/send-slack.ts | 3 +- 34 files changed, 88 insertions(+), 921 deletions(-) delete mode 100644 src/templates/slack/inventory-level/index.ts delete mode 100644 src/templates/slack/inventory-level/inventory-level.ts delete mode 100644 src/templates/slack/inventory-level/translations/en.json delete mode 100644 src/templates/slack/inventory-level/translations/index.ts delete mode 100644 src/templates/slack/inventory-level/translations/pl.json delete mode 100644 src/templates/slack/order/base-order.ts delete mode 100644 src/templates/slack/order/index.ts delete mode 100644 src/templates/slack/order/order-archived.ts delete mode 100644 src/templates/slack/order/order-canceled.ts delete mode 100644 src/templates/slack/order/order-completed.ts delete mode 100644 src/templates/slack/order/order-placed.ts delete mode 100644 src/templates/slack/order/order-updated.ts delete mode 100644 src/templates/slack/order/order.ts delete mode 100644 src/templates/slack/order/translations/en.json delete mode 100644 src/templates/slack/order/translations/index.ts delete mode 100644 src/templates/slack/order/translations/pl.json delete mode 100644 src/templates/slack/product-variant/index.ts delete mode 100644 src/templates/slack/product-variant/product-variant.ts delete mode 100644 src/templates/slack/product-variant/translations/en.json delete mode 100644 src/templates/slack/product-variant/translations/index.ts delete mode 100644 src/templates/slack/product-variant/translations/pl.json delete mode 100644 src/templates/slack/product/index.ts delete mode 100644 src/templates/slack/product/product.ts delete mode 100644 src/templates/slack/product/translations/en.json delete mode 100644 src/templates/slack/product/translations/index.ts delete mode 100644 src/templates/slack/product/translations/pl.json delete mode 100644 src/templates/slack/types.ts diff --git a/src/modules/mpn-automation/services/base-action-service.ts b/src/modules/mpn-automation/services/base-action-service.ts index c538195..c7720cc 100644 --- a/src/modules/mpn-automation/services/base-action-service.ts +++ b/src/modules/mpn-automation/services/base-action-service.ts @@ -32,7 +32,7 @@ export class BaseActionService implements ActionHandler { */ registerTemplate( name: string, - renderer: TemplateRenderer + renderer: any ): void { this.templates_.set(name, renderer) } @@ -42,7 +42,7 @@ export class BaseActionService implements ActionHandler { * @param name - Template name * @returns Template renderer or undefined */ - getTemplate(name: string): TemplateRenderer | undefined { + getTemplate(name: string): any | undefined { return this.templates_.get(name) } diff --git a/src/modules/mpn-automation/services/email-action-service.ts b/src/modules/mpn-automation/services/email-action-service.ts index fde0e5b..a34164f 100644 --- a/src/modules/mpn-automation/services/email-action-service.ts +++ b/src/modules/mpn-automation/services/email-action-service.ts @@ -1,6 +1,6 @@ import { FieldConfig } from "../types" import { BaseActionService } from "./base-action-service" -import { renderTemplate } from "@codee-sh/medusa-plugin-notification-emails/templates/emails" +import { emailService } from "@codee-sh/medusa-plugin-notification-emails/templates/emails" import { transformContext } from "@codee-sh/medusa-plugin-notification-emails/utils" import type { @@ -71,8 +71,12 @@ export class EmailActionService extends BaseActionService { * This method can be used to register custom templates if needed */ protected initializeTemplates(): void { - // Email templates are handled by external plugin - // Custom templates can be registered here if needed + // Email engine already has all prebuild templates registered + // You can register custom templates here if needed: + // emailEngine.registerTemplate("custom-template", { + // ...emailEngine.getBaseTemplate(), + // getConfig: () => ({ blocks: [...], translations: {...} }) + // }) } /** @@ -85,10 +89,6 @@ export class EmailActionService extends BaseActionService { context: TemplateData contextType?: string | null options?: TemplateOptionsType - customTemplateFunction?: ( - data: TemplateData, - options: TemplateOptionsType - ) => React.ReactElement }): Promise<{ html: string text: string @@ -98,19 +98,21 @@ export class EmailActionService extends BaseActionService { templateName, context, contextType, - options, - customTemplateFunction, + options = {} } = params const transformedContext = transformContext(contextType, context) - const result = await renderTemplate( + const result = await emailService.render({ templateName, - transformedContext, - options || {}, - customTemplateFunction - ) + data: transformedContext, + options: options || {}, + }) - return result + return { + html: result.html, + text: result.text, + subject: result.subject, + } } } diff --git a/src/modules/mpn-automation/services/slack-action-service.ts b/src/modules/mpn-automation/services/slack-action-service.ts index 6e1f592..fc06437 100644 --- a/src/modules/mpn-automation/services/slack-action-service.ts +++ b/src/modules/mpn-automation/services/slack-action-service.ts @@ -1,16 +1,6 @@ import { BaseActionService } from "./base-action-service" -import { - SlackTemplateRenderer, - SlackBlock, -} from "../../../templates/slack/types" -import { renderInventoryLevel } from "../../../templates/slack/inventory-level" -import { renderProductVariant } from "../../../templates/slack/product-variant/product-variant" -import { renderProduct } from "../../../templates/slack/product/product" -import { renderOrderPlaced } from "../../../templates/slack/order/order-placed" -import { renderOrderCompleted } from "../../../templates/slack/order/order-completed" -import { renderOrderUpdated } from "../../../templates/slack/order/order-updated" -import { renderOrderCanceled } from "../../../templates/slack/order/order-canceled" -import { renderOrderArchived } from "../../../templates/slack/order/order-archived" +import { slackService } from "@codee-sh/medusa-plugin-notification-emails/templates/slack" +import { transformContext } from "@codee-sh/medusa-plugin-notification-emails/utils" export class SlackActionService extends BaseActionService { id = "slack" @@ -28,24 +18,16 @@ export class SlackActionService extends BaseActionService { /** * Initialize default Slack templates + * Slack engine already has all prebuild templates registered + * This method can be used to register custom templates if needed */ protected initializeTemplates(): void { - // Register default templates - this.registerTemplate( - "inventory-level", - renderInventoryLevel as any - ) - this.registerTemplate( - "product-variant", - renderProductVariant as any - ) - this.registerTemplate("product", renderProduct as any) - - this.registerTemplate("order-placed", renderOrderPlaced as any) - this.registerTemplate("order-completed", renderOrderCompleted as any) - this.registerTemplate("order-updated", renderOrderUpdated as any) - this.registerTemplate("order-canceled", renderOrderCanceled as any) - this.registerTemplate("order-archived", renderOrderArchived as any) + // Slack engine already has all prebuild templates registered + // You can register custom templates here if needed: + // slackEngine.registerTemplate("custom-template", { + // ...slackEngine.getBaseTemplate(), + // getConfig: () => ({ blocks: [...], translations: {...} }) + // }) } /** @@ -58,24 +40,28 @@ export class SlackActionService extends BaseActionService { context: any contextType?: string | null options?: any - }): Promise<{ text: string; blocks: SlackBlock[] }> { - const renderer = this.getTemplate( - params.templateName - ) as SlackTemplateRenderer | undefined + }): Promise<{ text: string; blocks: any[] }> { - if (!renderer) { - throw new Error( - `Slack template "${params.templateName}" not found. Available templates: ${Array.from(this.templates_.keys()).join(", ")}` - ) - } + const transformedContext = transformContext(params.contextType, params.context) - const result = renderer({ - context: params.context, - contextType: params.contextType, - options: params.options || {}, + const { blocks } = await slackService.render({ + templateName: params.templateName, + data: { + ...transformedContext, + backend_url: params.options?.backendUrl, + }, + options: params.options }) - // Handle both sync and async renderers - return result instanceof Promise ? await result : result + // For Slack, the 'text' field is a fallback for notifications that don't support blocks. + // We can derive it from the first header block or a generic message. + const fallbackText = + blocks.find((b) => b.type === "header" && b.text?.text)?.text?.text || + `Notification for ${params.templateName}` + + return { + text: fallbackText, + blocks: blocks, + } } } diff --git a/src/modules/mpn-automation/types/modules/inventory/inventory.ts b/src/modules/mpn-automation/types/modules/inventory/inventory.ts index b9101a8..6c68abb 100644 --- a/src/modules/mpn-automation/types/modules/inventory/inventory.ts +++ b/src/modules/mpn-automation/types/modules/inventory/inventory.ts @@ -92,6 +92,14 @@ export const INVENTORY_LEVEL_ATTRIBUTES = [ isRelation: true, relationType: "stock_locations", }, + { + value: "inventory_level.inventory_item.title", + label: "Inventory Item Title", + description: "Inventory item title", + examples: ["Product A", "Product B", "Product C"], + isRelation: true, + relationType: "inventory_item", + }, ] // Fields for use in query.graph() - includes technical relations with * diff --git a/src/providers/slack/service.ts b/src/providers/slack/service.ts index dbf3619..856d35c 100644 --- a/src/providers/slack/service.ts +++ b/src/providers/slack/service.ts @@ -71,29 +71,40 @@ export class SlackNotificationProviderService extends AbstractNotificationProvid } } - const response = await fetch( - this.options_.webhook_url, - { - method: "POST", - body: JSON.stringify({ - text: content.text, - blocks: content.blocks, - }), - headers: { - "Content-Type": "application/json", - }, + try { + const response = await fetch( + this.options_.webhook_url, + { + method: "POST", + body: JSON.stringify({ + text: content.text, + blocks: content.blocks, + }), + headers: { + "Content-Type": "application/json", + }, + } + ) + + // Slack webhook API returns "ok" as plain text, not JSON + const responseText = await response.text() + + if (responseText !== "ok") { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + `Failed to send notification to Slack: ${responseText}` + ) } - ) - if (!response.ok) { - throw new MedusaError( - MedusaError.Types.UNEXPECTED_STATE, - "Failed to send notification to Slack" - ) - } + return { + status: responseText === "ok" ? "success" : "failed", + } + } catch (error) { + console.error("Failed to send notification to Slack", error) - return { - status: response.ok ? "success" : "failed", + return { + status: "failed" + } } } } diff --git a/src/templates/slack/inventory-level/index.ts b/src/templates/slack/inventory-level/index.ts deleted file mode 100644 index df1fa45..0000000 --- a/src/templates/slack/inventory-level/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./inventory-level" diff --git a/src/templates/slack/inventory-level/inventory-level.ts b/src/templates/slack/inventory-level/inventory-level.ts deleted file mode 100644 index b4e84b5..0000000 --- a/src/templates/slack/inventory-level/inventory-level.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { translations } from "./translations" -import { - createTranslator, - mergeTranslations, -} from "../../../utils" - -export interface RenderInventoryLevelParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderInventoryLevel({ - context, - contextType, - options = {}, -}: RenderInventoryLevelParams): { - text: string - blocks: SlackBlock[] -} { - const backendUrl = options?.backendUrl || "" - const locale = options?.locale || "pl" - const inventoryLevel = context?.inventory_level - - // Merge custom translations if provided - const mergedTranslations = mergeTranslations( - translations, - options.customTranslations - ) - - // Create translator function - const t = createTranslator(locale, mergedTranslations) - - const blocksSections: SlackBlock[] = [] - - if (inventoryLevel?.inventory_item?.title) { - blocksSections.push({ - type: "header", - text: { - type: "plain_text", - text: t("header.title", { - inventoryItemTitle: - inventoryLevel?.inventory_item?.title || - "unknown", - }), - emoji: true, - }, - }) - } - - if (inventoryLevel?.stock_locations?.length > 0) { - blocksSections.push({ - type: "section", - fields: inventoryLevel?.stock_locations?.map( - (stockLocation) => ({ - type: "mrkdwn", - text: `*${t("labels.location")}*\n${ - stockLocation.name - }`, - }) - ), - }) - } - - if (inventoryLevel?.stocked_quantity) { - blocksSections.push({ - type: "section", - fields: [ - { - type: "mrkdwn", - text: `*${t("labels.quantity")}*\n${ - inventoryLevel?.stocked_quantity - }`, - }, - ], - }) - } - if (inventoryLevel?.reserved_quantity) { - blocksSections.push({ - type: "section", - fields: [ - { - type: "mrkdwn", - text: `*${t("labels.reservedQuantity")}*\n${ - inventoryLevel?.reserved_quantity - }`, - }, - ], - }) - } - - if (inventoryLevel?.incoming_quantity) { - blocksSections.push({ - type: "section", - fields: [ - { - type: "mrkdwn", - text: `*${t("labels.incomingQuantity")}*\n${ - inventoryLevel?.incoming_quantity - }`, - }, - ], - }) - } - - const blocks: SlackBlock[] = - blocksSections.length > 0 ? blocksSections : [] - - if (inventoryLevel?.inventory_item_id) { - blocks.push({ - type: "actions", - elements: [ - { - type: "button", - text: { - type: "plain_text", - text: t("actions.openInPanel"), - }, - url: `${backendUrl}/app/inventory/${inventoryLevel.inventory_item_id}`, - style: "primary", - }, - ], - }) - } - - blocks.push({ type: "divider" }) - - return { - text: t("headerTitle", { - inventoryLevelId: inventoryLevel?.id || "unknown", - }), - blocks, - } -} diff --git a/src/templates/slack/inventory-level/translations/en.json b/src/templates/slack/inventory-level/translations/en.json deleted file mode 100644 index d1f0d47..0000000 --- a/src/templates/slack/inventory-level/translations/en.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "general": { - "header": { - "title": "Inventory level #{{inventoryItemTitle}} has been updated" - }, - "labels": { - "quantity": "Quantity", - "reservedQuantity": "Reserved Quantity", - "incomingQuantity": "Incoming Quantity", - "availableQuantity": "Available Quantity", - "location": "Location", - "noData": "No data" - }, - "actions": { - "openInPanel": "Open in panel" - } - } -} - diff --git a/src/templates/slack/inventory-level/translations/index.ts b/src/templates/slack/inventory-level/translations/index.ts deleted file mode 100644 index 6bbe4d8..0000000 --- a/src/templates/slack/inventory-level/translations/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import pl from "./pl.json" -import en from "./en.json" - -export const translations: Record = { - pl: pl, - en: en, -} - -export { pl, en } diff --git a/src/templates/slack/inventory-level/translations/pl.json b/src/templates/slack/inventory-level/translations/pl.json deleted file mode 100644 index 8f44a44..0000000 --- a/src/templates/slack/inventory-level/translations/pl.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "general": { - "header": { - "title": "Poziom zapasów {{inventoryItemTitle}} został zaktualizowany" - }, - "labels": { - "quantity": "Ilość", - "reservedQuantity": "Ilość zarezerwowana", - "incomingQuantity": "Ilość przychodząca", - "availableQuantity": "Ilość dostępna", - "location": "Lokalizacja", - "noData": "Brak danych" - }, - "actions": { - "openInPanel": "Otwórz w panelu" - } - } -} - diff --git a/src/templates/slack/order/base-order.ts b/src/templates/slack/order/base-order.ts deleted file mode 100644 index 5d4f9ad..0000000 --- a/src/templates/slack/order/base-order.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { translations } from "./translations" -import { - createTranslator, - mergeTranslations, -} from "../../../utils" - -export type OrderEventType = "placed" | "completed" | "updated" | "canceled" | "archived" - -export interface RenderOrderBaseParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions - eventType: OrderEventType -} - -/** - * Base function for rendering order Slack templates - * Handles common logic for all order event types - */ -export function renderOrderBase({ - context, - contextType, - options = {}, - eventType, -}: RenderOrderBaseParams): { - text: string - blocks: SlackBlock[] -} { - const backendUrl = options?.backendUrl || "" - const locale = options?.locale || "pl" - const order = context?.order - - // Merge custom translations if provided - const mergedTranslations = mergeTranslations( - translations, - options.customTranslations - ) - - // Create translator function - const t = createTranslator(locale, mergedTranslations) - - const blocks: SlackBlock[] = [] - - if (order?.id) { - blocks.push({ - type: "header", - text: { - type: "plain_text", - text: t(`${eventType}.header.title`, { - orderId: order?.display_id || order?.id || "unknown", - }), - emoji: true, - }, - }) - } - - if (order?.id) { - // Use "danger" style for canceled orders, "primary" for others - const buttonStyle = eventType === "canceled" ? "danger" : "primary" - - blocks.push({ - type: "actions", - elements: [ - { - type: "button", - text: { - type: "plain_text", - text: t("actions.openInPanel"), - }, - url: `${backendUrl}/app/orders/${order.id}`, - style: buttonStyle, - }, - ], - }) - } - - blocks.push({ type: "divider" }) - - return { - text: t(`${eventType}.headerTitle`, { - orderId: order?.display_id || order?.id || "unknown", - }), - blocks, - } -} - diff --git a/src/templates/slack/order/index.ts b/src/templates/slack/order/index.ts deleted file mode 100644 index 163e306..0000000 --- a/src/templates/slack/order/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./order" -export * from "./order-placed" -export * from "./order-completed" -export * from "./order-updated" -export * from "./order-canceled" -export * from "./order-archived" diff --git a/src/templates/slack/order/order-archived.ts b/src/templates/slack/order/order-archived.ts deleted file mode 100644 index 970c577..0000000 --- a/src/templates/slack/order/order-archived.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { renderOrderBase } from "./base-order" - -export interface RenderOrderArchivedParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrderArchived({ - context, - contextType, - options = {}, -}: RenderOrderArchivedParams): { - text: string - blocks: SlackBlock[] -} { - return renderOrderBase({ - context, - contextType, - options, - eventType: "archived", - }) -} - diff --git a/src/templates/slack/order/order-canceled.ts b/src/templates/slack/order/order-canceled.ts deleted file mode 100644 index 9a1cc80..0000000 --- a/src/templates/slack/order/order-canceled.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { renderOrderBase } from "./base-order" - -export interface RenderOrderCanceledParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrderCanceled({ - context, - contextType, - options = {}, -}: RenderOrderCanceledParams): { - text: string - blocks: SlackBlock[] -} { - return renderOrderBase({ - context, - contextType, - options, - eventType: "canceled", - }) -} - diff --git a/src/templates/slack/order/order-completed.ts b/src/templates/slack/order/order-completed.ts deleted file mode 100644 index d7b06d9..0000000 --- a/src/templates/slack/order/order-completed.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { renderOrderBase } from "./base-order" - -export interface RenderOrderCompletedParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrderCompleted({ - context, - contextType, - options = {}, -}: RenderOrderCompletedParams): { - text: string - blocks: SlackBlock[] -} { - return renderOrderBase({ - context, - contextType, - options, - eventType: "completed", - }) -} - diff --git a/src/templates/slack/order/order-placed.ts b/src/templates/slack/order/order-placed.ts deleted file mode 100644 index eb8b4d3..0000000 --- a/src/templates/slack/order/order-placed.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { renderOrderBase } from "./base-order" - -export interface RenderOrderPlacedParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrderPlaced({ - context, - contextType, - options = {}, -}: RenderOrderPlacedParams): { - text: string - blocks: SlackBlock[] -} { - return renderOrderBase({ - context, - contextType, - options, - eventType: "placed", - }) -} - diff --git a/src/templates/slack/order/order-updated.ts b/src/templates/slack/order/order-updated.ts deleted file mode 100644 index 02e7a4f..0000000 --- a/src/templates/slack/order/order-updated.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { renderOrderBase } from './base-order' - -export interface RenderOrderUpdatedParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrderUpdated({ - context, - contextType, - options = {}, -}: RenderOrderUpdatedParams): { - text: string - blocks: SlackBlock[] -} { - return renderOrderBase({ - context, - contextType, - options, - eventType: "updated", - }) -} - diff --git a/src/templates/slack/order/order.ts b/src/templates/slack/order/order.ts deleted file mode 100644 index c9b9235..0000000 --- a/src/templates/slack/order/order.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { translations } from "./translations" -import { - createTranslator, - mergeTranslations, -} from "../../../utils" - -export interface RenderOrderParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderOrder({ - context, - contextType, - options = {}, -}: RenderOrderParams): { - text: string - blocks: SlackBlock[] -} { - const backendUrl = options?.backendUrl || "" - const locale = options?.locale || "pl" - const order = context?.order - - // Merge custom translations if provided - const mergedTranslations = mergeTranslations( - translations, - options.customTranslations - ) - - // Create translator function - const t = createTranslator(locale, mergedTranslations) - - const blocksSections: SlackBlock[] = [] - - if (order?.id) { - blocksSections.push({ - type: "header", - text: { - type: "plain_text", - text: t("header.title", { - orderId: order?.id || "unknown", - }), - emoji: true, - }, - }) - } - - const blocks: SlackBlock[] = - blocksSections.length > 0 ? blocksSections : [] - - if (order?.id) { - blocks.push({ - type: "actions", - elements: [ - { - type: "button", - text: { - type: "plain_text", - text: t("actions.openInPanel"), - }, - url: `${backendUrl}/app/orders/${order.id}`, - style: "primary", - }, - ], - }) - } - - blocks.push({ type: "divider" }) - - return { - text: t("headerTitle", { - orderId: order?.id || "unknown", - }), - blocks, - } -} diff --git a/src/templates/slack/order/translations/en.json b/src/templates/slack/order/translations/en.json deleted file mode 100644 index 594ac47..0000000 --- a/src/templates/slack/order/translations/en.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "placed": { - "header": { - "title": "🎉 New order #{{orderId}}" - }, - "headerTitle": "New order #{{orderId}}" - }, - "completed": { - "header": { - "title": "✅ Order #{{orderId}} has been completed" - }, - "headerTitle": "Order #{{orderId}} has been completed" - }, - "updated": { - "header": { - "title": "📝 Order #{{orderId}} has been updated" - }, - "headerTitle": "Order #{{orderId}} has been updated" - }, - "canceled": { - "header": { - "title": "❌ Order #{{orderId}} has been canceled" - }, - "headerTitle": "Order #{{orderId}} has been canceled" - }, - "archived": { - "header": { - "title": "📦 Order #{{orderId}} has been archived" - }, - "headerTitle": "Order #{{orderId}} has been archived" - }, - "actions": { - "openInPanel": "Open in panel" - }, - "labels": { - "noData": "No data" - } -} - diff --git a/src/templates/slack/order/translations/index.ts b/src/templates/slack/order/translations/index.ts deleted file mode 100644 index 6bbe4d8..0000000 --- a/src/templates/slack/order/translations/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import pl from "./pl.json" -import en from "./en.json" - -export const translations: Record = { - pl: pl, - en: en, -} - -export { pl, en } diff --git a/src/templates/slack/order/translations/pl.json b/src/templates/slack/order/translations/pl.json deleted file mode 100644 index 1d043cf..0000000 --- a/src/templates/slack/order/translations/pl.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "placed": { - "header": { - "title": "🎉 Nowe zamówienie #{{orderId}}" - }, - "headerTitle": "Nowe zamówienie #{{orderId}}" - }, - "completed": { - "header": { - "title": "✅ Zamówienie #{{orderId}} zostało zrealizowane" - }, - "headerTitle": "Zamówienie #{{orderId}} zostało zrealizowane" - }, - "updated": { - "header": { - "title": "📝 Zamówienie #{{orderId}} zostało zaktualizowane" - }, - "headerTitle": "Zamówienie #{{orderId}} zostało zaktualizowane" - }, - "canceled": { - "header": { - "title": "❌ Zamówienie #{{orderId}} zostało anulowane" - }, - "headerTitle": "Zamówienie #{{orderId}} zostało anulowane" - }, - "archived": { - "header": { - "title": "📦 Zamówienie #{{orderId}} zostało zarchiwizowane" - }, - "headerTitle": "Zamówienie #{{orderId}} zostało zarchiwizowane" - }, - "actions": { - "openInPanel": "Otwórz w panelu" - }, - "labels": { - "noData": "Brak danych" - } -} - diff --git a/src/templates/slack/product-variant/index.ts b/src/templates/slack/product-variant/index.ts deleted file mode 100644 index dd21220..0000000 --- a/src/templates/slack/product-variant/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./product-variant" diff --git a/src/templates/slack/product-variant/product-variant.ts b/src/templates/slack/product-variant/product-variant.ts deleted file mode 100644 index 288ae35..0000000 --- a/src/templates/slack/product-variant/product-variant.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { translations } from "./translations" -import { - createTranslator, - mergeTranslations, -} from "../../../utils" - -export interface RenderProductVariantParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderProductVariant({ - context, - contextType, - options = {}, -}: RenderProductVariantParams): { - text: string - blocks: SlackBlock[] -} { - const backendUrl = options?.backendUrl || "" - const locale = options?.locale || "pl" - const productVariant = context?.product_variant - - console.log("productVariant", productVariant) - console.log("contextType", contextType) - - // Merge custom translations if provided - const mergedTranslations = mergeTranslations( - translations, - options.customTranslations - ) - - // Create translator function - const t = createTranslator(locale, mergedTranslations) - - const blocksSections: SlackBlock[] = [] - - if (productVariant?.title) { - blocksSections.push({ - type: "header", - text: { - type: "plain_text", - text: t("header.title", { - productVariantTitle: - productVariant?.title || "unknown", - }), - emoji: true, - }, - }) - } - - const blocks: SlackBlock[] = - blocksSections.length > 0 ? blocksSections : [] - - if (productVariant?.id && productVariant?.product?.id) { - blocks.push({ - type: "actions", - elements: [ - { - type: "button", - text: { - type: "plain_text", - text: t("actions.openInPanel"), - }, - url: `${backendUrl}/app/products/${productVariant.product.id}/variants/${productVariant.id}`, - style: "primary", - }, - ], - }) - } - - blocks.push({ type: "divider" }) - - return { - text: t("headerTitle", { - productVariantId: productVariant?.id || "unknown", - }), - blocks, - } -} diff --git a/src/templates/slack/product-variant/translations/en.json b/src/templates/slack/product-variant/translations/en.json deleted file mode 100644 index d1f0d47..0000000 --- a/src/templates/slack/product-variant/translations/en.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "general": { - "header": { - "title": "Inventory level #{{inventoryItemTitle}} has been updated" - }, - "labels": { - "quantity": "Quantity", - "reservedQuantity": "Reserved Quantity", - "incomingQuantity": "Incoming Quantity", - "availableQuantity": "Available Quantity", - "location": "Location", - "noData": "No data" - }, - "actions": { - "openInPanel": "Open in panel" - } - } -} - diff --git a/src/templates/slack/product-variant/translations/index.ts b/src/templates/slack/product-variant/translations/index.ts deleted file mode 100644 index 6bbe4d8..0000000 --- a/src/templates/slack/product-variant/translations/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import pl from "./pl.json" -import en from "./en.json" - -export const translations: Record = { - pl: pl, - en: en, -} - -export { pl, en } diff --git a/src/templates/slack/product-variant/translations/pl.json b/src/templates/slack/product-variant/translations/pl.json deleted file mode 100644 index f20f546..0000000 --- a/src/templates/slack/product-variant/translations/pl.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "general": { - "header": { - "title": "Wariant produktu {{productVariantTitle}} został zaktualizowany" - }, - "labels": { - "title": "Tytuł" - }, - "actions": { - "openInPanel": "Otwórz w panelu" - } - } -} - diff --git a/src/templates/slack/product/index.ts b/src/templates/slack/product/index.ts deleted file mode 100644 index f7a5bca..0000000 --- a/src/templates/slack/product/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./product" diff --git a/src/templates/slack/product/product.ts b/src/templates/slack/product/product.ts deleted file mode 100644 index 4d3d528..0000000 --- a/src/templates/slack/product/product.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { SlackTemplateOptions, SlackBlock } from "../types" -import { translations } from "./translations" -import { - createTranslator, - mergeTranslations, -} from "../../../utils" - -export interface RenderProductParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export function renderProduct({ - context, - contextType, - options = {}, -}: RenderProductParams): { - text: string - blocks: SlackBlock[] -} { - const backendUrl = options?.backendUrl || "" - const locale = options?.locale || "pl" - const product = context?.product - - console.log("product", product) - console.log("contextType", contextType) - - // Merge custom translations if provided - const mergedTranslations = mergeTranslations( - translations, - options.customTranslations - ) - - // Create translator function - const t = createTranslator(locale, mergedTranslations) - - const blocksSections: SlackBlock[] = [] - - if (product?.title) { - blocksSections.push({ - type: "header", - text: { - type: "plain_text", - text: t("header.title", { - productTitle: product?.title || "unknown", - }), - emoji: true, - }, - }) - } - - const blocks: SlackBlock[] = - blocksSections.length > 0 ? blocksSections : [] - - if (product?.id) { - blocks.push({ - type: "actions", - elements: [ - { - type: "button", - text: { - type: "plain_text", - text: t("actions.openInPanel"), - }, - url: `${backendUrl}/app/products/${product.id}`, - style: "primary", - }, - ], - }) - } - - blocks.push({ type: "divider" }) - - return { - text: t("headerTitle", { - productId: product?.id || "unknown", - }), - blocks, - } -} diff --git a/src/templates/slack/product/translations/en.json b/src/templates/slack/product/translations/en.json deleted file mode 100644 index d1f0d47..0000000 --- a/src/templates/slack/product/translations/en.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "general": { - "header": { - "title": "Inventory level #{{inventoryItemTitle}} has been updated" - }, - "labels": { - "quantity": "Quantity", - "reservedQuantity": "Reserved Quantity", - "incomingQuantity": "Incoming Quantity", - "availableQuantity": "Available Quantity", - "location": "Location", - "noData": "No data" - }, - "actions": { - "openInPanel": "Open in panel" - } - } -} - diff --git a/src/templates/slack/product/translations/index.ts b/src/templates/slack/product/translations/index.ts deleted file mode 100644 index 6bbe4d8..0000000 --- a/src/templates/slack/product/translations/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import pl from "./pl.json" -import en from "./en.json" - -export const translations: Record = { - pl: pl, - en: en, -} - -export { pl, en } diff --git a/src/templates/slack/product/translations/pl.json b/src/templates/slack/product/translations/pl.json deleted file mode 100644 index aafe83a..0000000 --- a/src/templates/slack/product/translations/pl.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "general": { - "header": { - "title": "Produkt {{productTitle}} został zaktualizowany" - }, - "labels": { - "title": "Tytuł" - }, - "actions": { - "openInPanel": "Otwórz w panelu" - } - } -} - diff --git a/src/templates/slack/types.ts b/src/templates/slack/types.ts deleted file mode 100644 index 9654473..0000000 --- a/src/templates/slack/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -export type SlackBlock = { - type: string - [key: string]: any -} - -export interface SlackTemplateOptions { - backendUrl?: string - locale?: string - customTranslations?: Record> - [key: string]: any -} - -export interface SlackTemplateRendererParams { - context: any - contextType?: string | null - options?: SlackTemplateOptions -} - -export type SlackTemplateRenderer = ( - params: SlackTemplateRendererParams -) => - | Promise<{ text: string; blocks: SlackBlock[] }> - | { text: string; blocks: SlackBlock[] } diff --git a/src/utils/types/index.ts b/src/utils/types/index.ts index 2bce076..93d29cf 100644 --- a/src/utils/types/index.ts +++ b/src/utils/types/index.ts @@ -1,2 +1 @@ export * from "../../modules/mpn-automation/types" -export * from "../../templates/slack/types" diff --git a/src/workflows/notifications/steps/send-slack.ts b/src/workflows/notifications/steps/send-slack.ts index cc42d5c..b85e500 100644 --- a/src/workflows/notifications/steps/send-slack.ts +++ b/src/workflows/notifications/steps/send-slack.ts @@ -4,12 +4,11 @@ import { } from "@medusajs/framework/workflows-sdk" import { Modules } from "@medusajs/framework/utils" import type { NotificationContent } from "@medusajs/framework/types" -import type { SlackBlock } from "../../../templates/slack/types" import MpnAutomationService from "../../../modules/mpn-automation/services/service" import { MedusaError } from "@medusajs/utils" type SlackNotificationContent = NotificationContent & { - blocks?: SlackBlock[] + blocks?: any[] } export interface SendSlackConfig { From 50fd1f57481c2b8c07696bb6d2d3a07760d57dd3 Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Tue, 30 Dec 2025 15:18:38 +0100 Subject: [PATCH 3/3] chore: update changeset --- .changeset/swift-pillows-push.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/swift-pillows-push.md diff --git a/.changeset/swift-pillows-push.md b/.changeset/swift-pillows-push.md new file mode 100644 index 0000000..896fd6d --- /dev/null +++ b/.changeset/swift-pillows-push.md @@ -0,0 +1,5 @@ +--- +"@codee-sh/medusa-plugin-automations": patch +--- + +Replace the Slack templates with external plugin