Skip to content

Commit

Permalink
feat: Add Mailchain Email Provider novuhq#4336
Browse files Browse the repository at this point in the history
  • Loading branch information
ItIsOHM committed Oct 5, 2023
1 parent 6f8ae28 commit 5c998c2
Show file tree
Hide file tree
Showing 20 changed files with 255 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions libs/shared/src/consts/providers/channels/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
plunkConfig,
sparkpostConfig,
emailWebhookConfig,
mailchainConfig,
} from '../credentials';
import { IProviderConfig } from '../provider.interface';
import { EmailProviderIdEnum } from '../provider.enum';
Expand Down Expand Up @@ -159,4 +160,12 @@ export const emailProviders: IProviderConfig[] = [
docReference: 'https://docs.novu.co/channels/email/email-webhook/',
logoFileName: { light: 'email_webhook.svg', dark: 'email_webhook.svg' },
},
{
id: EmailProviderIdEnum.Mailchain,
displayName: 'Mailchain',
channel: ChannelTypeEnum.EMAIL,
credentials: mailchainConfig,
docReference: 'https://docs.mailchain.com/',
logoFileName: { light: 'mailchain.png', dark: 'mailchain.png' },
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -740,3 +740,14 @@ export const sendchampConfig: IConfigCredentials[] = [
},
...smsConfigBase,
];

export const mailchainConfig: IConfigCredentials[] = [
{
key: CredentialsKeyEnum.SecretPhrase,
displayName: '24 word mnemonic phrase. ',
description: 'This phrase is used to initialise the Mailchain SDK',
type: 'string',
required: true,
},
...mailConfigBase,
];
2 changes: 2 additions & 0 deletions libs/shared/src/consts/providers/provider.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum CredentialsKeyEnum {
RedirectUrl = 'redirectUrl',
Hmac = 'hmac',
IpPoolName = 'ipPoolName',
SecretPhrase = 'secretPhrase',
}

export enum EmailProviderIdEnum {
Expand All @@ -49,6 +50,7 @@ export enum EmailProviderIdEnum {
Novu = 'novu-email',
SparkPost = 'sparkpost',
EmailWebhook = 'email-webhook',
Mailchain = 'mailchain',
}

export enum SmsProviderIdEnum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export interface ICredentials {
redirectUrl?: string;
hmac?: boolean;
ipPoolName?: string;
secretPhrase?: string;
}
1 change: 1 addition & 0 deletions packages/application-generic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@novu/gupshup": "^0.20.0-alpha.0",
"@novu/infobip": "^0.20.0-alpha.0",
"@novu/kannel": "^0.20.0-alpha.0",
"@novu/mailchain" : "0.16.3",
"@novu/mailersend": "^0.20.0-alpha.0",
"@novu/mailgun": "^0.20.0-alpha.0",
"@novu/mailjet": "^0.20.0-alpha.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from './plunk.handler';
export * from './sparkpost.handler';
export * from './email-webhook.handler';
export * from './novu.handler';
export * from './mailchain.handler';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ChannelTypeEnum, ICredentialsDto, ICredentials } from '@novu/shared';
import { MailchainEmailProvider } from '@novu/mailchain';
import { BaseHandler } from './base.handler';

