diff --git a/integration-tests/modules/__tests__/notification/admin/notification.spec.ts b/integration-tests/modules/__tests__/notification/admin/notification.spec.ts
index a2f1975f29..a379d3cc2b 100644
--- a/integration-tests/modules/__tests__/notification/admin/notification.spec.ts
+++ b/integration-tests/modules/__tests__/notification/admin/notification.spec.ts
@@ -38,6 +38,10 @@ medusaIntegrationTestRunner({
trigger_type: "order-created",
resource_id: "order-id",
resource_type: "order",
+ content: {
+ subject: "We received you order",
+ html: "
Thank you
",
+ },
} as CreateNotificationDTO
const result = await service.createNotifications(notification)
@@ -67,6 +71,8 @@ medusaIntegrationTestRunner({
})
)
+ expect(result).toHaveProperty("content")
+
expect(fromDB).toEqual(
expect.objectContaining({
to: "test@medusajs.com",
@@ -83,6 +89,8 @@ medusaIntegrationTestRunner({
})
)
+ expect(fromDB).not.toHaveProperty("content")
+
expect(logSpy).toHaveBeenCalledWith(
`Attempting to send a notification to: 'test@medusajs.com' on the channel: 'email' with template: 'order-created' and data: '{\"username\":\"john-doe\"}'`
)
diff --git a/packages/core/types/src/notification/common.ts b/packages/core/types/src/notification/common.ts
index 963eb85347..0c975d9d62 100644
--- a/packages/core/types/src/notification/common.ts
+++ b/packages/core/types/src/notification/common.ts
@@ -176,3 +176,23 @@ export interface FilterableNotificationProps
*/
created_at?: OperatorMap
}
+
+/**
+ * @interface
+ *
+ * The structure for content passed to the notification provider.
+ */
+export interface NotificationContent {
+ /**
+ * the subject of the notification
+ */
+ subject?: string
+ /**
+ * the text content of the notification
+ */
+ text?: string
+ /**
+ * the html content of the notification
+ */
+ html?: string
+}
diff --git a/packages/core/types/src/notification/mutations.ts b/packages/core/types/src/notification/mutations.ts
index 7501f941cf..004fdc4f53 100644
--- a/packages/core/types/src/notification/mutations.ts
+++ b/packages/core/types/src/notification/mutations.ts
@@ -1,3 +1,5 @@
+import { NotificationContent } from "./common"
+
/**
* @interface
*
@@ -21,6 +23,10 @@ export interface CreateNotificationDTO {
* The data that gets passed over to the provider for rendering the notification.
*/
data?: Record | null
+ /**
+ * The content that gets passed over to the provider.
+ */
+ content?: NotificationContent | null
/**
* The event name, the workflow, or anything else that can help to identify what triggered the notification.
*/
diff --git a/packages/core/types/src/notification/provider.ts b/packages/core/types/src/notification/provider.ts
index 1ba8207c39..ff98475376 100644
--- a/packages/core/types/src/notification/provider.ts
+++ b/packages/core/types/src/notification/provider.ts
@@ -1,4 +1,4 @@
-import { Attachment } from "./common"
+import { Attachment, NotificationContent } from "./common"
/**
* @interface
@@ -30,6 +30,10 @@ export type ProviderSendNotificationDTO = {
* The data that gets passed over to the provider for rendering the notification.
*/
data?: Record | null
+ /**
+ * The content that gets passed to the provider.
+ */
+ content?: NotificationContent | null
}
/**
diff --git a/packages/modules/notification/integration-tests/__tests__/notification-module-service/index.spec.ts b/packages/modules/notification/integration-tests/__tests__/notification-module-service/index.spec.ts
index d459436a2d..7865e45559 100644
--- a/packages/modules/notification/integration-tests/__tests__/notification-module-service/index.spec.ts
+++ b/packages/modules/notification/integration-tests/__tests__/notification-module-service/index.spec.ts
@@ -85,6 +85,30 @@ moduleIntegrationTestRunner({
)
})
+ it("should send a notification and don't store the content in the database", async () => {
+ const notification = {
+ to: "admin@medusa.com",
+ template: "signup-template",
+ channel: "email",
+ data: {},
+ content: {
+ html: "Welcome to medusa
",
+ },
+ }
+
+ const result = await service.createNotifications(notification)
+ const dbEntry = await service.retrieveNotification(result.id)
+
+ expect(dbEntry).toEqual(
+ expect.objectContaining({
+ provider_id: "test-provider",
+ external_id: "external_id",
+ status: NotificationStatus.SUCCESS,
+ })
+ )
+ expect(dbEntry).not.toHaveProperty("content")
+ })
+
it("should emit an event when a notification is created", async () => {
const notification = {
to: "admin@medusa.com",
diff --git a/packages/modules/providers/notification-sendgrid/integration-tests/__tests__/services.spec.ts b/packages/modules/providers/notification-sendgrid/integration-tests/__tests__/services.spec.ts
index e312be4447..40ee377b0b 100644
--- a/packages/modules/providers/notification-sendgrid/integration-tests/__tests__/services.spec.ts
+++ b/packages/modules/providers/notification-sendgrid/integration-tests/__tests__/services.spec.ts
@@ -6,6 +6,7 @@ jest.setTimeout(100000)
describe.skip("Sendgrid notification provider", () => {
let sendgridService: SendgridNotificationService
let emailTemplate = ""
+ let emailContent = ""
let to = ""
beforeAll(() => {
sendgridService = new SendgridNotificationService(
@@ -19,6 +20,7 @@ describe.skip("Sendgrid notification provider", () => {
)
emailTemplate = process.env.SENDGRID_TEST_TEMPLATE ?? ""
+ emailContent = `Welcome to medusa`
to = process.env.SENDGRID_TEST_TO ?? ""
})
@@ -35,6 +37,41 @@ describe.skip("Sendgrid notification provider", () => {
expect(resp).toEqual({})
})
+ it("sends an email with the specified email body", async () => {
+ const resp = await sendgridService.send({
+ to,
+ channel: "email",
+ template: "signup-template",
+ content: {
+ subject: "It's a test",
+ html: emailContent,
+ },
+ data: {
+ username: "john-doe",
+ },
+ })
+
+ expect(resp).toEqual({})
+ })
+
+ it("throws an exception if the subject is not present for html content", async () => {
+ const error = await sendgridService
+ .send({
+ to,
+ template: "signup-template",
+ channel: "email",
+ content: { html: emailContent },
+ data: {
+ username: "john-doe",
+ },
+ })
+ .catch((e) => e)
+
+ expect(error.message).toEqual(
+ "Failed to send email: 400 - The subject is required. You can get around this requirement if you use a template with a subject defined or if every personalization has a subject defined."
+ )
+ })
+
it("throws an exception if the template does not exist", async () => {
const error = await sendgridService
.send({
diff --git a/packages/modules/providers/notification-sendgrid/src/services/sendgrid.ts b/packages/modules/providers/notification-sendgrid/src/services/sendgrid.ts
index 987977c89f..23b80d2994 100644
--- a/packages/modules/providers/notification-sendgrid/src/services/sendgrid.ts
+++ b/packages/modules/providers/notification-sendgrid/src/services/sendgrid.ts
@@ -13,6 +13,8 @@ type InjectedDependencies = {
logger: Logger
}
+type MailContent = Required>
+
interface SendgridServiceConfig {
apiKey: string
from: string
@@ -59,14 +61,32 @@ export class SendgridNotificationService extends AbstractNotificationProviderSer
const from = notification.from?.trim() || this.config_.from
+ let mailContent:
+ | MailContent
+ | {
+ templateId: string
+ }
+
+ if ("content" in notification && !!notification.content) {
+ mailContent = {
+ subject: notification.content?.subject,
+ html: notification.content?.html,
+ } as MailContent
+ } else {
+ // we can't mix html and templates for sendgrid
+ mailContent = {
+ templateId: notification.template,
+ }
+ }
+
const message: sendgrid.MailDataRequired = {
to: notification.to,
from: from,
- templateId: notification.template,
dynamicTemplateData: notification.data as
| { [key: string]: any }
| undefined,
attachments: attachments,
+ ...mailContent,
}
try {