Skip to content

Commit dc3296a

Browse files
authored
Merge pull request #590 from gitroomhq/feat/digest
Digest Notifications
2 parents 136f20b + 6716360 commit dc3296a

File tree

5 files changed

+103
-12
lines changed

5 files changed

+103
-12
lines changed

apps/workers/src/app/posts.controller.ts

+5
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ export class PostsController {
1515
async payout(data: { id: string; releaseURL: string }) {
1616
return this._postsService.payout(data.id, data.releaseURL);
1717
}
18+
19+
@EventPattern('sendDigestEmail', Transport.REDIS)
20+
async sendDigestEmail(data: { subject: string, org: string; since: string }) {
21+
return this._postsService.sendDigestEmail(data.subject, data.org, data.since);
22+
}
1823
}

libraries/nestjs-libraries/src/database/prisma/notifications/notification.service.ts

+52-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import { Injectable } from '@nestjs/common';
22
import { NotificationsRepository } from '@gitroom/nestjs-libraries/database/prisma/notifications/notifications.repository';
33
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
44
import { OrganizationRepository } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.repository';
5+
import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/client';
6+
import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service';
7+
import dayjs from 'dayjs';
58

69
@Injectable()
710
export class NotificationService {
811
constructor(
912
private _notificationRepository: NotificationsRepository,
1013
private _emailService: EmailService,
11-
private _organizationRepository: OrganizationRepository
14+
private _organizationRepository: OrganizationRepository,
15+
private _workerServiceProducer: BullMqClient
1216
) {}
1317

1418
getMainPageCount(organizationId: string, userId: string) {
@@ -25,12 +29,58 @@ export class NotificationService {
2529
);
2630
}
2731

28-
async inAppNotification(orgId: string, subject: string, message: string, sendEmail = false) {
32+
getNotificationsSince(organizationId: string, since: string) {
33+
return this._notificationRepository.getNotificationsSince(
34+
organizationId,
35+
since
36+
);
37+
}
38+
39+
async inAppNotification(
40+
orgId: string,
41+
subject: string,
42+
message: string,
43+
sendEmail = false,
44+
digest = false
45+
) {
46+
const date = new Date().toISOString();
2947
await this._notificationRepository.createNotification(orgId, message);
3048
if (!sendEmail) {
3149
return;
3250
}
3351

52+
if (digest) {
53+
await ioRedis.watch('digest_' + orgId);
54+
const value = await ioRedis.get('digest_' + orgId);
55+
if (value) {
56+
return;
57+
}
58+
59+
await ioRedis
60+
.multi()
61+
.set('digest_' + orgId, date)
62+
.expire('digest_' + orgId, 60)
63+
.exec();
64+
65+
this._workerServiceProducer.emit('sendDigestEmail', {
66+
id: 'digest_' + orgId,
67+
options: {
68+
delay: 60000,
69+
},
70+
payload: {
71+
subject,
72+
org: orgId,
73+
since: date,
74+
},
75+
});
76+
77+
return;
78+
}
79+
80+
await this.sendEmailsToOrg(orgId, subject, message);
81+
}
82+
83+
async sendEmailsToOrg(orgId: string, subject: string, message: string) {
3484
const userOrg = await this._organizationRepository.getAllUsersOrgs(orgId);
3585
for (const user of userOrg?.users || []) {
3686
await this.sendEmail(user.user.email, subject, message);

libraries/nestjs-libraries/src/database/prisma/notifications/notifications.repository.ts

+11
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ export class NotificationsRepository {
4545
});
4646
}
4747

48+
async getNotificationsSince(organizationId: string, since: string) {
49+
return this._notifications.model.notifications.findMany({
50+
where: {
51+
organizationId,
52+
createdAt: {
53+
gte: new Date(since),
54+
},
55+
},
56+
});
57+
}
58+
4859
async getNotifications(organizationId: string, userId: string) {
4960
const { lastReadNotifications } = (await this.getLastReadNotification(
5061
userId

libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts

+35-9
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ export class PostsService {
4646
async getStatistics(orgId: string, id: string) {
4747
const getPost = await this.getPostsRecursively(id, true, orgId, true);
4848
const content = getPost.map((p) => p.content);
49-
const shortLinksTracking = await this._shortLinkService.getStatistics(content);
49+
const shortLinksTracking = await this._shortLinkService.getStatistics(
50+
content
51+
);
5052

5153
return {
52-
clicks: shortLinksTracking
53-
}
54+
clicks: shortLinksTracking,
55+
};
5456
}
5557

5658
async getPostsRecursively(
@@ -363,7 +365,10 @@ export class PostsService {
363365
`Your post has been published on ${capitalize(
364366
integration.providerIdentifier
365367
)}`,
366-
`Your post has been published at ${publishedPosts[0].releaseURL}`,
368+
`Your post has been published on ${capitalize(
369+
integration.providerIdentifier
370+
)} at ${publishedPosts[0].releaseURL}`,
371+
true,
367372
true
368373
);
369374

@@ -517,10 +522,10 @@ export class PostsService {
517522
const post = await this._postRepository.deletePost(orgId, group);
518523
if (post?.id) {
519524
await this._workerServiceProducer.delete('post', post.id);
520-
return {id: post.id};
525+
return { id: post.id };
521526
}
522527

523-
return {error: true};
528+
return { error: true };
524529
}
525530

526531
async countPostsFromDay(orgId: string, date: Date) {
@@ -566,8 +571,10 @@ export class PostsService {
566571
async createPost(orgId: string, body: CreatePostDto) {
567572
const postList = [];
568573
for (const post of body.posts) {
569-
const messages = post.value.map(p => p.content);
570-
const updateContent = !body.shortLink ? messages : await this._shortLinkService.convertTextToShortLinks(orgId, messages);
574+
const messages = post.value.map((p) => p.content);
575+
const updateContent = !body.shortLink
576+
? messages
577+
: await this._shortLinkService.convertTextToShortLinks(orgId, messages);
571578

572579
post.value = post.value.map((p, i) => ({
573580
...p,
@@ -624,7 +631,7 @@ export class PostsService {
624631
postList.push({
625632
postId: posts[0].id,
626633
integration: post.integration.id,
627-
})
634+
});
628635
}
629636

630637
return postList;
@@ -878,4 +885,23 @@ export class PostsService {
878885
) {
879886
return this._postRepository.createComment(orgId, userId, postId, comment);
880887
}
888+
889+
async sendDigestEmail(subject: string, orgId: string, since: string) {
890+
const getNotificationsForOrgSince =
891+
await this._notificationService.getNotificationsSince(orgId, since);
892+
if (getNotificationsForOrgSince.length === 0) {
893+
return;
894+
}
895+
896+
const message = getNotificationsForOrgSince
897+
.map((p) => p.content)
898+
.join('<br />');
899+
await this._notificationService.sendEmailsToOrg(
900+
orgId,
901+
getNotificationsForOrgSince.length === 1
902+
? subject
903+
: '[Postiz] Your latest notifications',
904+
message
905+
);
906+
}
881907
}

libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
} from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';
77
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
88
import {
9-
NotEnoughScopes,
109
RefreshToken,
1110
SocialAbstract,
1211
} from '@gitroom/nestjs-libraries/integrations/social.abstract';

0 commit comments

Comments
 (0)