From 231ca114382116ea16f40a8b35aedbaae3ed4201 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Wed, 27 Mar 2024 06:14:46 +0200 Subject: [PATCH 1/4] Create logic for accepting bark beetle reports New endpoint to accept bark beetle reports and forward them via PostMark for reviewing --- .env.example | 2 ++ src/report/postmark.service.ts | 51 +++++++++++++++++++++++++++++++++ src/report/report.controller.ts | 24 +++++++++++++++- src/report/report.module.ts | 3 +- yarn.lock | 7 +++++ 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/report/postmark.service.ts diff --git a/.env.example b/.env.example index b846791..ca5134e 100644 --- a/.env.example +++ b/.env.example @@ -5,3 +5,5 @@ CLOUDINARY_KEY=CLOUDINARY_KEY CLOUDINARY_SECRET=CLOUDINARY_SECRET JWT_SECRET=JWT_SECRET SENTRY_DSN=SENTRY_DSN +POSTMARK_API_TOKEN=POSTMARK_API_TOKEN +POSTMARK_TEMPLATE_ID=POSTMARK_TEMPLATE_ID \ No newline at end of file diff --git a/src/report/postmark.service.ts b/src/report/postmark.service.ts new file mode 100644 index 0000000..082ecc1 --- /dev/null +++ b/src/report/postmark.service.ts @@ -0,0 +1,51 @@ +import { Injectable } from '@nestjs/common'; +import * as postmark from 'postmark'; +import { CreateReportDto } from './dto'; +import { TemplatedMessage } from 'postmark'; +import * as process from 'process'; + +@Injectable() +export class PostmarkService { + private client: postmark.ServerClient; + + constructor() { + this.client = new postmark.ServerClient(process.env['POSTMARK_API_TOKEN']!); + } + + async sendBarkBeetleReport( + createReportDto: CreateReportDto, + images: Array, + to: string, + ) { + function encodeToBase64(file: Express.Multer.File) { + return Buffer.from(file.buffer).toString('base64'); + } + + const attachments = []; + + for (let i = 0; i < images.length; i++) { + const encodedImageContent = encodeToBase64(images[i]); + attachments.push({ + Name: 'nuotrauka' + i + '.jpg', + Content: encodedImageContent, + ContentType: 'image/jpeg', + ContentID: 'photo' + i, + }); + } + + const templatedMessage: TemplatedMessage = { + TemplateId: Number(process.env['POSTMARK_TEMPLATE_ID']), + From: 'neatsakyti@tvarkaulietuva.lt', + To: to, + TemplateModel: { + description: createReportDto.name, + longitude: createReportDto.longitude, + latitude: createReportDto.latitude, + email: createReportDto.email, + }, + Attachments: attachments, + }; + + return this.client.sendEmailWithTemplate(templatedMessage); + } +} diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index aa94cca..50e244d 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -25,11 +25,15 @@ import { CreateReportDto } from './dto'; import { FilesInterceptor } from '@nestjs/platform-express'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; import { ReportCategory } from '../common/dto/report-category'; +import { PostmarkService } from './postmark.service'; @Controller('reports') @ApiTags('reports') export class ReportController { - constructor(private readonly reportService: ReportService) {} + constructor( + private readonly reportService: ReportService, + private readonly postmarkService: PostmarkService, + ) {} @ApiCreatedResponse({ description: 'New Report has been successfully created', @@ -45,6 +49,24 @@ export class ReportController { return this.reportService.createReport(createReportDto, images); } + @ApiCreatedResponse({ + description: 'New Report has been successfully sent', + type: PublicReportDto, + }) + @ApiConsumes('multipart/form-data') + @UseInterceptors(FilesInterceptor('images', 4)) + @Post('/bark-beetle') + sendBarkBeetleReport( + @Body() createReportDto: CreateReportDto, + @UploadedFiles() images: Array, + ) { + return this.postmarkService.sendBarkBeetleReport( + createReportDto, + images, + 'temp@mail.com', + ); + } + @ApiOkResponse({ description: 'All visible reports have been successfully found', type: [PublicReportDto], diff --git a/src/report/report.module.ts b/src/report/report.module.ts index 6059c0d..249dcb5 100644 --- a/src/report/report.module.ts +++ b/src/report/report.module.ts @@ -5,6 +5,7 @@ import { MongooseModule } from '@nestjs/mongoose'; import { ReportRepository } from '../repositories/reports/report.repository'; import { Report, ReportSchema } from '../repositories/reports/schemas'; import { CloudinaryModule } from '../cloudinary/cloudinary.module'; +import { PostmarkService } from './postmark.service'; @Module({ imports: [ @@ -12,6 +13,6 @@ import { CloudinaryModule } from '../cloudinary/cloudinary.module'; CloudinaryModule, ], controllers: [ReportController], - providers: [ReportService, ReportRepository], + providers: [ReportService, ReportRepository, PostmarkService], }) export class ReportModule {} diff --git a/yarn.lock b/yarn.lock index d7e3dfe..e89563b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4997,6 +4997,13 @@ pluralize@8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +postmark@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postmark/-/postmark-4.0.2.tgz#0c0410ac427d85f2a43454360cf8d07e0fbda317" + integrity sha512-2zlCv+KVVQ0KoamXZHE7d+gXzLlr8tPE+PxQmtUaIZhbHzZAq4D6yH2b+ykhA8wYCc5ISodcx8U1aNLenXBs9g== + dependencies: + axios "^1.6.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" From 13d0968f4040311fbbcc4dc5c71d4d311629e2f4 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:16:43 +0200 Subject: [PATCH 2/4] Change temporary mail location --- src/report/report.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index 50e244d..aae8bc7 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -63,7 +63,7 @@ export class ReportController { return this.postmarkService.sendBarkBeetleReport( createReportDto, images, - 'temp@mail.com', + 'benas.svedas@aad.am.lt', ); } From 81b1f7f17bec89007bf4cadb08acee793f630aff Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Thu, 28 Mar 2024 05:36:32 +0200 Subject: [PATCH 3/4] Update return types --- src/report/postmark.service.ts | 3 ++- src/report/report.controller.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/report/postmark.service.ts b/src/report/postmark.service.ts index 082ecc1..293d64a 100644 --- a/src/report/postmark.service.ts +++ b/src/report/postmark.service.ts @@ -3,6 +3,7 @@ import * as postmark from 'postmark'; import { CreateReportDto } from './dto'; import { TemplatedMessage } from 'postmark'; import * as process from 'process'; +import { MessageSendingResponse } from 'postmark/dist/client/models'; @Injectable() export class PostmarkService { @@ -16,7 +17,7 @@ export class PostmarkService { createReportDto: CreateReportDto, images: Array, to: string, - ) { + ): Promise { function encodeToBase64(file: Express.Multer.File) { return Buffer.from(file.buffer).toString('base64'); } diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index aae8bc7..7fda911 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -26,6 +26,7 @@ import { FilesInterceptor } from '@nestjs/platform-express'; import { ReportStatisticsDto } from './dto/report-statistics.dto'; import { ReportCategory } from '../common/dto/report-category'; import { PostmarkService } from './postmark.service'; +import { Message, MessageSendingResponse } from 'postmark/dist/client/models'; @Controller('reports') @ApiTags('reports') @@ -51,7 +52,7 @@ export class ReportController { @ApiCreatedResponse({ description: 'New Report has been successfully sent', - type: PublicReportDto, + type: Message, }) @ApiConsumes('multipart/form-data') @UseInterceptors(FilesInterceptor('images', 4)) @@ -59,7 +60,7 @@ export class ReportController { sendBarkBeetleReport( @Body() createReportDto: CreateReportDto, @UploadedFiles() images: Array, - ) { + ): Promise { return this.postmarkService.sendBarkBeetleReport( createReportDto, images, From a657d285523b6addf756c1292257876a4c655611 Mon Sep 17 00:00:00 2001 From: Ignas-rgb <61393113+Ignas-rgb@users.noreply.github.com> Date: Thu, 28 Mar 2024 05:40:12 +0200 Subject: [PATCH 4/4] Added dependancy --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 32f08ce..39965f1 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "passport": "^0.7.0", "passport-jwt": "^4.0.1", "passport-local": "^1.0.0", + "postmark": "^4.0.2", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" },