Files
speckle-server/packages/server/modules/activitystream/services/streamActivity.ts
T
Gergő Jedlicska d1d5984e30 gergo/summaryEmails (#979)
* refactor(server emails): email transports module refactor to TypeScript

* refactor(docker-compose deps): move local email server to common dev compose file

* chore(server launch.json): add ts-node script running example

* chore(server deps): add nodemailer types package

* refactor(server activitystream): add strongly typed activity definitions

* feat(server activitystream): add activity repository

* feat(server info): add canonical url on the service level

* feat(server): add static file serving route to server core

* feat(server): add dependencies for periodical email digests

* feat(server activity stream): call the initialization step from the activity stream module

* feat(server activity digest): add WIP weekly email digest implementation

* feat(server digest email): smul upgrades and fixes to the email template and its contents

* just for Fabs to test

* chore(root package.json): remove deleted docker-compose references

* feat(frontend profile): add notification preferences panel

* feat(server digest emails): set prod ready cron tab and timespan

* refactor(server email digest): move templates into the email module

* refactor(server activity digests): refactor to use notifications infrastructure

* test(server activities): add tests and some refactor to activities and notification preferences

* refactor(notification preferences): fix minor issues

* test(server notification preferences test): fix describe nesting

* fix(server activities): add missing action types

* fix(server activities): fix errors after merging main

* test(server activity notifications): add test coverage for activity notifications service

* refactor(server activities): fixing tests and some cleanup

* feat(server cli): add summary notification command to cli

* chore(dev env db versions): upgrade local dev env versions

* chore(server deps): upgrade local dev db to pg 14

* fix(docker-compose): bind maildev to localhost

* process-scoped notifications test queues

* test(activity tests): add  sleep to fix flaky CI

* feat(activity digests): add demo date for digest trigger

* feat(activity digest): add UK timezone trigger date

Co-authored-by: Iain Sproat <68657+iainsproat@users.noreply.github.com>
Co-authored-by: Fabians <fabis94@live.com>
2022-09-09 12:46:57 +02:00

169 lines
4.7 KiB
TypeScript

import { saveActivity } from '@/modules/activitystream/services'
import { ActionTypes, ResourceTypes } from '@/modules/activitystream/helpers/types'
import { StreamRoles } from '@/modules/core/helpers/mainConstants'
import { pubsub, StreamPubsubEvents } from '@/modules/shared'
/**
* Save "stream permissions granted to user" activity item
*/
export async function addStreamPermissionsAddedActivity(params: {
streamId: string
activityUserId: string
targetUserId: string
role: StreamRoles
}) {
const { streamId, activityUserId, targetUserId, role } = params
await Promise.all([
saveActivity({
streamId,
resourceType: ResourceTypes.Stream,
resourceId: streamId,
actionType: ActionTypes.Stream.PermissionsAdd,
userId: activityUserId,
info: { targetUser: targetUserId, role },
message: `Permission granted to user ${targetUserId} (${role})`
}),
pubsub.publish(StreamPubsubEvents.UserStreamAdded, {
userStreamAdded: {
id: streamId,
sharedBy: activityUserId
},
ownerId: targetUserId
})
])
}
/**
* Save "user accepted stream invite" activity item
*/
export async function addStreamInviteAcceptedActivity(params: {
streamId: string
inviteTargetId: string
inviterId: string
role: StreamRoles
}) {
const { streamId, inviteTargetId, inviterId, role } = params
await Promise.all([
saveActivity({
streamId,
resourceType: ResourceTypes.Stream,
resourceId: streamId,
actionType: ActionTypes.Stream.InviteAccepted,
userId: inviteTargetId,
info: { inviterUser: inviterId, role },
message: `User ${inviteTargetId} has accepted an invitation to become a ${role}`
}),
pubsub.publish(StreamPubsubEvents.UserStreamAdded, {
userStreamAdded: {
id: streamId,
sharedBy: inviterId
},
ownerId: inviteTargetId
})
])
}
/**
* Save "stream permissions revoked for user" activity item
*/
export async function addStreamPermissionsRevokedActivity(params: {
streamId: string
activityUserId: string
removedUserId: string
}) {
const { streamId, activityUserId, removedUserId } = params
const isVoluntaryLeave = activityUserId === removedUserId
await Promise.all([
saveActivity({
streamId,
resourceType: ResourceTypes.Stream,
resourceId: streamId,
actionType: ActionTypes.Stream.PermissionsRemove,
userId: activityUserId,
info: { targetUser: removedUserId },
message: isVoluntaryLeave
? `User ${removedUserId} left the stream`
: `Permission revoked for user ${removedUserId}`
}),
pubsub.publish(StreamPubsubEvents.UserStreamRemoved, {
userStreamRemoved: {
id: streamId,
revokedBy: activityUserId
},
ownerId: removedUserId
})
])
}
/**
* Save "user invited another user to stream" activity item
*/
export async function addStreamInviteSentOutActivity(params: {
streamId: string
inviteTargetId: string
inviterId: string
inviteTargetEmail: string
}) {
const { streamId, inviteTargetId, inviterId, inviteTargetEmail } = params
const targetDisplay = inviteTargetId || inviteTargetEmail
await saveActivity({
streamId,
resourceType: ResourceTypes.Stream,
resourceId: streamId,
actionType: ActionTypes.Stream.InviteSent,
userId: inviterId,
message: `User ${inviterId} has invited ${targetDisplay} to stream ${streamId}`,
info: { targetId: inviteTargetId || null, targetEmail: inviteTargetEmail || null }
})
}
/**
* Save "user declined an invite" activity item
*/
export async function addStreamInviteDeclinedActivity(params: {
streamId: string
inviteTargetId: string
inviterId: string
}) {
const { streamId, inviteTargetId, inviterId } = params
await saveActivity({
streamId,
resourceType: ResourceTypes.Stream,
resourceId: streamId,
actionType: ActionTypes.Stream.InviteDeclined,
userId: inviteTargetId,
message: `User ${inviteTargetId} declined to join the stream ${streamId}`,
info: { targetId: inviteTargetId, inviterId }
})
}
/**
* Save "user mentioned in stream comment" activity item
*/
export async function addStreamCommentMentionActivity(params: {
streamId: string
mentionAuthorId: string
mentionTargetId: string
commentId: string
threadId: string
}) {
const { streamId, mentionAuthorId, mentionTargetId, commentId, threadId } = params
await saveActivity({
streamId,
resourceType: ResourceTypes.Comment,
resourceId: commentId,
actionType: ActionTypes.Comment.Mention,
userId: mentionAuthorId,
message: `User ${mentionAuthorId} mentioned user ${mentionTargetId} in comment ${commentId}`,
info: {
mentionAuthorId,
mentionTargetId,
commentId,
threadId
}
})
}