From 51b1828b1d1f0ca81ef91078c2db139ac48cd729 Mon Sep 17 00:00:00 2001 From: isra el Date: Tue, 16 Apr 2024 07:38:19 +0300 Subject: [PATCH] feat(api): receive and save sms --- api/src/gateway/gateway.controller.ts | 25 ++++++++++++++- api/src/gateway/gateway.service.ts | 44 +++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/api/src/gateway/gateway.controller.ts b/api/src/gateway/gateway.controller.ts index 2d35dbe..1275f52 100644 --- a/api/src/gateway/gateway.controller.ts +++ b/api/src/gateway/gateway.controller.ts @@ -8,10 +8,16 @@ import { Request, Get, Delete, + HttpCode, + HttpStatus, } from '@nestjs/common' import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger' import { AuthGuard } from '../auth/guards/auth.guard' -import { RegisterDeviceInputDTO, SendSMSInputDTO } from './gateway.dto' +import { + ReceivedSMSDTO, + RegisterDeviceInputDTO, + SendSMSInputDTO, +} from './gateway.dto' import { GatewayService } from './gateway.service' import { CanModifyDevice } from './guards/can-modify-device.guard' @@ -98,4 +104,21 @@ export class GatewayController { const data = await this.gatewayService.sendSMS(deviceId, smsData) return { data } } + + @ApiOperation({ summary: 'Received SMS from a device' }) + @ApiQuery({ + name: 'apiKey', + required: false, + description: 'Required if jwt bearer token not provided', + }) + @HttpCode(HttpStatus.OK) + @Post('/devices/:id/receivedSMS') + @UseGuards(AuthGuard, CanModifyDevice) + async receivedSMS( + @Param('id') deviceId: string, + @Body() dto: ReceivedSMSDTO, + ) { + const data = await this.gatewayService.receivedSMS(deviceId, dto) + return { data } + } } diff --git a/api/src/gateway/gateway.service.ts b/api/src/gateway/gateway.service.ts index f995008..6935383 100644 --- a/api/src/gateway/gateway.service.ts +++ b/api/src/gateway/gateway.service.ts @@ -3,11 +3,15 @@ import { InjectModel } from '@nestjs/mongoose' import { Device, DeviceDocument } from './schemas/device.schema' import { Model } from 'mongoose' import * as firebaseAdmin from 'firebase-admin' -import { RegisterDeviceInputDTO, SendSMSInputDTO } from './gateway.dto' +import { + ReceivedSMSDTO, + RegisterDeviceInputDTO, + SendSMSInputDTO, +} from './gateway.dto' import { User } from '../users/schemas/user.schema' import { AuthService } from 'src/auth/auth.service' import { SMS } from './schemas/sms.schema' - +import { SMSType } from './sms-type.enum' @Injectable() export class GatewayService { constructor( @@ -133,6 +137,42 @@ export class GatewayService { } } + async receivedSMS(deviceId: string, dto: ReceivedSMSDTO): Promise { + const device = await this.deviceModel.findById(deviceId) + + if (!device) { + throw new HttpException( + { + success: false, + error: 'Device does not exist', + }, + HttpStatus.BAD_REQUEST, + ) + } + + if (!dto.receivedAt || !dto.sender || !dto.message) { + throw new HttpException( + { + success: false, + error: 'Invalid received SMS data', + }, + HttpStatus.BAD_REQUEST, + ) + } + + const sms = await this.smsModel.create({ + device: device._id, + message: dto.message, + type: SMSType.RECEIVED, + sender: dto.sender, + receivedAt: dto.receivedAt, + }) + + // TODO: Implement webhook to forward received SMS to user's callback URL + + return sms + } + async getStatsForUser(user: User) { const devices = await this.deviceModel.find({ user: user._id }) const apiKeys = await this.authService.getUserApiKeys(user)