Skip to content

Commit

Permalink
feat: implement push notifications (#87)
Browse files Browse the repository at this point in the history
* feat: implement push notifications

* fix tests
  • Loading branch information
adelinaenache authored May 29, 2024
1 parent d546502 commit 2ce6233
Show file tree
Hide file tree
Showing 20 changed files with 446 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/platform-fastify": "^10.3.3",
"@nestjs/schedule": "^4.0.2",
"@nestjs/swagger": "^7.3.0",
"@prisma/client": "^5.10.2",
"@types/uuid": "^9.0.8",
Expand All @@ -48,6 +49,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"crypto-js": "^4.2.0",
"expo-server-sdk": "^3.10.0",
"express": "^4.19.2",
"install": "^0.13.0",
"ioredis": "^5.4.1",
Expand Down
74 changes: 74 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ReviewsModule } from '../../src/reviews/reviews.module';
import { ConnectionsModule } from '../../src/connections/connections.module';
import { AppLoggerMiddleware } from '../../src/middlewares/logger.middleware';
import { CommonModule } from '../common/common.module';
import { NotificationsModule } from '../../src/notifications/notifications.module';

@Module({
imports: [
Expand All @@ -27,6 +28,7 @@ import { CommonModule } from '../common/common.module';
MailModule,
ProviderModule,
ReviewsModule,
NotificationsModule,
ConnectionsModule,
],
controllers: [AppController],
Expand Down
3 changes: 2 additions & 1 deletion src/connections/connections.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { Test, TestingModule } from '@nestjs/testing';
import { ConnectionsController } from './connections.controller';
import { ConnectionsService } from './connections.service';
import { PrismaService } from '../../src/prisma/prisma.service';
import { NotificationsService } from '../../src/notifications/notifications.service';

describe('ConnectionsController', () => {
let controller: ConnectionsController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConnectionsController],
providers: [ConnectionsService, PrismaService],
providers: [ConnectionsService, PrismaService, NotificationsService],
}).compile();

controller = module.get<ConnectionsController>(ConnectionsController);
Expand Down
3 changes: 2 additions & 1 deletion src/connections/connections.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Module } from '@nestjs/common';
import { ConnectionsService } from './connections.service';
import { ConnectionsController } from './connections.controller';
import { NotificationsService } from '../../src/notifications/notifications.service';

@Module({
providers: [ConnectionsService],
providers: [ConnectionsService, NotificationsService],
controllers: [ConnectionsController],
})
export class ConnectionsModule {}
3 changes: 2 additions & 1 deletion src/connections/connections.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConnectionsService } from './connections.service';
import { PrismaService } from '../../src/prisma/prisma.service';
import { NotificationsService } from '../../src/notifications/notifications.service';

describe('ConnectionsService', () => {
let service: ConnectionsService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConnectionsService, PrismaService],
providers: [ConnectionsService, PrismaService, NotificationsService],
}).compile();

service = module.get<ConnectionsService>(ConnectionsService);
Expand Down
18 changes: 15 additions & 3 deletions src/connections/connections.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ import {
Injectable,
NotFoundException,
} from '@nestjs/common';
import { AuthType, User } from '@prisma/client';
import { AuthType, NotificationType, User } from '@prisma/client';
import { PrismaService } from '../../src/prisma/prisma.service';
import { ConnectionDto } from './dto/Connection.dto';
import { ApiTags } from '@nestjs/swagger';
import { ProfileFetcherDelegator } from '../../src/user/profile-fetcher/delegator.profile-fetcher';
import { v4 } from 'uuid';
import { NotificationsService } from '../../src/notifications/notifications.service';

@Injectable()
@ApiTags('Connections controller')
@ApiTags('Connections service')
export class ConnectionsService {
constructor(private readonly prisma: PrismaService) {}
constructor(
private readonly prisma: PrismaService,
private readonly notificationsService: NotificationsService,
) {}

// retuns an object to be used with prisma's include
private includeWithUserConnection(currentUserId?: User['id']) {
Expand Down Expand Up @@ -105,6 +109,14 @@ export class ConnectionsService {
},
});

await this.notificationsService.sendNotificationToUser(
userId,
NotificationType.CONNECTION,
`You have a new connection.`,
'New Culero connection',
{ followerId: currentUserId, followingId: userId },
);

return this.convertConnectionToDto(connection.following);
}

Expand Down
6 changes: 6 additions & 0 deletions src/notifications/dto/add-token.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { IsString } from 'class-validator';

export class PushTokenDto {
@IsString()
token: string;
}
15 changes: 15 additions & 0 deletions src/notifications/dto/notification.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NotificationType } from '@prisma/client';
import { Type } from 'class-transformer';
import { IsDate, IsEnum } from 'class-validator';

export class NotificationDto {
extraData: any;
body: string;
title: string;
@Type(() => Date)
@IsDate()
createdAt: Date;

@IsEnum(NotificationType)
type: NotificationType;
}
32 changes: 32 additions & 0 deletions src/notifications/notifications.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Body, Controller, Get, Post } from '@nestjs/common';
import { NotificationsService } from './notifications.service';
import { CurrentUser } from '../../src/decorators/current-user.decorator';
import { User } from '@prisma/client';
import { NotificationDto } from './dto/notification.dto';
import { PushTokenDto } from './dto/add-token.dto';

@Controller('notifications')
export class NotificationsController {
constructor(private readonly notificationsService: NotificationsService) {}
/**
* Get current user's notifications
*/
@Get()
public async getNotifications(
@CurrentUser() user: User,
): Promise<NotificationDto[]> {
return this.notificationsService.getUserNotifications(user.id);
}

/**
* Add a notification token
*/
@Post('/token')
public async addPushToken(
@CurrentUser() user: User,
@Body() data: PushTokenDto,
) {
await this.notificationsService.addPushToken(user.id, data.token);
return { ok: true };
}
}
10 changes: 10 additions & 0 deletions src/notifications/notifications.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { NotificationsService } from './notifications.service';
import { PrismaService } from '../prisma/prisma.service';
import { NotificationsController } from './notifications.controller';

@Module({
providers: [PrismaService, NotificationsService],
controllers: [NotificationsController],
})
export class NotificationsModule {}
Loading

0 comments on commit 2ce6233

Please sign in to comment.