export class MailchainHandler extends BaseHandler {
constructor() {
super('mailchain', ChannelTypeEnum.EMAIL);
}

buildProvider(credentials: ICredentials, from?: string) {
const config: { secretRecoveryPhrase: string; from: string } = {
secretRecoveryPhrase: credentials.secretPhrase,
from: credentials.from,
};

this.provider = new MailchainEmailProvider(config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
EmailWebhookHandler,
NovuEmailHandler,
PlunkHandler,
MailchainHandler,
} from './handlers';
import { IMailHandler } from './interfaces/send.handler.interface';

Expand All @@ -41,6 +42,7 @@ export class MailFactory {
new SparkPostHandler(),
new EmailWebhookHandler(),
new NovuEmailHandler(),
new MailchainHandler(),
];

getHandler(
Expand Down
3 changes: 3 additions & 0 deletions providers/mailchain/.czrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"path": "cz-conventional-changelog"
}
3 changes: 3 additions & 0 deletions providers/mailchain/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc.js"
}
9 changes: 9 additions & 0 deletions providers/mailchain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Novu Mailchain Provider

A Mailchain email provider library for [@novu/node](https://github.com/novuhq/novu)

## Usage

```javascript
FILL IN THE INITIALIZATION USAGE
```
5 changes: 5 additions & 0 deletions providers/mailchain/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
82 changes: 82 additions & 0 deletions providers/mailchain/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"name": "@novu/mailchain",
"version": "0.16.3",
"description": "A mailchain wrapper for novu",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
"module": "build/module/index.js",
"private": false,
"repository": "https://github.com/novuhq/novu",
"license": "MIT",
"keywords": [],
"scripts": {
"prebuild": "rimraf build",
"build": "run-p build:*",
"build:main": "tsc -p tsconfig.json",
"build:module": "tsc -p tsconfig.module.json",
"fix": "run-s fix:*",
"fix:prettier": "prettier \"src/**/*.ts\" --write",
"fix:lint": "eslint src --ext .ts --fix",
"test": "run-s test:*",
"lint": "eslint src --ext .ts",
"test:unit": "jest src",
"watch:build": "tsc -p tsconfig.json -w",
"watch:test": "jest src --watch",
"reset-hard": "git clean -dfx && git reset --hard && yarn",
"prepare-release": "run-s reset-hard test"
},
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=13.0.0 <17.0.0",
"pnpm": "^7.26.0"
},
"dependencies": {
"@mailchain/sdk": "^0.25.0",
"@novu/stateless": "0.16.3"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "~1.0.1",
"@types/jest": "~27.5.2",
"cspell": "~6.19.2",
"jest": "~27.5.1",
"npm-run-all": "^4.1.5",
"nyc": "~15.1.0",
"prettier": "~2.8.0",
"rimraf": "~3.0.2",
"ts-jest": "~27.1.5",
"ts-node": "~10.9.1",
"typescript": "4.9.5"
},
"files": [
"build/main",
"build/module",
"!**/*.spec.*",
"!**/*.json",
"CHANGELOG.md",
"LICENSE",
"README.md"
],
"ava": {
"failFast": true,
"timeout": "60s",
"typescript": {
"rewritePaths": {
"src/": "build/main/"
}
},
"files": [
"!build/module/**"
]
},
"prettier": {
"singleQuote": true
},
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"exclude": [
"**/*.spec.js"
]
}
}
1 change: 1 addition & 0 deletions providers/mailchain/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/mailchain.provider';
3 changes: 3 additions & 0 deletions providers/mailchain/src/lib/mailchain.provider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { MailchainEmailProvider } from './mailchain.provider';

test('should trigger mailchain library correctly', async () => {});
85 changes: 85 additions & 0 deletions providers/mailchain/src/lib/mailchain.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
ChannelTypeEnum,
ISendMessageSuccessResponse,
IEmailOptions,
IEmailProvider,
ICheckIntegrationResponse,
IEmailEventBody,
CheckIntegrationResponseEnum,
} from '@novu/stateless';
import { Mailchain, SendMailParams } from '@mailchain/sdk';

export class MailchainEmailProvider implements IEmailProvider {
id = 'mailchain';
channelType = ChannelTypeEnum.EMAIL as ChannelTypeEnum.EMAIL;
private mailchainClient: Mailchain;

constructor(
private config: {
secretRecoveryPhrase: string;
from: string;
}
) {
this.mailchainClient = Mailchain.fromSecretRecoveryPhrase(
config.secretRecoveryPhrase
);
}

getMessageId?: (body: any) => string[];
parseEventBody?: (body: any, identifier: string) => IEmailEventBody;

async checkIntegration(
options: IEmailOptions
): Promise<ICheckIntegrationResponse> {
try {
const user = await this.mailchainClient.user();
await this.mailchainClient.sendMail({
from: user.address || this.config.from,
to: options.to,
subject: options.subject,
content: {
text: options.text,
html: options.html,
},
});

return {
success: true,
message: 'Integrated successfully!',
code: CheckIntegrationResponseEnum.SUCCESS,
};
} catch (error) {
return {
success: false,
message: error?.message,
code: CheckIntegrationResponseEnum.FAILED,
};
}
}

async sendMessage(
options: IEmailOptions
): Promise<ISendMessageSuccessResponse> {
const user = await this.mailchainClient.user();
console.log(`username: ${user.username}, address: ${user.address}`);

const result = await this.mailchainClient.sendMail({
from: user.address || this.config.from,
to: options.to,
subject: options.subject,
content: {
text: options.text,
html: options.html,
},
});

console.log(result.data);

const savedMessageId = '12345';

return {
id: savedMessageId,
date: new Date().toISOString(),
};
}
}
10 changes: 10 additions & 0 deletions providers/mailchain/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "build/main",
"rootDir": "src",
"types": ["node", "jest"]
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules/**"]
}
9 changes: 9 additions & 0 deletions providers/mailchain/tsconfig.module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"target": "esnext",
"outDir": "build/module",
"module": "esnext"
},
"exclude": ["node_modules/**"]
}

0 comments on commit 5c998c2

Please sign in to comment.