import { Injectable , Logger , OnModuleDestroy , OnModuleInit } from '@nestjs/common' ; import { InjectRepository } from '@nestjs/typeorm' ; import { Any , In , Raw , Repository } from 'typeorm' ; import { CrudService , IPagination } from '../../core' ; import { Notification , TargetType } from './notification.entity' ; import { CQRSGateway } from '../../shared' ; import { SubscriptionService } from '../subscription/subscription.service' ; import { PushService } from './push.service' ; import { Subscription } from '../subscription/subscription.entity' ; import { FindOwnNotificationsDto } from './dto/find-own-notifications.dto' ; import { FindNotificationsDto } from './dto/find-notifications.dto' ; import { User } from '@ngx-starter-kit/models' ; import { NotificationsDeleteCommand , NotificationsMarkAsReadCommand } from './commands' ; @ Injectable ( ) export class NotificationService extends CrudService < Notification > implements OnModuleInit , OnModuleDestroy { readonly logger = new Logger ( NotificationService . name ) ; constructor ( private readonly pushService , private readonly cqrsGateway , private readonly subscriptionService , @ InjectRepository ( Notification ) private readonly notificationsRepository , @ InjectRepository ( Subscription ) private readonly subscriptionRepository ) { super ( notificationsRepository ) ; } onModuleInit ( ) { } onModuleDestroy ( ) { } async findAll ( { take , skip , order , ... where } ) { return super . findAll ( { where , take , skip , order } ) ; } async findOwn ( { take , skip , order } , actor ) { const where = { isActive : true , target : In ( [ 'all' , actor . username ] ) } ; return super . findAll ( { where , take , skip , order } ) ; } async send ( id ) { const notification = await this . findOne ( id ) ; const pushNotification = { title : notification . title , body : notification . body , icon : 'assets/icons/icon-72x72.png' , data : notification , vibrate : [ 200 , 100 , 200 ] , } ; let subscriptions ; switch ( notification . targetType ) { case TargetType . USER : subscriptions = await this . subscriptionRepository . find ( { where : { username : notification . target } } ) ; break ; case TargetType . TOPIC : subscriptions = await this . subscriptionRepository . find ( { where : { topics : Raw ( ( alias ) => `${ alias } && '{${ notification . target }}'::text[]` ) } , } ) ; break ; case TargetType . ALL : subscriptions = await this . subscriptionRepository . find ( { take : 10 } ) ; break ; } subscriptions . forEach ( ( subscription ) => { const { endpoint , p256dh , auth } = subscription ; return this . pushService . sendNotification ( { endpoint , keys : { p256dh , auth } } , pushNotification as any ) ; } ) ; } async onMarkAsRead ( command ) { await this . update ( { id : command . payload . id , targetType : TargetType . USER , target : command . user . username } , { read : true } ) ; } async onMarkAllAsRead ( command ) { await this . update ( { targetType : TargetType . USER , target : command . user . username } , { read : true } ) ; } async onDeleteNotification ( command ) { await this . update ( { id : command . payload . id , targetType : TargetType . USER , target : command . user . username } , { isActive : false } ) ; } }