How to add a new provider?
Novu currently supports five channelsin_app, push, email, chat and sms.
For in_app we support only our own provider, so new providers cannot be added to this channel. For the other four channels, we support the integration of external providers. This guide will help in adding new providers for any of these 4 channels.
In this guide, we are adding a new provider for the email channel, but all of the mentioned steps are similar for other channels as well.
Description
Providers allow us to handle message delivery over multiple channels. We have multiple providers for each channel (SMS, Email, Push and Chat). To get started with adding a new provider let’s look at setting up our repository.Requirements
- Node.js version v20.8.1
- MongoDB
- Redis
- (Optional) pnpm - Needed if you want to install new packages
- (Optional) localstack (required only in S3 related modules)
We have used pnpm package manager in this guide. You can use npm as well.
Initialization
Fork the novu repository and clone it in your local machine.node package to get started.
Generate provider
After the project is initialized, a new provider can be generated using the below command. Use the above command at the root of the project.
up and down arrow to switch channel type and press enter to select.
For this example, we will be selecting EMAIL as our provider type. The name for our provider will be example-provider.
example-provider is generated in your local machine project.
In above example, we have given our provider name as example-provider for simplicity. If provider you want to add have name as twilio, don’t use twilio-provider as name, instead use twilio only. If one provider supports multiple channels like infobip supports both sms and email channels, use infobip-email or infobip-sms to differentiate these providers.Once our
example-provider is generated we will need to begin working from within /providers/example-provider directory. Make sure to write the test for this new provider.
providers/example-provider/src/lib/example-provider.provider.ts
Template test case for example-provider.
providers/example-provider/src/lib/example-provider.provider.sepc.ts
Add the provider’s SDK as a dependency in the provider’s package.json file. Run
pnpm run setup:project to build all dependencies again. Use this new sdk method to complete the provider’s sendMessage function. Check the reference links for adding new providers section for each channel’s provider example. Add provider logos
In order to present this new provider in theintegration store we need logos in dark and light mode. Add dark color svg logo in apps/web/public/static/images/providers/dark/sqaure directory and light color svg logo in apps/web/public/static/images/providers/light/sqaure directory.
Use the provider name as the file name. The sample name for our above-added provider is example-provider.svg.
Add config items to the list
In order to build the UI integration store, we need to provide it list of all provider integrations. This part is made up of two parts:- Create credentials config
- Add ProviderId Enum
- Add provider configuration to the providers list
1. Create credentials config
Every provider requires some credentials to create an instance. Novu will add these credentials fields in the integration store provider’s form so that users can use their credentials to connect to their preferred provider to use for that channel notification. For example, in the above addedexample-provider, we have only one credential ApiKey. We will need to add a config object for example-provider with all existing provider’s configs like below.
libs/shared/src/consts/providers/credentials/provider-credentials.ts
- Here the
keyis of typeCredentialsKeyEnum.
If a new key is added, add this key at these 3 places:-
- In
CredentialsKeyEnumat filelibs/shared/src/consts/providers/provider.enum.ts- In
CredentialsDtoat fileapps/api/src/app/integrations/dtos/credentials.dto.ts- In
credentialsfield ofintegrationSchemaat filelibs/dal/src/repositories/integration/integration.schema.ts
displayNameis a human-friendly easy to understand name which will be shown in the provider integration form for this credential.descriptionis a field that can be used to share more information about the credential.typehere means text field type. this can be a string for text, text for text-area, or a switch for the toggle.requiredis of boolean type.mailConfigBaseis an object having default credentials required by anyemailprovider. Make sure not to add duplicate providers which are already there inmailConfigBase. In the case of another channel provider, we will use that channel config base in place ofmailConfigBase.
A credential can be made secret by adding in ./secure-credentials.ts file.
2. Add ProviderId Enum
Add this new provider id in the respective channel provider id enum in filelibs/shared/src/consts/providers/provider.enum.ts. As our example-provider is of email type, add this in EmailProviderIdEnum with all existing providers like below
libs/shared/src/consts/providers/provider.enum.ts
3. Add provider to providers list
Now we need to add the provider data to the list located atlibs/shared/src/consts/providers/channels/email.ts. Note that the id is the provider’s name, displayName is the provider’s name in Pascal’s case, credentials are the ones we created in the previous step, logoFileName should be as it was on the adding logo step (with the format type included).
libs/shared/src/consts/providers/channels/email.ts
Add provider handler in the API
1. Adding the provider dependency in the application-generic package
In the previous step, we created a standalone provider package that will be published to NPM. However currently in our development environment, it is not yet published. In order to use it locally please go to thepackage.json located in packages/application-generic/package.json and add it manually to the dependencies list: "@novu/<NEW_PROVIDER_NAME>": "^<VERSION>"
Please note that the provider name and version can be found from the provider package.json you created earlier.After adding the dependency run
pnpm run setup:project from the root of the mono repo. so, it can create the required symlinks for the newly created package.
2. Create a provider handler
In order to map internally the different providers’ credentials, we need to add a provider handler at the respective channel handlers located. For Email, it can be found atapps/packages/application-generic/src/factories/mail/handlers. Other channel handlers can also be found here.
Create a new file example-provider.handler.ts here with the following code
packages/application-generic/src/factories/mail/handlers/example-provider.handler.ts
packages/application-generic/src/factories/mail/handlers/index.ts
3. Add handler to factory
The last step is to initialize the handler in the factory located inpackages/application-generic/src/factories/mail/mail.factory.ts
packages/application-generic/src/factories/mail/mail.factory.ts
Final Steps
Now, build the project again using this command️ In this guide, we have used only one credential
apiKey for our example-provider. This is for reference purposes only. A provider can have more than one credential as per its SDK requirements. At each step, you will need to add all credentials carefully. Check providers referenced below for more information.