--- displayed_sidebar: homepage --- import TypeList from "@site/src/components/TypeList" # AbstractNotificationService ## Overview :::note[Prerequisites] Before creating a Notification Provider, [install an event bus module](https://docs.medusajs.com/development/events/modules/redis). ::: A Notification Provider is a provider that handles sending and resending of notifications. To create a Notification Provider, create a TypeScript or JavaScript file in `src/services`. The name of the file is the name of the provider (for example, `sendgrid.ts`). The file must export a class that extends the `AbstractNotificationService` class imported from `@medusajs/medusa`. For example, create the file `src/services/email-sender.ts` with the following content: ```ts title="src/services/email-sender.ts" import { AbstractNotificationService } from "@medusajs/medusa" import { EntityManager } from "typeorm" class EmailSenderService extends AbstractNotificationService { protected manager_: EntityManager protected transactionManager_: EntityManager sendNotification( event: string, data: unknown, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record; }> { throw new Error("Method not implemented.") } resendNotification( notification: unknown, config: unknown, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record; }> { throw new Error("Method not implemented.") } } export default EmailSenderService ``` --- ## Identifier Property The `NotificationProvider` entity has 2 properties: `identifier` and `is_installed`. The value of the `identifier` property in the notification provider class is used when the Notification Provider is created in the database. The value of this property is also used later when you want to subscribe the Notification Provider to events in a [Loader](https://docs.medusajs.com/development/loaders/overview). For example: ```ts class EmailSenderService extends AbstractNotificationService { static identifier = "email-sender" // ... } ``` --- ## constructor You can use the `constructor` of your notification provider to access the different services in Medusa through dependency injection. You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party provider’s APIs, you can initialize it in the constructor and use it in other methods in the service. Additionally, if you’re creating your notification provider as an external plugin to be installed on any Medusa backend and you want to access the options added for the plugin, you can access it in the constructor. ### Example ```ts // ... import { AbstractNotificationService, OrderService } from "@medusajs/medusa" import { EntityManager } from "typeorm" class EmailSenderService extends AbstractNotificationService { // ... protected orderService: OrderService constructor(container, options) { super(container) // you can access options here in case you're // using a plugin this.orderService = container.orderService // you can also initialize a client that // communicates with a third-party service. this.client = new Client(options) } // ... } export default EmailSenderService ``` ### Parameters `","description":"An instance of `MedusaContainer` that allows you to access other resources, such as services, in your Medusa backend.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"config","type":"`Record`","description":"If this notification provider is created in a plugin, the plugin's options are passed in this parameter.","optional":true,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records" sectionTitle="new AbstractNotificationService"/> ___ ## Properties `","description":"An instance of `MedusaContainer` that allows you to access other resources, such as services, in your Medusa backend.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"manager_","type":"`EntityManager`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionManager_","type":"`undefined` \\| `EntityManager`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"__container__","type":"`any`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"config","type":"`Record`","description":"If this notification provider is created in a plugin, the plugin's options are passed in this parameter.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"__configModule__","type":"`Record`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"__moduleDeclaration__","type":"`Record`","description":"","optional":true,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records" sectionTitle="AbstractNotificationService"/> ___ ## Accessors ### activeManager\_ #### Returns ___ ## Methods ### sendNotification When an event is triggered that your Notification Provider is registered as a handler for, the [`NotificationService`](https://docs.medusajs.com/references/services/classes/services.NotificationService) in the Medusa backend executes this method of your Notification Provider. In this method, you can perform the necessary operation to send the Notification. For example, you can send an email to the customer when they place an order. #### Example ```ts class EmailSenderService extends AbstractNotificationService { // ... async sendNotification( event: string, data: any, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record; }> { if (event === "order.placed") { // retrieve order const order = await this.orderService.retrieve(data.id) // TODO send email console.log("Notification sent") return { to: order.email, status: "done", data: { // any data necessary to send the email // for example: subject: "You placed a new order!", items: order.items, }, } } } // ... } ``` #### Parameters #### Returns ### resendNotification This method is used to resend notifications, which is typically triggered by the [Resend Notification API Route](https://docs.medusajs.com/api/admin#notifications\_postnotificationsnotificationresend). #### Example ```ts class EmailSenderService extends AbstractNotificationService { // ... async resendNotification( notification: any, config: any, attachmentGenerator: unknown ): Promise<{ to: string; status: string; data: Record; }> { // check if the receiver should be changed const to: string = config.to || notification.to // TODO resend the notification using the same data // that is saved under notification.data console.log("Notification resent") return { to, status: "done", data: notification.data, // make changes to the data } } } ``` #### Parameters #### Returns ### withTransaction #### Parameters #### Returns ### shouldRetryTransaction\_ #### Parameters ` \\| `object`","description":"","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records" sectionTitle="shouldRetryTransaction_"/> #### Returns ### atomicPhase\_ Wraps some work within a transactional block. If the service already has a transaction manager attached this will be reused, otherwise a new transaction manager is created. #### Type Parameters #### Parameters Promise<TResult>","description":"the transactional work to be done","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationOrErrorHandler","type":"`IsolationLevel` \\| (`error`: TError) => Promise<void \\| TResult>","description":"the isolation level to be used for the work.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"maybeErrorHandlerOrDontFail","type":"(`error`: TError) => Promise<void \\| TResult>","description":"Potential error handler","optional":true,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/development/entities/repositories#retrieving-a-list-of-records" sectionTitle="atomicPhase_"/> #### Returns