How to Create a Notification Module Provider
In this document, you’ll learn how to create a Notification Module Provider and the methods you must implement in it.
Implementation Example#
As you implement your Notification Module Provider, it can be useful to refer to an existing provider and how it's implemeted.
If you need to refer to an existing implementation as an example, check the SendGrid Notification Module Provider in the Medusa repository.
1. Create Module Provider Directory#
Start by creating a new directory for your module provider.
If you're creating the module provider in a Medusa application, create it under the src/modules
directory. For example, src/modules/my-notification
.
If you're creating the module provider in a plugin, create it under the src/providers
directory. For example, src/providers/my-notification
.
src/modules/my-notification
directory as an example.2. Create the Notification Module Provider's Service#
Create the file src/modules/my-notification/service.ts
that holds the implementation of the notification service.
The Notification Module Provider's main service must extend the AbstractNotificationProviderService
class imported from @medusajs/framework/utils
:
constructor#
The constructor allows you to access resources from the module's container using the first parameter, and the module's options using the second parameter.
If you're creating a client or establishing a connection with a third-party service, do it in the constructor.
Example
1import { AbstractNotificationProviderService } from "@medusajs/framework/utils"2import { Logger } from "@medusajs/framework/types"3 4type InjectedDependencies = {5 logger: Logger6}7 8type Options = {9 apiKey: string10}11 12class MyNotificationProviderService extends AbstractNotificationProviderService {13 protected logger_: Logger14 protected options_: Options15 // assuming you're initializing a client16 protected client17 18 constructor (19 { logger }: InjectedDependencies,20 options: Options21 ) {22 super()23 24 this.logger_ = logger25 this.options_ = options26 27 // assuming you're initializing a client28 this.client = new Client(options)29 }30}31 32export default MyNotificationProviderService
identifier#
Each notification provider has a unique ID used to identify it.
Example
validateOptions#
This method validates the options of the provider set in medusa-config.ts
.
Implementing this method is optional. It's useful if your provider requires custom validation.
If the options aren't valid, throw an error.
Example
Parameters
options
Record<any, any>send#
This method is used to send a notification using the third-party provider or your custom logic.
Example
1// other imports...2import {3 ProviderSendNotificationDTO,4 ProviderSendNotificationResultsDTO5} from "@medusajs/framework/types"6 7class MyNotificationProviderService extends AbstractNotificationProviderService {8 // ...9 async send(10 notification: ProviderSendNotificationDTO11 ): Promise<ProviderSendNotificationResultsDTO> {12 // TODO send the notification using a third-party13 // provider or custom logic.14 // for example:15 return this.client.send({16 email: notification.to,17 template: notification.template,18 template_data: notification.data19 })20 }21}
Parameters
notification
ProviderSendNotificationDTOThe details of the
notification to send.
notification
ProviderSendNotificationDTOReturns
Promise
Promise<ProviderSendNotificationResultsDTO>The result of sending
the notification.
Promise
Promise<ProviderSendNotificationResultsDTO>3. Create Module Provider Definition File#
Create the file src/modules/my-notification/index.ts
with the following content:
This exports the module provider's definition, indicating that the MyNotificationProviderService
is the module provider's service.
4. Use Module Provider#
To use your Notification Module Provider, add it to the providers
array of the Notification Module in medusa-config.ts
:
1module.exports = defineConfig({2 // ...3 modules: [4 {5 resolve: "@medusajs/medusa/notification",6 options: {7 providers: [8 // default provider9 {10 resolve: "@medusajs/medusa/notification-local",11 id: "local",12 options: {13 name: "Local Notification Provider",14 channels: ["feed"],15 },16 },17 {18 // if module provider is in a plugin, use `plugin-name/providers/my-notification`19 resolve: "./src/modules/my-notification",20 id: "my-notification",21 options: {22 channels: ["email"],23 // provider options...24 },25 },26 ],27 },28 },29 ]30})
Make sure to specify the correct channels for your provider in the channels
option.
5. Test it Out#
Create Subscriber#
To test out the provider, create a subscriber at src/subscribers/user-created.ts
with the following content:
1import { Modules } from "@medusajs/framework/utils"2import {3 SubscriberArgs,4 type SubscriberConfig,5} from "@medusajs/medusa"6 7export default async function userCreatedHandler({8 event: { data },9 container,10}: SubscriberArgs<{ id: string }>) {11 const notificationModuleService = container.resolve(12 Modules.NOTIFICATION13 )14 const userModule = container.resolve(15 Modules.USER16 )17 18 const user = await userModule.retrieveUser(data.id)19 20 await notificationModuleService.createNotifications({21 to: user.email,22 channel: "email",23 template: "new-user"24 })25}26 27export const config: SubscriberConfig = {28 event: "user.created",29}
In the subscriber, you resolve the Notification and User modules. Then, you use the User Module's main service to retrieve the user's details.
Finally, you use the Notification Module's main service to send a notification to the user's email through the email
channel (assuming that's your provider's channel).
Make sure to replace the value of template
to the ID of the template in your provider.
Create User#
Use the following command to create a user:
After the user is created, the subscriber is executed, sending the notification using your provider.