Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/swift-pillows-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codee-sh/medusa-plugin-automations": patch
---

Replace the Slack templates with external plugin
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/modules/mpn-automation/services/base-action-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class BaseActionService implements ActionHandler {
*/
registerTemplate(
name: string,
renderer: TemplateRenderer
renderer: any
): void {
this.templates_.set(name, renderer)
}
Expand All @@ -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)
}

Expand Down
32 changes: 17 additions & 15 deletions src/modules/mpn-automation/services/email-action-service.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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: {...} })
// })
}

/**
Expand All @@ -85,10 +89,6 @@ export class EmailActionService extends BaseActionService {
context: TemplateData
contextType?: string | null
options?: TemplateOptionsType
customTemplateFunction?: (
data: TemplateData,
options: TemplateOptionsType
) => React.ReactElement<any>
}): Promise<{
html: string
text: string
Expand All @@ -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,
}
}
}
72 changes: 29 additions & 43 deletions src/modules/mpn-automation/services/slack-action-service.ts
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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: {...} })
// })
}

/**
Expand All @@ -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,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
51 changes: 31 additions & 20 deletions src/providers/slack/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
}
1 change: 0 additions & 1 deletion src/templates/slack/inventory-level/index.ts

This file was deleted.

Loading