@hedhog/mail 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/enums/mail-configuration-type.enum.d.ts +5 -0
- package/dist/enums/mail-configuration-type.enum.d.ts.map +1 -0
- package/dist/enums/mail-configuration-type.enum.js +9 -0
- package/dist/enums/mail-configuration-type.enum.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/mail-module-options.interface.d.ts +13 -0
- package/dist/interfaces/mail-module-options.interface.d.ts.map +1 -0
- package/dist/interfaces/mail-module-options.interface.js +3 -0
- package/dist/interfaces/mail-module-options.interface.js.map +1 -0
- package/dist/interfaces/mail-type.d.ts +13 -0
- package/dist/interfaces/mail-type.d.ts.map +1 -0
- package/dist/interfaces/mail-type.js +3 -0
- package/dist/interfaces/mail-type.js.map +1 -0
- package/dist/mail.consts.d.ts +17 -0
- package/dist/mail.consts.d.ts.map +1 -0
- package/dist/mail.consts.js +5 -0
- package/dist/mail.consts.js.map +1 -0
- package/dist/mail.module.d.ts +6 -0
- package/dist/mail.module.d.ts.map +1 -0
- package/dist/mail.module.js +37 -0
- package/dist/mail.module.js.map +1 -0
- package/dist/mail.service.d.ts +14 -0
- package/dist/mail.service.d.ts.map +1 -0
- package/dist/mail.service.js +247 -0
- package/dist/mail.service.js.map +1 -0
- package/dist/mail.service.spec.d.ts +2 -0
- package/dist/mail.service.spec.d.ts.map +1 -0
- package/dist/mail.service.spec.js +17 -0
- package/dist/mail.service.spec.js.map +1 -0
- package/package.json +13 -0
- package/src/enums/mail-configuration-type.enum.ts +4 -0
- package/src/index.ts +2 -0
- package/src/interfaces/mail-module-options.interface.ts +13 -0
- package/src/interfaces/mail-type.ts +12 -0
- package/src/mail.consts.ts +20 -0
- package/src/mail.module.ts +26 -0
- package/src/mail.service.spec.ts +18 -0
- package/src/mail.service.ts +256 -0
- package/tsconfig.lib.json +9 -0
- package/tsconfig.production.json +20 -0
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-configuration-type.enum.d.ts","sourceRoot":"","sources":["../../src/enums/mail-configuration-type.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,yBAAyB;IACjC,GAAG,QAAQ;IACX,KAAK,UAAU;CAClB"}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.MailConfigurationTypeEnum = void 0;
|
4
|
+
var MailConfigurationTypeEnum;
|
5
|
+
(function (MailConfigurationTypeEnum) {
|
6
|
+
MailConfigurationTypeEnum["AWS"] = "AWS";
|
7
|
+
MailConfigurationTypeEnum["GMAIL"] = "GMAIL";
|
8
|
+
})(MailConfigurationTypeEnum || (exports.MailConfigurationTypeEnum = MailConfigurationTypeEnum = {}));
|
9
|
+
//# sourceMappingURL=mail-configuration-type.enum.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-configuration-type.enum.js","sourceRoot":"","sources":["../../src/enums/mail-configuration-type.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,wCAAW,CAAA;IACX,4CAAe,CAAA;AACnB,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./mail.module"), exports);
|
18
|
+
__exportStar(require("./mail.service"), exports);
|
19
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,iDAA+B"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { MailConfigurationTypeEnum } from "../enums/mail-configuration-type.enum";
|
2
|
+
export interface MailModuleOptions {
|
3
|
+
global?: boolean;
|
4
|
+
mailConfigurationType: MailConfigurationTypeEnum;
|
5
|
+
host?: string;
|
6
|
+
from?: string;
|
7
|
+
accessKeyId?: string;
|
8
|
+
secretAccessKey?: string;
|
9
|
+
clientId?: string;
|
10
|
+
clientSecret?: string;
|
11
|
+
refreshToken?: string;
|
12
|
+
}
|
13
|
+
//# sourceMappingURL=mail-module-options.interface.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-module-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/mail-module-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,yBAAyB,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-module-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/mail-module-options.interface.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
export interface MailType {
|
2
|
+
from?: string;
|
3
|
+
to: string | string[];
|
4
|
+
cc?: string | string[];
|
5
|
+
bcc?: string | string[];
|
6
|
+
subject?: string;
|
7
|
+
body?: string;
|
8
|
+
replyTo?: string | string[];
|
9
|
+
priority?: string;
|
10
|
+
createdAt?: string;
|
11
|
+
updatedAt?: string;
|
12
|
+
}
|
13
|
+
//# sourceMappingURL=mail-type.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-type.d.ts","sourceRoot":"","sources":["../../src/interfaces/mail-type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail-type.js","sourceRoot":"","sources":["../../src/interfaces/mail-type.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { MailType } from './interfaces/mail-type';
|
2
|
+
export type MailAttachment = {
|
3
|
+
filename?: string;
|
4
|
+
content?: Buffer;
|
5
|
+
contentType?: string;
|
6
|
+
};
|
7
|
+
export type Mail = {
|
8
|
+
attachments?: MailAttachment[];
|
9
|
+
} & MailType;
|
10
|
+
export type MailConfig = {
|
11
|
+
host?: string;
|
12
|
+
from?: string;
|
13
|
+
accessKeyId?: string;
|
14
|
+
secretAccessKey?: string;
|
15
|
+
};
|
16
|
+
export declare const MAIL_MODULE_OPTIONS = "MAIL_MODULE_OPTIONS";
|
17
|
+
//# sourceMappingURL=mail.consts.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.consts.d.ts","sourceRoot":"","sources":["../src/mail.consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC,GAAG,QAAQ,CAAC;AAEb,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,wBAAwB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.consts.js","sourceRoot":"","sources":["../src/mail.consts.ts"],"names":[],"mappings":";;;AAmBa,QAAA,mBAAmB,GAAG,qBAAqB,CAAC"}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
2
|
+
import { MailModuleOptions } from './interfaces/mail-module-options.interface';
|
3
|
+
export declare class MailModule {
|
4
|
+
static init(options: MailModuleOptions): DynamicModule;
|
5
|
+
}
|
6
|
+
//# sourceMappingURL=mail.module.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.module.d.ts","sourceRoot":"","sources":["../src/mail.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAK/E,qBAKa,UAAU;IACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa;CAYvD"}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
7
|
+
};
|
8
|
+
var MailModule_1;
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
exports.MailModule = void 0;
|
11
|
+
const common_1 = require("@nestjs/common");
|
12
|
+
const mail_service_1 = require("./mail.service");
|
13
|
+
const mail_consts_1 = require("./mail.consts");
|
14
|
+
const axios_1 = require("@nestjs/axios");
|
15
|
+
let MailModule = MailModule_1 = class MailModule {
|
16
|
+
static init(options) {
|
17
|
+
return {
|
18
|
+
module: MailModule_1,
|
19
|
+
global: options.global,
|
20
|
+
providers: [
|
21
|
+
{
|
22
|
+
provide: mail_consts_1.MAIL_MODULE_OPTIONS,
|
23
|
+
useValue: options || {},
|
24
|
+
},
|
25
|
+
],
|
26
|
+
};
|
27
|
+
}
|
28
|
+
};
|
29
|
+
exports.MailModule = MailModule;
|
30
|
+
exports.MailModule = MailModule = MailModule_1 = __decorate([
|
31
|
+
(0, common_1.Module)({
|
32
|
+
imports: [axios_1.HttpModule],
|
33
|
+
providers: [mail_service_1.MailService],
|
34
|
+
exports: [mail_service_1.MailService],
|
35
|
+
})
|
36
|
+
], MailModule);
|
37
|
+
//# sourceMappingURL=mail.module.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.module.js","sourceRoot":"","sources":["../src/mail.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,iDAA6C;AAG7C,+CAAoD;AACpD,yCAAwD;AAOjD,IAAM,UAAU,kBAAhB,MAAM,UAAU;IACrB,MAAM,CAAC,IAAI,CAAC,OAA0B;QACpC,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,iCAAmB;oBAC5B,QAAQ,EAAE,OAAO,IAAI,EAAE;iBACxB;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAbY,gCAAU;qBAAV,UAAU;IALtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,kBAAU,CAAC;QACrB,SAAS,EAAE,CAAC,0BAAW,CAAC;QACxB,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAatB"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { Mail } from './mail.consts';
|
2
|
+
import { SES } from 'aws-sdk';
|
3
|
+
import { MailModuleOptions } from './interfaces/mail-module-options.interface';
|
4
|
+
import { HttpService } from '@nestjs/axios';
|
5
|
+
export declare class MailService {
|
6
|
+
private readonly mailConfig;
|
7
|
+
private readonly httpService;
|
8
|
+
constructor(mailConfig: MailModuleOptions, httpService: HttpService);
|
9
|
+
send(mail: Mail): Promise<void>;
|
10
|
+
createRawEmail(mail: Mail): Promise<string>;
|
11
|
+
sendWithGmail(mail: Mail): Promise<import("axios").AxiosResponse<any, any>>;
|
12
|
+
sendWithSES(mail: Mail): Promise<import("aws-sdk/lib/request").PromiseResult<SES.SendRawEmailResponse, import("aws-sdk").AWSError>>;
|
13
|
+
}
|
14
|
+
//# sourceMappingURL=mail.service.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.service.d.ts","sourceRoot":"","sources":["../src/mail.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAuB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,qBACa,WAAW;IAES,OAAO,CAAC,QAAQ,CAAC,UAAU;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADkB,UAAU,EAAE,iBAAiB,EAC1D,WAAW,EAAE,WAAW;IAGrC,IAAI,CAAC,IAAI,EAAE,IAAI;IAYf,cAAc,CAAC,IAAI,EAAE,IAAI;IAyEzB,aAAa,CAAC,IAAI,EAAE,IAAI;IAqCxB,WAAW,CAAC,IAAI,EAAE,IAAI;CAoH7B"}
|
@@ -0,0 +1,247 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
23
|
+
};
|
24
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
25
|
+
if (mod && mod.__esModule) return mod;
|
26
|
+
var result = {};
|
27
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
28
|
+
__setModuleDefault(result, mod);
|
29
|
+
return result;
|
30
|
+
};
|
31
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
32
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
33
|
+
};
|
34
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
35
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
36
|
+
};
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
38
|
+
exports.MailService = void 0;
|
39
|
+
const common_1 = require("@nestjs/common");
|
40
|
+
const mail_consts_1 = require("./mail.consts");
|
41
|
+
const aws_sdk_1 = require("aws-sdk");
|
42
|
+
const mimemessage = __importStar(require("mimemessage"));
|
43
|
+
const mail_configuration_type_enum_1 = require("./enums/mail-configuration-type.enum");
|
44
|
+
const googleapis_1 = require("googleapis");
|
45
|
+
const axios_1 = require("@nestjs/axios");
|
46
|
+
const rxjs_1 = require("rxjs");
|
47
|
+
let MailService = class MailService {
|
48
|
+
constructor(mailConfig, httpService) {
|
49
|
+
this.mailConfig = mailConfig;
|
50
|
+
this.httpService = httpService;
|
51
|
+
}
|
52
|
+
async send(mail) {
|
53
|
+
switch (this.mailConfig.mailConfigurationType) {
|
54
|
+
case mail_configuration_type_enum_1.MailConfigurationTypeEnum.AWS:
|
55
|
+
await this.sendWithSES(mail);
|
56
|
+
break;
|
57
|
+
case mail_configuration_type_enum_1.MailConfigurationTypeEnum.GMAIL:
|
58
|
+
await this.sendWithGmail(mail);
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
async createRawEmail(mail) {
|
63
|
+
var _a;
|
64
|
+
if (mail.attachments instanceof Array && ((_a = mail.attachments) === null || _a === void 0 ? void 0 : _a.length)) {
|
65
|
+
const mailContent = mimemessage.factory({
|
66
|
+
contentType: 'multipart/mixed',
|
67
|
+
body: [],
|
68
|
+
});
|
69
|
+
mailContent.header('From', mail.from);
|
70
|
+
mailContent.header('To', mail.to);
|
71
|
+
mailContent.header('Subject', mail.subject);
|
72
|
+
const alternateEntity = mimemessage.factory({
|
73
|
+
contentType: 'multipart/alternate',
|
74
|
+
body: [],
|
75
|
+
});
|
76
|
+
const htmlEntity = mimemessage.factory({
|
77
|
+
contentType: 'text/html;charset=utf-8',
|
78
|
+
body: mail.body,
|
79
|
+
});
|
80
|
+
alternateEntity.body.push(htmlEntity);
|
81
|
+
mailContent.body.push(alternateEntity);
|
82
|
+
await Promise.all(mail.attachments.map(async (attachment) => {
|
83
|
+
const attachmentEntity = mimemessage.factory({
|
84
|
+
contentType: attachment.contentType,
|
85
|
+
contentTransferEncoding: 'base64',
|
86
|
+
body: attachment.content
|
87
|
+
.toString('base64')
|
88
|
+
.replace(/([^\0]{76})/g, '$1\n'),
|
89
|
+
});
|
90
|
+
attachmentEntity.header('Content-Disposition', `attachment; filename="${attachment.filename}"`);
|
91
|
+
mailContent.body.push(attachmentEntity);
|
92
|
+
}));
|
93
|
+
const messageString = mailContent.toString();
|
94
|
+
const encodedMessage = Buffer.from(messageString)
|
95
|
+
.toString('base64')
|
96
|
+
.replace(/\+/g, '-')
|
97
|
+
.replace(/\//g, '_')
|
98
|
+
.replace(/=+$/, '');
|
99
|
+
return encodedMessage;
|
100
|
+
}
|
101
|
+
else {
|
102
|
+
const messageParts = [
|
103
|
+
`From: ${mail.from}`,
|
104
|
+
`To: ${mail.to instanceof Array ? mail.to.join(',') : mail.to}`,
|
105
|
+
`Subject: ${mail.subject}`,
|
106
|
+
'Content-Type: text/plain; charset="UTF-8"',
|
107
|
+
'',
|
108
|
+
mail.body,
|
109
|
+
];
|
110
|
+
const message = messageParts.join('\n');
|
111
|
+
const encodedMessage = Buffer.from(message)
|
112
|
+
.toString('base64')
|
113
|
+
.replace(/\+/g, '-')
|
114
|
+
.replace(/\//g, '_')
|
115
|
+
.replace(/=+$/, '');
|
116
|
+
return encodedMessage;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
async sendWithGmail(mail) {
|
120
|
+
const { clientId, clientSecret, from, refreshToken } = this.mailConfig;
|
121
|
+
const redirectURI = 'https://developers.google.com/oauthplayground';
|
122
|
+
const oauth2Client = new googleapis_1.google.auth.OAuth2(clientId, clientSecret, redirectURI);
|
123
|
+
oauth2Client.setCredentials({
|
124
|
+
refresh_token: refreshToken,
|
125
|
+
});
|
126
|
+
const { token } = await oauth2Client.getAccessToken();
|
127
|
+
const raw = await this.createRawEmail(Object.assign(Object.assign({}, mail), { from }));
|
128
|
+
const url = 'https://www.googleapis.com/gmail/v1/users/me/messages/send';
|
129
|
+
const requestBody = {
|
130
|
+
raw,
|
131
|
+
};
|
132
|
+
const headers = {
|
133
|
+
Authorization: `Bearer ${token}`,
|
134
|
+
'Content-Type': 'application/json',
|
135
|
+
};
|
136
|
+
const response = this.httpService.post(url, requestBody, { headers });
|
137
|
+
return (0, rxjs_1.firstValueFrom)(response);
|
138
|
+
}
|
139
|
+
async sendWithSES(mail) {
|
140
|
+
const { host, from, accessKeyId, secretAccessKey } = this.mailConfig;
|
141
|
+
const ses = new aws_sdk_1.SES({
|
142
|
+
apiVersion: '2010-12-01',
|
143
|
+
region: host.split('.')[1],
|
144
|
+
credentials: {
|
145
|
+
accessKeyId,
|
146
|
+
secretAccessKey,
|
147
|
+
},
|
148
|
+
});
|
149
|
+
ses.config.update({
|
150
|
+
credentials: {
|
151
|
+
accessKeyId,
|
152
|
+
secretAccessKey,
|
153
|
+
},
|
154
|
+
});
|
155
|
+
if (typeof mail.to === 'string') {
|
156
|
+
mail.to = mail.to.split(';');
|
157
|
+
}
|
158
|
+
if (typeof mail.bcc === 'string') {
|
159
|
+
mail.bcc = mail.bcc.split(';');
|
160
|
+
}
|
161
|
+
else if (!mail.bcc) {
|
162
|
+
mail.bcc = [];
|
163
|
+
}
|
164
|
+
if (typeof mail.cc === 'string') {
|
165
|
+
mail.cc = mail.cc.split(';');
|
166
|
+
}
|
167
|
+
else if (!mail.cc) {
|
168
|
+
mail.cc = [];
|
169
|
+
}
|
170
|
+
if (typeof mail.replyTo === 'string') {
|
171
|
+
mail.replyTo = mail.replyTo.split(';');
|
172
|
+
}
|
173
|
+
else if (!mail.replyTo) {
|
174
|
+
mail.replyTo = [];
|
175
|
+
}
|
176
|
+
if (mail.attachments instanceof Array && mail.attachments.length > 0) {
|
177
|
+
const mailContent = mimemessage.factory({
|
178
|
+
contentType: 'multipart/mixed',
|
179
|
+
body: [],
|
180
|
+
});
|
181
|
+
mailContent.header('From', from);
|
182
|
+
mailContent.header('To', mail.to);
|
183
|
+
mailContent.header('Subject', mail.subject);
|
184
|
+
const alternateEntity = mimemessage.factory({
|
185
|
+
contentType: 'multipart/alternate',
|
186
|
+
body: [],
|
187
|
+
});
|
188
|
+
const htmlEntity = mimemessage.factory({
|
189
|
+
contentType: 'text/html;charset=utf-8',
|
190
|
+
body: mail.body,
|
191
|
+
});
|
192
|
+
alternateEntity.body.push(htmlEntity);
|
193
|
+
mailContent.body.push(alternateEntity);
|
194
|
+
await Promise.all(mail.attachments.map((item) => {
|
195
|
+
const attachmentEntity = mimemessage.factory({
|
196
|
+
contentType: item.contentType,
|
197
|
+
contentTransferEncoding: 'base64',
|
198
|
+
body: item.content
|
199
|
+
.toString('base64')
|
200
|
+
.replace(/([^\0]{76})/g, '$1\n'),
|
201
|
+
});
|
202
|
+
attachmentEntity.header('Content-Disposition', `attachment ;filename="${item.filename}"`);
|
203
|
+
mailContent.body.push(attachmentEntity);
|
204
|
+
}));
|
205
|
+
return ses
|
206
|
+
.sendRawEmail({
|
207
|
+
RawMessage: { Data: mailContent.toString() },
|
208
|
+
})
|
209
|
+
.promise();
|
210
|
+
}
|
211
|
+
else {
|
212
|
+
const params = {
|
213
|
+
Destination: {
|
214
|
+
ToAddresses: mail.to,
|
215
|
+
BccAddresses: mail.bcc,
|
216
|
+
CcAddresses: mail.cc,
|
217
|
+
},
|
218
|
+
Message: {
|
219
|
+
Body: {
|
220
|
+
Html: {
|
221
|
+
Data: mail.body,
|
222
|
+
Charset: 'utf-8',
|
223
|
+
},
|
224
|
+
Text: {
|
225
|
+
Data: mail.body,
|
226
|
+
Charset: 'utf-8',
|
227
|
+
},
|
228
|
+
},
|
229
|
+
Subject: {
|
230
|
+
Data: mail.subject,
|
231
|
+
Charset: 'utf-8',
|
232
|
+
},
|
233
|
+
},
|
234
|
+
ReplyToAddresses: mail.replyTo,
|
235
|
+
Source: from,
|
236
|
+
};
|
237
|
+
return ses.sendEmail(params).promise();
|
238
|
+
}
|
239
|
+
}
|
240
|
+
};
|
241
|
+
exports.MailService = MailService;
|
242
|
+
exports.MailService = MailService = __decorate([
|
243
|
+
(0, common_1.Injectable)(),
|
244
|
+
__param(0, (0, common_1.Inject)(mail_consts_1.MAIL_MODULE_OPTIONS)),
|
245
|
+
__metadata("design:paramtypes", [Object, axios_1.HttpService])
|
246
|
+
], MailService);
|
247
|
+
//# sourceMappingURL=mail.service.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.service.js","sourceRoot":"","sources":["../src/mail.service.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.service.spec.d.ts","sourceRoot":"","sources":["../src/mail.service.spec.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const testing_1 = require("@nestjs/testing");
|
4
|
+
const mail_service_1 = require("./mail.service");
|
5
|
+
describe('MailService', () => {
|
6
|
+
let service;
|
7
|
+
beforeEach(async () => {
|
8
|
+
const module = await testing_1.Test.createTestingModule({
|
9
|
+
providers: [mail_service_1.MailService],
|
10
|
+
}).compile();
|
11
|
+
service = module.get(mail_service_1.MailService);
|
12
|
+
});
|
13
|
+
it('should be defined', () => {
|
14
|
+
expect(service).toBeDefined();
|
15
|
+
});
|
16
|
+
});
|
17
|
+
//# sourceMappingURL=mail.service.spec.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"mail.service.spec.js","sourceRoot":"","sources":["../src/mail.service.spec.ts"],"names":[],"mappings":";;AAAA,6CAAsD;AACtD,iDAA6C;AAE7C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,OAAoB,CAAC;IAEzB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,MAAM,GAAkB,MAAM,cAAI,CAAC,mBAAmB,CAAC;YAC3D,SAAS,EAAE,CAAC,0BAAW,CAAC;SACzB,CAAC,CAAC,OAAO,EAAE,CAAC;QAEb,OAAO,GAAG,MAAM,CAAC,GAAG,CAAc,0BAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "@hedhog/mail",
|
3
|
+
"version": "0.0.3",
|
4
|
+
"main": "dist/index.js",
|
5
|
+
"scripts": {
|
6
|
+
"build": "tsc --project tsconfig.production.json && npm version patch",
|
7
|
+
"prod": "npm run build && npm publish --access public"
|
8
|
+
},
|
9
|
+
"keywords": [],
|
10
|
+
"author": "HedHog",
|
11
|
+
"license": "MIT",
|
12
|
+
"description": ""
|
13
|
+
}
|
package/src/index.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import { MailConfigurationTypeEnum } from "../enums/mail-configuration-type.enum";
|
2
|
+
|
3
|
+
export interface MailModuleOptions {
|
4
|
+
global?: boolean;
|
5
|
+
mailConfigurationType: MailConfigurationTypeEnum;
|
6
|
+
host?: string;
|
7
|
+
from?: string;
|
8
|
+
accessKeyId?: string;
|
9
|
+
secretAccessKey?: string;
|
10
|
+
clientId?: string;
|
11
|
+
clientSecret?: string;
|
12
|
+
refreshToken?: string;
|
13
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export interface MailType {
|
2
|
+
from?: string;
|
3
|
+
to: string | string[];
|
4
|
+
cc?: string | string[];
|
5
|
+
bcc?: string | string[];
|
6
|
+
subject?: string;
|
7
|
+
body?: string;
|
8
|
+
replyTo?: string | string[];
|
9
|
+
priority?: string;
|
10
|
+
createdAt?: string;
|
11
|
+
updatedAt?: string;
|
12
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { MailType } from './interfaces/mail-type';
|
2
|
+
|
3
|
+
export type MailAttachment = {
|
4
|
+
filename?: string;
|
5
|
+
content?: Buffer;
|
6
|
+
contentType?: string;
|
7
|
+
};
|
8
|
+
|
9
|
+
export type Mail = {
|
10
|
+
attachments?: MailAttachment[];
|
11
|
+
} & MailType;
|
12
|
+
|
13
|
+
export type MailConfig = {
|
14
|
+
host?: string;
|
15
|
+
from?: string;
|
16
|
+
accessKeyId?: string;
|
17
|
+
secretAccessKey?: string;
|
18
|
+
};
|
19
|
+
|
20
|
+
export const MAIL_MODULE_OPTIONS = 'MAIL_MODULE_OPTIONS';
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { DynamicModule, Module } from '@nestjs/common';
|
2
|
+
import { MailService } from './mail.service';
|
3
|
+
import { MailModuleOptions } from './interfaces/mail-module-options.interface';
|
4
|
+
import { MailConfigurationTypeEnum } from './enums/mail-configuration-type.enum';
|
5
|
+
import { MAIL_MODULE_OPTIONS } from './mail.consts';
|
6
|
+
import { HttpModule, HttpService } from '@nestjs/axios';
|
7
|
+
|
8
|
+
@Module({
|
9
|
+
imports: [HttpModule],
|
10
|
+
providers: [MailService],
|
11
|
+
exports: [MailService],
|
12
|
+
})
|
13
|
+
export class MailModule {
|
14
|
+
static init(options: MailModuleOptions): DynamicModule {
|
15
|
+
return {
|
16
|
+
module: MailModule,
|
17
|
+
global: options.global,
|
18
|
+
providers: [
|
19
|
+
{
|
20
|
+
provide: MAIL_MODULE_OPTIONS,
|
21
|
+
useValue: options || {},
|
22
|
+
},
|
23
|
+
],
|
24
|
+
};
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
2
|
+
import { MailService } from './mail.service';
|
3
|
+
|
4
|
+
describe('MailService', () => {
|
5
|
+
let service: MailService;
|
6
|
+
|
7
|
+
beforeEach(async () => {
|
8
|
+
const module: TestingModule = await Test.createTestingModule({
|
9
|
+
providers: [MailService],
|
10
|
+
}).compile();
|
11
|
+
|
12
|
+
service = module.get<MailService>(MailService);
|
13
|
+
});
|
14
|
+
|
15
|
+
it('should be defined', () => {
|
16
|
+
expect(service).toBeDefined();
|
17
|
+
});
|
18
|
+
});
|
@@ -0,0 +1,256 @@
|
|
1
|
+
import { Inject, Injectable } from '@nestjs/common';
|
2
|
+
import { Mail, MAIL_MODULE_OPTIONS } from './mail.consts';
|
3
|
+
import { SES } from 'aws-sdk';
|
4
|
+
import * as mimemessage from 'mimemessage';
|
5
|
+
import { MailConfigurationTypeEnum } from './enums/mail-configuration-type.enum';
|
6
|
+
import { MailModuleOptions } from './interfaces/mail-module-options.interface';
|
7
|
+
import { google } from 'googleapis';
|
8
|
+
import { HttpService } from '@nestjs/axios';
|
9
|
+
import { firstValueFrom } from 'rxjs';
|
10
|
+
|
11
|
+
@Injectable()
|
12
|
+
export class MailService {
|
13
|
+
constructor(
|
14
|
+
@Inject(MAIL_MODULE_OPTIONS) private readonly mailConfig: MailModuleOptions,
|
15
|
+
private readonly httpService: HttpService,
|
16
|
+
) {}
|
17
|
+
|
18
|
+
async send(mail: Mail) {
|
19
|
+
switch (this.mailConfig.mailConfigurationType) {
|
20
|
+
case MailConfigurationTypeEnum.AWS:
|
21
|
+
await this.sendWithSES(mail);
|
22
|
+
break;
|
23
|
+
|
24
|
+
case MailConfigurationTypeEnum.GMAIL:
|
25
|
+
await this.sendWithGmail(mail);
|
26
|
+
break;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
async createRawEmail(mail: Mail) {
|
31
|
+
if (mail.attachments instanceof Array && mail.attachments?.length) {
|
32
|
+
const mailContent = mimemessage.factory({
|
33
|
+
contentType: 'multipart/mixed',
|
34
|
+
body: [],
|
35
|
+
});
|
36
|
+
|
37
|
+
mailContent.header('From', mail.from);
|
38
|
+
mailContent.header('To', mail.to);
|
39
|
+
mailContent.header('Subject', mail.subject);
|
40
|
+
|
41
|
+
const alternateEntity = mimemessage.factory({
|
42
|
+
contentType: 'multipart/alternate',
|
43
|
+
body: [],
|
44
|
+
});
|
45
|
+
|
46
|
+
const htmlEntity = mimemessage.factory({
|
47
|
+
contentType: 'text/html;charset=utf-8',
|
48
|
+
body: mail.body,
|
49
|
+
});
|
50
|
+
|
51
|
+
alternateEntity.body.push(htmlEntity);
|
52
|
+
|
53
|
+
mailContent.body.push(alternateEntity);
|
54
|
+
|
55
|
+
await Promise.all(
|
56
|
+
mail.attachments.map(async (attachment) => {
|
57
|
+
const attachmentEntity = mimemessage.factory({
|
58
|
+
contentType: attachment.contentType,
|
59
|
+
contentTransferEncoding: 'base64',
|
60
|
+
body: attachment.content
|
61
|
+
.toString('base64')
|
62
|
+
.replace(/([^\0]{76})/g, '$1\n'),
|
63
|
+
});
|
64
|
+
|
65
|
+
attachmentEntity.header(
|
66
|
+
'Content-Disposition',
|
67
|
+
`attachment; filename="${attachment.filename}"`,
|
68
|
+
);
|
69
|
+
|
70
|
+
mailContent.body.push(attachmentEntity);
|
71
|
+
}),
|
72
|
+
);
|
73
|
+
|
74
|
+
const messageString = mailContent.toString();
|
75
|
+
const encodedMessage = Buffer.from(messageString)
|
76
|
+
.toString('base64')
|
77
|
+
.replace(/\+/g, '-')
|
78
|
+
.replace(/\//g, '_')
|
79
|
+
.replace(/=+$/, '');
|
80
|
+
|
81
|
+
return encodedMessage;
|
82
|
+
} else {
|
83
|
+
const messageParts = [
|
84
|
+
`From: ${mail.from}`,
|
85
|
+
`To: ${mail.to instanceof Array ? mail.to.join(',') : mail.to}`,
|
86
|
+
`Subject: ${mail.subject}`,
|
87
|
+
'Content-Type: text/plain; charset="UTF-8"',
|
88
|
+
'',
|
89
|
+
mail.body,
|
90
|
+
];
|
91
|
+
|
92
|
+
const message = messageParts.join('\n');
|
93
|
+
const encodedMessage = Buffer.from(message)
|
94
|
+
.toString('base64')
|
95
|
+
.replace(/\+/g, '-')
|
96
|
+
.replace(/\//g, '_')
|
97
|
+
.replace(/=+$/, '');
|
98
|
+
|
99
|
+
return encodedMessage;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
async sendWithGmail(mail: Mail) {
|
104
|
+
const { clientId, clientSecret, from, refreshToken } = this.mailConfig;
|
105
|
+
const redirectURI = 'https://developers.google.com/oauthplayground';
|
106
|
+
|
107
|
+
const oauth2Client = new google.auth.OAuth2(
|
108
|
+
clientId,
|
109
|
+
clientSecret,
|
110
|
+
redirectURI,
|
111
|
+
);
|
112
|
+
|
113
|
+
oauth2Client.setCredentials({
|
114
|
+
refresh_token: refreshToken,
|
115
|
+
});
|
116
|
+
|
117
|
+
const { token } = await oauth2Client.getAccessToken();
|
118
|
+
|
119
|
+
const raw = await this.createRawEmail({
|
120
|
+
...mail,
|
121
|
+
from,
|
122
|
+
});
|
123
|
+
|
124
|
+
const url = 'https://www.googleapis.com/gmail/v1/users/me/messages/send';
|
125
|
+
|
126
|
+
const requestBody = {
|
127
|
+
raw,
|
128
|
+
};
|
129
|
+
|
130
|
+
const headers = {
|
131
|
+
Authorization: `Bearer ${token}`,
|
132
|
+
'Content-Type': 'application/json',
|
133
|
+
};
|
134
|
+
|
135
|
+
const response = this.httpService.post(url, requestBody, { headers });
|
136
|
+
|
137
|
+
return firstValueFrom(response);
|
138
|
+
}
|
139
|
+
|
140
|
+
async sendWithSES(mail: Mail) {
|
141
|
+
const { host, from, accessKeyId, secretAccessKey } = this.mailConfig;
|
142
|
+
|
143
|
+
const ses = new SES({
|
144
|
+
apiVersion: '2010-12-01',
|
145
|
+
region: host.split('.')[1],
|
146
|
+
credentials: {
|
147
|
+
accessKeyId,
|
148
|
+
secretAccessKey,
|
149
|
+
},
|
150
|
+
});
|
151
|
+
|
152
|
+
ses.config.update({
|
153
|
+
credentials: {
|
154
|
+
accessKeyId,
|
155
|
+
secretAccessKey,
|
156
|
+
},
|
157
|
+
});
|
158
|
+
|
159
|
+
if (typeof mail.to === 'string') {
|
160
|
+
mail.to = mail.to.split(';');
|
161
|
+
}
|
162
|
+
if (typeof mail.bcc === 'string') {
|
163
|
+
mail.bcc = mail.bcc.split(';');
|
164
|
+
} else if (!mail.bcc) {
|
165
|
+
mail.bcc = [];
|
166
|
+
}
|
167
|
+
if (typeof mail.cc === 'string') {
|
168
|
+
mail.cc = mail.cc.split(';');
|
169
|
+
} else if (!mail.cc) {
|
170
|
+
mail.cc = [];
|
171
|
+
}
|
172
|
+
if (typeof mail.replyTo === 'string') {
|
173
|
+
mail.replyTo = mail.replyTo.split(';');
|
174
|
+
} else if (!mail.replyTo) {
|
175
|
+
mail.replyTo = [];
|
176
|
+
}
|
177
|
+
|
178
|
+
if (mail.attachments instanceof Array && mail.attachments.length > 0) {
|
179
|
+
const mailContent = mimemessage.factory({
|
180
|
+
contentType: 'multipart/mixed',
|
181
|
+
body: [],
|
182
|
+
});
|
183
|
+
|
184
|
+
mailContent.header('From', from);
|
185
|
+
mailContent.header('To', mail.to);
|
186
|
+
mailContent.header('Subject', mail.subject);
|
187
|
+
|
188
|
+
const alternateEntity = mimemessage.factory({
|
189
|
+
contentType: 'multipart/alternate',
|
190
|
+
body: [],
|
191
|
+
});
|
192
|
+
|
193
|
+
const htmlEntity = mimemessage.factory({
|
194
|
+
contentType: 'text/html;charset=utf-8',
|
195
|
+
body: mail.body,
|
196
|
+
});
|
197
|
+
|
198
|
+
alternateEntity.body.push(htmlEntity);
|
199
|
+
|
200
|
+
mailContent.body.push(alternateEntity);
|
201
|
+
|
202
|
+
await Promise.all(
|
203
|
+
mail.attachments.map((item) => {
|
204
|
+
const attachmentEntity = mimemessage.factory({
|
205
|
+
contentType: item.contentType,
|
206
|
+
contentTransferEncoding: 'base64',
|
207
|
+
body: item.content
|
208
|
+
.toString('base64')
|
209
|
+
.replace(/([^\0]{76})/g, '$1\n'),
|
210
|
+
});
|
211
|
+
|
212
|
+
attachmentEntity.header(
|
213
|
+
'Content-Disposition',
|
214
|
+
`attachment ;filename="${item.filename}"`,
|
215
|
+
);
|
216
|
+
|
217
|
+
mailContent.body.push(attachmentEntity);
|
218
|
+
}),
|
219
|
+
);
|
220
|
+
|
221
|
+
return ses
|
222
|
+
.sendRawEmail({
|
223
|
+
RawMessage: { Data: mailContent.toString() },
|
224
|
+
})
|
225
|
+
.promise();
|
226
|
+
} else {
|
227
|
+
const params = {
|
228
|
+
Destination: {
|
229
|
+
ToAddresses: mail.to,
|
230
|
+
BccAddresses: mail.bcc,
|
231
|
+
CcAddresses: mail.cc,
|
232
|
+
},
|
233
|
+
Message: {
|
234
|
+
Body: {
|
235
|
+
Html: {
|
236
|
+
Data: mail.body,
|
237
|
+
Charset: 'utf-8',
|
238
|
+
},
|
239
|
+
Text: {
|
240
|
+
Data: mail.body,
|
241
|
+
Charset: 'utf-8',
|
242
|
+
},
|
243
|
+
},
|
244
|
+
Subject: {
|
245
|
+
Data: mail.subject,
|
246
|
+
Charset: 'utf-8',
|
247
|
+
},
|
248
|
+
},
|
249
|
+
ReplyToAddresses: mail.replyTo,
|
250
|
+
Source: from,
|
251
|
+
};
|
252
|
+
|
253
|
+
return ses.sendEmail(params).promise();
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"experimentalDecorators": true,
|
4
|
+
"target": "es2017",
|
5
|
+
"module": "commonjs",
|
6
|
+
"lib": ["es2017", "es7", "es6"],
|
7
|
+
"declaration": true,
|
8
|
+
"declarationMap": true,
|
9
|
+
"sourceMap": true,
|
10
|
+
"outDir": "./dist",
|
11
|
+
"rootDir": "./src",
|
12
|
+
"strict": true,
|
13
|
+
"noImplicitAny": false,
|
14
|
+
"strictNullChecks": false,
|
15
|
+
"allowSyntheticDefaultImports": true,
|
16
|
+
"esModuleInterop": true,
|
17
|
+
"emitDecoratorMetadata": true
|
18
|
+
},
|
19
|
+
"exclude": ["node_modules", "dist"]
|
20
|
+
}
|