From 0f2203ffa4d47f0240a3efa0c1f9ad82c7bf3338 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanovic Date: Wed, 5 Jul 2023 09:23:02 +0200 Subject: [PATCH] External invitations notification (#231) * Send notifications to external emails. * Add external invitation notification. * Fix external user notifications. * Update versions. * Use external users data from payload. * Fixed kratos identity path * Format multiple emails proper way. --------- Co-authored-by: Valentin Yanakiev --- lib/package-lock.json | 4 +- lib/package.json | 2 +- ...ternal.invitation.created.event.payload.ts | 8 ++ lib/src/dto/index.ts | 1 + lib/src/notification.event.type.ts | 1 + service/notifications.yml | 13 +- service/package-lock.json | 18 +-- service/package.json | 4 +- service/src/app.controller.ts | 17 +++ service/src/app.module.ts | 2 + ...ommunication.user.mention.email.payload.ts | 4 - ...ternal.invitation.created.email.payload.ts | 14 ++ .../common/email-template-payload/index.ts | 1 + service/src/common/enums/email.template.ts | 2 + ...n.recipient.template.provider.interface.ts | 1 + .../src/core/models/credential.criterion.ts | 2 + service/src/core/models/user.ts | 23 ++++ .../alkemio.url.generator.ts | 13 +- .../notification.builder.ts | 38 ++++-- .../utils/utils.ts | 32 ++++- ....callout.published.notification.builder.ts | 8 +- ...t.review.submitted.notification.builder.ts | 8 +- ...discussion.comment.notification.builder.ts | 8 +- ...aboration.interest.notification.builder.ts | 8 +- ...ation.post.comment.notification.builder.ts | 8 +- ...ation.post.created.notification.builder.ts | 8 +- ...whiteboard.created.notification.builder.ts | 8 +- .../comment.reply.notification.builder.ts | 10 +- ...nity.leads.message.notification.builder.ts | 8 +- ...ganization.mention.notification.builder.ts | 8 +- ...ganization.message.notification.builder.ts | 8 +- ...ion.update.created.notification.builder.ts | 8 +- ...ation.user.mention.notification.builder.ts | 12 +- ...ation.user.message.notification.builder.ts | 8 +- ...pplication.created.notification.builder.ts | 10 +- ...invitation.created.notification.builder.ts | 120 ++++++++++++++++++ ...invitation.created.notification.builder.ts | 10 +- ...mmunity.new.member.notification.builder.ts | 8 +- service/src/services/domain/builders/index.ts | 1 + ...discussion.comment.notification.builder.ts | 8 +- ...discussion.created.notification.builder.ts | 8 +- ...rm.user.registered.notification.builder.ts | 8 +- ...tform.user.removed.notification.builder.ts | 13 +- .../notification/notification.service.spec.ts | 2 + .../notification/notification.service.ts | 12 ++ .../src/templates/alkemio.template.blocks.js | 8 +- ...ity.external.invitation.created.invitee.js | 28 ++++ ...ity.external.invitation.created.inviter.js | 27 ++++ .../community.invitation.created.invitee.js | 3 +- 49 files changed, 431 insertions(+), 153 deletions(-) create mode 100644 lib/src/dto/community.external.invitation.created.event.payload.ts create mode 100644 service/src/common/email-template-payload/community.external.invitation.created.email.payload.ts create mode 100644 service/src/services/domain/builders/community-external-invitation-created/community.external.invitation.created.notification.builder.ts create mode 100644 service/src/templates/community.external.invitation.created.invitee.js create mode 100644 service/src/templates/community.external.invitation.created.inviter.js diff --git a/lib/package-lock.json b/lib/package-lock.json index fdfe4cc5..11d2a82d 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -1,12 +1,12 @@ { "name": "@alkemio/notifications-lib", - "version": "0.5.3", + "version": "0.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@alkemio/notifications-lib", - "version": "0.5.3", + "version": "0.6.0", "license": "EUPL-1.2", "devDependencies": { "@types/node": "^16.4.6", diff --git a/lib/package.json b/lib/package.json index cac95112..6a855ecc 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,6 +1,6 @@ { "name": "@alkemio/notifications-lib", - "version": "0.5.3", + "version": "0.6.0", "description": "Library for interacting with Alkemio notifications service", "author": "Alkemio Foundation", "private": false, diff --git a/lib/src/dto/community.external.invitation.created.event.payload.ts b/lib/src/dto/community.external.invitation.created.event.payload.ts new file mode 100644 index 00000000..f9223c54 --- /dev/null +++ b/lib/src/dto/community.external.invitation.created.event.payload.ts @@ -0,0 +1,8 @@ +import { JourneyBaseEventPayload } from './journey.base.event.payload'; +export interface CommunityExternalInvitationCreatedEventPayload + extends JourneyBaseEventPayload { + invitees: { + email: string; + }[]; + welcomeMessage?: string; +} diff --git a/lib/src/dto/index.ts b/lib/src/dto/index.ts index 0258f116..c50610b3 100644 --- a/lib/src/dto/index.ts +++ b/lib/src/dto/index.ts @@ -9,6 +9,7 @@ export * from './communication.organization.mention.event.payload'; export * from './community.application.created.event.payload'; export * from './community.new.member.payload'; export * from './community.invitation.created.event.payload'; +export * from './community.external.invitation.created.event.payload'; export * from './collaboration.interest.payload'; export * from './collaboration.whiteboard.created.event.payload'; export * from './collaboration.post.created.event.payload'; diff --git a/lib/src/notification.event.type.ts b/lib/src/notification.event.type.ts index 037286ff..5f2df235 100644 --- a/lib/src/notification.event.type.ts +++ b/lib/src/notification.event.type.ts @@ -2,6 +2,7 @@ export enum NotificationEventType { COMMUNITY_APPLICATION_CREATED = 'communityApplicationCreated', COMMUNITY_NEW_MEMBER = 'communityNewMember', COMMUNITY_INVITATION_CREATED = 'communityInvitationCreated', + COMMUNITY_EXTERNAL_INVITATION_CREATED = 'communityExternalInvitationCreated', COMMUNICATION_COMMENT_SENT = 'communicationCommentSent', COMMUNICATION_UPDATE_SENT = 'communicationUpdateSent', COMMUNICATION_USER_MESSAGE = 'communicationUserMessage', diff --git a/service/notifications.yml b/service/notifications.yml index 67e4618c..7548bdb9 100644 --- a/service/notifications.yml +++ b/service/notifications.yml @@ -83,7 +83,7 @@ alkemio: password: ${SERVICE_ACCOUNT_PASSWORD}:change-me-now kratos: - public_endpoint: ${KRATOS_API_PUBLIC_ENDPOINT}:http://localhost:3000/identity/ory/kratos/public + public_endpoint: ${KRATOS_API_PUBLIC_ENDPOINT}:http://localhost:3000/ory/kratos/public recipients: community_application_created: @@ -132,6 +132,17 @@ recipients: - rule: type: USER_SELF_MANAGEMENT resource_id: + community_external_invitation_created: + - name: inviter + rules: + - rule: + type: USER_SELF_MANAGEMENT + resource_id: + - name: invitee + rules: + - rule: + type: EXTERNAL_USER + resource_id: communication_update_sent: - name: admin rules: diff --git a/service/package-lock.json b/service/package-lock.json index cf081a34..0713a8bc 100644 --- a/service/package-lock.json +++ b/service/package-lock.json @@ -1,16 +1,16 @@ { "name": "alkemio-notifications", - "version": "0.12.0", + "version": "0.13.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "alkemio-notifications", - "version": "0.12.0", + "version": "0.13.0", "license": "EUPL-1.2", "dependencies": { "@alkemio/client-lib": "^0.21.0", - "@alkemio/notifications-lib": "^0.5.3", + "@alkemio/notifications-lib": "^0.6.0", "@nestjs/common": "^8.0.5", "@nestjs/config": "^1.0.1", "@nestjs/core": "^8.0.5", @@ -185,9 +185,9 @@ } }, "node_modules/@alkemio/notifications-lib": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@alkemio/notifications-lib/-/notifications-lib-0.5.3.tgz", - "integrity": "sha512-SYBSyH8jKFdL9UElNpkvLwAg7Wh/rYF+c3z5KeN+7+KUVI/eVHb/9N7o9JPwip4IMN1fDwqXHe/ufWVbVawPpg==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@alkemio/notifications-lib/-/notifications-lib-0.6.0.tgz", + "integrity": "sha512-Li0gcC9FFBXJMAPuLeCaGYJHd77CK2nSAYsOjti+qcZljNH9ht1exSvyA0U4ofhTFopDx+Kc85s10EeSTJLoVA==", "engines": { "node": ">=16.15.0", "npm": ">=8.5.5" @@ -14670,9 +14670,9 @@ } }, "@alkemio/notifications-lib": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@alkemio/notifications-lib/-/notifications-lib-0.5.3.tgz", - "integrity": "sha512-SYBSyH8jKFdL9UElNpkvLwAg7Wh/rYF+c3z5KeN+7+KUVI/eVHb/9N7o9JPwip4IMN1fDwqXHe/ufWVbVawPpg==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@alkemio/notifications-lib/-/notifications-lib-0.6.0.tgz", + "integrity": "sha512-Li0gcC9FFBXJMAPuLeCaGYJHd77CK2nSAYsOjti+qcZljNH9ht1exSvyA0U4ofhTFopDx+Kc85s10EeSTJLoVA==" }, "@angular-devkit/core": { "version": "13.3.6", diff --git a/service/package.json b/service/package.json index 75e7f1a8..4b83b492 100644 --- a/service/package.json +++ b/service/package.json @@ -1,6 +1,6 @@ { "name": "alkemio-notifications", - "version": "0.12.0", + "version": "0.13.0", "description": "Alkemio notifications service", "author": "Alkemio Foundation", "private": false, @@ -36,7 +36,7 @@ }, "dependencies": { "@alkemio/client-lib": "^0.21.0", - "@alkemio/notifications-lib": "^0.5.3", + "@alkemio/notifications-lib": "^0.6.0", "@nestjs/common": "^8.0.5", "@nestjs/config": "^1.0.1", "@nestjs/core": "^8.0.5", diff --git a/service/src/app.controller.ts b/service/src/app.controller.ts index 30eefdbf..786c2243 100644 --- a/service/src/app.controller.ts +++ b/service/src/app.controller.ts @@ -37,6 +37,7 @@ import { } from '@alkemio/notifications-lib'; import { NotificationService } from './services/domain/notification/notification.service'; import { ALKEMIO_CLIENT_ADAPTER, LogContext } from './common/enums'; +import { CommunityExternalInvitationCreatedEventPayload } from '@alkemio/notifications-lib'; @Controller() export class AppController { @@ -78,6 +79,22 @@ export class AppController { ); } + @EventPattern(NotificationEventType.COMMUNITY_EXTERNAL_INVITATION_CREATED) + async sendExternalInvitationNotification( + // todo is auto validation possible + @Payload() eventPayload: CommunityExternalInvitationCreatedEventPayload, + @Ctx() context: RmqContext + ) { + this.sendNotifications( + eventPayload, + context, + this.notificationService.sendExternalInvitationCreatedNotifications( + eventPayload + ), + NotificationEventType.COMMUNITY_EXTERNAL_INVITATION_CREATED + ); + } + @EventPattern(NotificationEventType.COMMUNITY_NEW_MEMBER) async sendCommunityNewMemberNotification( // todo is auto validation possible diff --git a/service/src/app.module.ts b/service/src/app.module.ts index ea9034aa..209cacc3 100644 --- a/service/src/app.module.ts +++ b/service/src/app.module.ts @@ -39,6 +39,7 @@ import { CollaborationWhiteboardCreatedNotificationBuilder } from './services/do import { CollaborationDiscussionCommentNotificationBuilder } from './services/domain/builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder'; import { CommunityInvitationCreatedNotificationBuilder } from './services/domain/builders/community-invitation-created/community.invitation.created.notification.builder'; import { CommentReplyNotificationBuilder } from './services/domain/builders/comment-reply/comment.reply.notification.builder'; +import { CommunityExternalInvitationCreatedNotificationBuilder } from './services/domain/builders/community-external-invitation-created/community.external.invitation.created.notification.builder'; @Module({ imports: [ @@ -64,6 +65,7 @@ import { CommentReplyNotificationBuilder } from './services/domain/builders/comm NotificationBuilder, CommunityApplicationCreatedNotificationBuilder, CommunityInvitationCreatedNotificationBuilder, + CommunityExternalInvitationCreatedNotificationBuilder, PlatformUserRegisteredNotificationBuilder, PlatformUserRemovedNotificationBuilder, PlatformForumDiscussionCommentNotificationBuilder, diff --git a/service/src/common/email-template-payload/communication.user.mention.email.payload.ts b/service/src/common/email-template-payload/communication.user.mention.email.payload.ts index 294dc020..807629d1 100644 --- a/service/src/common/email-template-payload/communication.user.mention.email.payload.ts +++ b/service/src/common/email-template-payload/communication.user.mention.email.payload.ts @@ -6,10 +6,6 @@ export interface CommunicationUserMentionEmailPayload extends BaseEmailPayload { firstName: string; }; comment: string; - mentionedUser: { - displayName: string; - firstName: string; - }; commentOrigin: { url: string; displayName: string; diff --git a/service/src/common/email-template-payload/community.external.invitation.created.email.payload.ts b/service/src/common/email-template-payload/community.external.invitation.created.email.payload.ts new file mode 100644 index 00000000..048c456e --- /dev/null +++ b/service/src/common/email-template-payload/community.external.invitation.created.email.payload.ts @@ -0,0 +1,14 @@ +import { BaseJourneyEmailPayload } from './base.journey.email.payload'; + +export interface CommunityExternalInvitationCreatedEmailPayload + extends BaseJourneyEmailPayload { + inviter: { + name: string; + firstName: string; + email: string; + profile: string; + }; + welcomeMessage?: string; + emails?: string; + journeyAdminURL: string; +} diff --git a/service/src/common/email-template-payload/index.ts b/service/src/common/email-template-payload/index.ts index 1af6f247..96c69021 100644 --- a/service/src/common/email-template-payload/index.ts +++ b/service/src/common/email-template-payload/index.ts @@ -2,6 +2,7 @@ export * from './base.email.payload'; export * from './base.journey.email.payload'; export * from './community.application.created.email.payload'; export * from './community.invitation.created.email.payload'; +export * from './community.external.invitation.created.email.payload'; export * from './community.new.member.email.payload'; export * from './collaboration.whiteboard.created.email.payload'; export * from './collaboration.post.comment.email.payload'; diff --git a/service/src/common/enums/email.template.ts b/service/src/common/enums/email.template.ts index 4c52a711..f330c2e7 100644 --- a/service/src/common/enums/email.template.ts +++ b/service/src/common/enums/email.template.ts @@ -6,6 +6,8 @@ export enum EmailTemplate { COMMUNITY_INVITATION_ADMIN = 'community.invitation.created.admin', COMMUNITY_INVITATION_INVITEE = 'community.invitation.created.invitee', COMMUNITY_INVITATION_INVITER = 'community.invitation.created.inviter', + COMMUNITY_EXTERNAL_INVITATION_INVITEE = 'community.external.invitation.created.invitee', + COMMUNITY_EXTERNAL_INVITATION_INVITER = 'community.external.invitation.created.inviter', COMMUNICATION_UPDATE_ADMIN = 'communication.update.admin', COMMUNICATION_UPDATE_MEMBER = 'communication.update.member', COMMUNICATION_USER_MESSAGE_SENDER = 'communication.user.message.sender', diff --git a/service/src/core/contracts/notification.recipient.template.provider.interface.ts b/service/src/core/contracts/notification.recipient.template.provider.interface.ts index b18f066a..9b6e8b02 100644 --- a/service/src/core/contracts/notification.recipient.template.provider.interface.ts +++ b/service/src/core/contracts/notification.recipient.template.provider.interface.ts @@ -16,6 +16,7 @@ export type TemplateRuleSet = { export type TemplateConfig = { community_application_created?: TemplateRuleSet[]; community_invitation_created?: TemplateRuleSet[]; + community_external_invitation_created?: TemplateRuleSet[]; community_new_member?: TemplateRuleSet[]; communication_update_sent?: TemplateRuleSet[]; platform_forum_discussion_created?: TemplateRuleSet[]; diff --git a/service/src/core/models/credential.criterion.ts b/service/src/core/models/credential.criterion.ts index e449e33c..c876c303 100644 --- a/service/src/core/models/credential.criterion.ts +++ b/service/src/core/models/credential.criterion.ts @@ -1,5 +1,7 @@ import { AuthorizationCredential } from '@alkemio/client-lib'; +export const ROLE_EXTERNAL_USER = 'EXTERNAL_USER'; + export type CredentialCriterion = { type: AuthorizationCredential; resourceID?: string; diff --git a/service/src/core/models/user.ts b/service/src/core/models/user.ts index ab372297..3341185b 100644 --- a/service/src/core/models/user.ts +++ b/service/src/core/models/user.ts @@ -11,6 +11,29 @@ export type User = { }; }; +export type InternalUser = { + id: string; + nameID: string; + firstName: string; + lastName: string; + email: string; + preferences?: UserPreference[]; + profile: { + id: string; + displayName: string; + }; +}; + +export type ExternalUser = { + firstName: string; + lastName: string; + email: string; +}; + +export const isUser = (user: User | ExternalUser): user is User => { + return (user as User).nameID !== undefined; +}; + export type UserPreference = { definition: UserPreferenceDefinition; value: string; diff --git a/service/src/services/application/alkemio-url-generator/alkemio.url.generator.ts b/service/src/services/application/alkemio-url-generator/alkemio.url.generator.ts index 31cec87e..ab196b89 100644 --- a/service/src/services/application/alkemio-url-generator/alkemio.url.generator.ts +++ b/service/src/services/application/alkemio-url-generator/alkemio.url.generator.ts @@ -13,6 +13,7 @@ import { createOrganizationURL as libCreateOrganizationURL, createUserNotificationPreferencesURL as libCreateUserNotificationPreferencesURL, } from '@alkemio/notifications-lib'; +import { ExternalUser, User, isUser } from '@src/core/models'; @Injectable() export class AlkemioUrlGenerator { @@ -67,10 +68,12 @@ export class AlkemioUrlGenerator { return libCreateOrganizationURL(this.webclientEndpoint, orgNameID); } - createUserNotificationPreferencesURL(userNameID: string): string { - return libCreateUserNotificationPreferencesURL( - this.webclientEndpoint, - userNameID - ); + createUserNotificationPreferencesURL(user: User | ExternalUser): string { + return isUser(user) + ? libCreateUserNotificationPreferencesURL( + this.webclientEndpoint, + user.nameID + ) + : ''; } } diff --git a/service/src/services/application/notification-builder/notification.builder.ts b/service/src/services/application/notification-builder/notification.builder.ts index 79bc599f..f3c25b22 100644 --- a/service/src/services/application/notification-builder/notification.builder.ts +++ b/service/src/services/application/notification-builder/notification.builder.ts @@ -8,7 +8,7 @@ import { import { AlkemioClientAdapter } from '@src/services'; import { EmailTemplate } from '@common/enums/email.template'; import { UserPreferenceType } from '@alkemio/client-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { INotificationRecipientTemplateProvider, TemplateConfig, @@ -24,6 +24,10 @@ import { TEMPLATE_PROVIDER, } from '@src/common/enums/providers'; import { LogContext } from '@src/common/enums'; +import { + filterCredentialCriterion, + isCredentialCriterionExternalUser, +} from '../template-to-credential-mapper/utils/utils'; export type RoleConfig = { role: string; @@ -33,7 +37,7 @@ export type RoleConfig = { export type TemplateType = keyof TemplateConfig; export type TemplateBuilderFn = ( payload: TPayload, - recipient: User, + recipient: User | ExternalUser, eventUser?: User ) => TEmailPayload; @@ -53,6 +57,8 @@ export type NotificationOptions< eventUserId?: string; /** variables to be used into the chosen templateType if any */ templateVariables?: Record; + /** external users to which email addresses the notification will be sent */ + externalUsers?: ExternalUser[]; }; export class NotificationBuilder< @@ -124,7 +130,8 @@ export class NotificationBuilder< rolePreferenceType?: UserPreferenceType; } ): Promise { - const { templateType, roleConfig, templateVariables } = options; + const { templateType, roleConfig, templateVariables, externalUsers } = + options; this.logger.verbose?.( `[${emailTemplate} - '${recipientRole}'] Building notifications - start'`, LogContext.NOTIFICATIONS @@ -139,7 +146,6 @@ export class NotificationBuilder< `No rule set(s) found for roles: [${rolesText}]` ); } - const variableMap = templateVariables ? new Map( Object.keys(templateVariables).map(x => [x, templateVariables[x]]) @@ -153,12 +159,23 @@ export class NotificationBuilder< ruleSets ); + const filteredCriteria = filterCredentialCriterion(credentialCriteria); + const recipients = await this.alkemioAdapter.getUniqueUsersMatchingCredentialCriteria( - credentialCriteria + filteredCriteria ); - if (!recipients.length) { + const externalRecipients: ExternalUser[] = []; + + if ( + isCredentialCriterionExternalUser(credentialCriteria) && + externalUsers + ) { + externalRecipients.push(...externalUsers); + } + + if (!recipients.length && !externalRecipients) { const criteriaText = credentialCriteria .map(x => `<${x.type},${x.resourceID}>`) .join(' OR '); @@ -219,7 +236,12 @@ export class NotificationBuilder< LogContext.NOTIFICATIONS ); - const notifications = filteredRecipients.map(recipient => + const notificationRecipients = [ + ...filteredRecipients, + ...externalRecipients, + ]; + + const notifications = notificationRecipients.map(recipient => this.buildNotificationTemplate( options, recipient, @@ -252,7 +274,7 @@ export class NotificationBuilder< private async buildNotificationTemplate( options: NotificationOptions, - recipient: User, + recipient: User | ExternalUser, templateName: string, eventUser?: User ): Promise { diff --git a/service/src/services/application/template-to-credential-mapper/utils/utils.ts b/service/src/services/application/template-to-credential-mapper/utils/utils.ts index 5014c4f7..cdac4e76 100644 --- a/service/src/services/application/template-to-credential-mapper/utils/utils.ts +++ b/service/src/services/application/template-to-credential-mapper/utils/utils.ts @@ -1,6 +1,6 @@ import { LogContext } from '@common/enums'; import { TemplateRule } from '@core/contracts'; -import { CredentialCriterion } from '@core/models'; +import { CredentialCriterion, ROLE_EXTERNAL_USER } from '@core/models'; import { NotSupportedException } from '@src/common/exceptions'; /*** @@ -69,3 +69,33 @@ export const getResourceId = ( return lookupValue; }; + +/*** + * Filteres credential list from notification service role types + * @param credentialCriteria + * @returns Credential creiteria list + */ +export const filterCredentialCriterion = ( + credentialCriteria: CredentialCriterion[] +): CredentialCriterion[] => { + return credentialCriteria.filter( + criteria => (criteria.type as string) !== ROLE_EXTERNAL_USER + ); +}; + +/*** + * Filteres credential list from notification service role types + * @param credentialCriteria + * @returns Credential creiteria list + */ +export const isCredentialCriterionExternalUser = ( + credentialCriteria: CredentialCriterion[] +): boolean => { + const criteria = credentialCriteria.find( + criteria => (criteria.type as string) === ROLE_EXTERNAL_USER + ); + + if (criteria) return true; + + return false; +}; diff --git a/service/src/services/domain/builders/collaboration-callout-published/collaboration.callout.published.notification.builder.ts b/service/src/services/domain/builders/collaboration-callout-published/collaboration.callout.published.notification.builder.ts index f24cd739..9806f85d 100644 --- a/service/src/services/domain/builders/collaboration-callout-published/collaboration.callout.published.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-callout-published/collaboration.callout.published.notification.builder.ts @@ -7,7 +7,7 @@ import { } from '@src/services/application'; import { NotificationTemplateType } from '@src/types'; import { UserPreferenceType } from '@alkemio/client-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { EmailTemplate } from '@common/enums/email.template'; import { CollaborationCalloutPublishedEventPayload } from '@alkemio/notifications-lib'; @@ -56,7 +56,7 @@ export class CollaborationCalloutPublishedNotificationBuilder createTemplatePayload( eventPayload: CollaborationCalloutPublishedEventPayload, - recipient: User, + recipient: User | ExternalUser, creator?: User ): CollaborationCalloutPublishedEmailPayload { if (!creator) { @@ -66,9 +66,7 @@ export class CollaborationCalloutPublishedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioUrl = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( diff --git a/service/src/services/domain/builders/collaboration-context-feedback/collaboration.context.review.submitted.notification.builder.ts b/service/src/services/domain/builders/collaboration-context-feedback/collaboration.context.review.submitted.notification.builder.ts index 67d08006..b8d4df93 100644 --- a/service/src/services/domain/builders/collaboration-context-feedback/collaboration.context.review.submitted.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-context-feedback/collaboration.context.review.submitted.notification.builder.ts @@ -7,7 +7,7 @@ import { } from '@alkemio/notifications-lib'; import { EmailTemplate } from '@common/enums/email.template'; import { UserPreferenceType } from '@alkemio/client-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { AlkemioUrlGenerator, NotificationBuilder, @@ -65,7 +65,7 @@ export class CollaborationContextReviewSubmittedNotificationBuilder createTemplatePayload( eventPayload: CollaborationContextReviewSubmittedPayload, - recipient: User, + recipient: User | ExternalUser, reviewer?: User ): CollaborationContextReviewEmailPayload { if (!reviewer) { @@ -75,9 +75,7 @@ export class CollaborationContextReviewSubmittedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); diff --git a/service/src/services/domain/builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder.ts b/service/src/services/domain/builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder.ts index 70967428..1b79f09c 100644 --- a/service/src/services/domain/builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder.ts @@ -8,7 +8,7 @@ import { } from '@src/services/application'; import { NotificationTemplateType } from '@src/types'; import { EmailTemplate } from '@common/enums/email.template'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { CollaborationDiscussionCommentEventPayload, @@ -58,7 +58,7 @@ export class CollaborationDiscussionCommentNotificationBuilder createTemplatePayload( eventPayload: CollaborationDiscussionCommentEventPayload, - recipient: User, + recipient: User | ExternalUser, commentAuthor?: User ): CollaborationDiscussionCommentEmailPayload { if (!commentAuthor) { @@ -67,9 +67,7 @@ export class CollaborationDiscussionCommentNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( diff --git a/service/src/services/domain/builders/collaboration-interest/collaboration.interest.notification.builder.ts b/service/src/services/domain/builders/collaboration-interest/collaboration.interest.notification.builder.ts index 22d11b08..6cffcf95 100644 --- a/service/src/services/domain/builders/collaboration-interest/collaboration.interest.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-interest/collaboration.interest.notification.builder.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { UserPreferenceType } from '@alkemio/client-lib'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { AlkemioUrlGenerator, NotificationBuilder, @@ -64,7 +64,7 @@ export class CollaborationInterestNotificationBuilder private createTemplatePayload( eventPayload: CollaborationInterestPayload, - recipient: User, + recipient: User | ExternalUser, user?: User ): CollaborationInterestEmailPayload { if (!user) { @@ -74,9 +74,7 @@ export class CollaborationInterestNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); diff --git a/service/src/services/domain/builders/collaboration-post-comment/collaboration.post.comment.notification.builder.ts b/service/src/services/domain/builders/collaboration-post-comment/collaboration.post.comment.notification.builder.ts index 819e7ec8..2c5cdd43 100644 --- a/service/src/services/domain/builders/collaboration-post-comment/collaboration.post.comment.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-post-comment/collaboration.post.comment.notification.builder.ts @@ -10,7 +10,7 @@ import { } from '@src/services/application'; import { NotificationTemplateType } from '@src/types'; import { EmailTemplate } from '@common/enums/email.template'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { NotificationEventType } from '@alkemio/notifications-lib'; @@ -53,7 +53,7 @@ export class CollaborationPostCommentNotificationBuilder createTemplatePayload( eventPayload: CollaborationPostCommentEventPayload, - recipient: User, + recipient: User | ExternalUser, commentAuthor?: User ): CollaborationPostCommentEmailPayload { if (!commentAuthor) { @@ -62,9 +62,7 @@ export class CollaborationPostCommentNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( diff --git a/service/src/services/domain/builders/collaboration-post-created/collaboration.post.created.notification.builder.ts b/service/src/services/domain/builders/collaboration-post-created/collaboration.post.created.notification.builder.ts index a3313e29..a44b6584 100644 --- a/service/src/services/domain/builders/collaboration-post-created/collaboration.post.created.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-post-created/collaboration.post.created.notification.builder.ts @@ -7,7 +7,7 @@ import { RoleConfig, } from '@src/services/application'; import { NotificationTemplateType } from '@src/types'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { EmailTemplate } from '@common/enums/email.template'; import { CollaborationPostCreatedEmailPayload } from '@common/email-template-payload'; @@ -64,7 +64,7 @@ export class CollaborationPostCreatedNotificationBuilder createTemplatePayload( eventPayload: CollaborationPostCreatedEventPayload, - recipient: User, + recipient: User | ExternalUser, creator?: User ): CollaborationPostCreatedEmailPayload { if (!creator) { @@ -74,9 +74,7 @@ export class CollaborationPostCreatedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( diff --git a/service/src/services/domain/builders/collaboration-whiteboard-created/collaboration.whiteboard.created.notification.builder.ts b/service/src/services/domain/builders/collaboration-whiteboard-created/collaboration.whiteboard.created.notification.builder.ts index 8fd41172..72085c58 100644 --- a/service/src/services/domain/builders/collaboration-whiteboard-created/collaboration.whiteboard.created.notification.builder.ts +++ b/service/src/services/domain/builders/collaboration-whiteboard-created/collaboration.whiteboard.created.notification.builder.ts @@ -8,7 +8,7 @@ import { RoleConfig, } from '@src/services/application'; import { NotificationTemplateType } from '@src/types'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { EmailTemplate } from '@common/enums/email.template'; import { CollaborationWhiteboardCreatedEmailPayload } from '@common/email-template-payload'; @@ -64,7 +64,7 @@ export class CollaborationWhiteboardCreatedNotificationBuilder createTemplatePayload( eventPayload: CollaborationWhiteboardCreatedEventPayload, - recipient: User, + recipient: User | ExternalUser, creator?: User ): CollaborationWhiteboardCreatedEmailPayload { if (!creator) { @@ -74,9 +74,7 @@ export class CollaborationWhiteboardCreatedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( diff --git a/service/src/services/domain/builders/comment-reply/comment.reply.notification.builder.ts b/service/src/services/domain/builders/comment-reply/comment.reply.notification.builder.ts index c8a7625b..c5abadf6 100644 --- a/service/src/services/domain/builders/comment-reply/comment.reply.notification.builder.ts +++ b/service/src/services/domain/builders/comment-reply/comment.reply.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { EmailTemplate } from '@common/enums/email.template'; import { CommentReplyEventPayload } from '@alkemio/notifications-lib'; import { UserPreferenceType } from '@alkemio/client-lib'; @@ -53,7 +53,7 @@ export class CommentReplyNotificationBuilder implements INotificationBuilder { createTemplatePayload( eventPayload: CommentReplyEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommentReplyEmailPayload { if (!sender) { @@ -63,16 +63,14 @@ export class CommentReplyNotificationBuilder implements INotificationBuilder { } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', reply: { message: eventPayload.reply, createdBy: sender.profile.displayName, - createdByUrl: this.alkemioUrlGenerator.createUserURL(recipient.nameID), + createdByUrl: this.alkemioUrlGenerator.createUserURL(sender.nameID), }, comment: eventPayload.comment, recipient: { diff --git a/service/src/services/domain/builders/communication-community-message/communication.community.leads.message.notification.builder.ts b/service/src/services/domain/builders/communication-community-message/communication.community.leads.message.notification.builder.ts index 8f7e0d86..804fcd0f 100644 --- a/service/src/services/domain/builders/communication-community-message/communication.community.leads.message.notification.builder.ts +++ b/service/src/services/domain/builders/communication-community-message/communication.community.leads.message.notification.builder.ts @@ -3,7 +3,7 @@ import { NotificationEventType, CommunicationCommunityLeadsMessageEventPayload, } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; import { NotificationBuilder, RoleConfig } from '../../../application'; @@ -61,7 +61,7 @@ export class CommunicationCommunityLeadsMessageNotificationBuilder private createTemplatePayload( eventPayload: CommunicationCommunityLeadsMessageEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationCommunityLeadsMessageEmailPayload { if (!sender) { @@ -70,9 +70,7 @@ export class CommunicationCommunityLeadsMessageNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const journeyURL = this.alkemioUrlGenerator.createJourneyURL( eventPayload.journey diff --git a/service/src/services/domain/builders/communication-organization-mention/communication.organization.mention.notification.builder.ts b/service/src/services/domain/builders/communication-organization-mention/communication.organization.mention.notification.builder.ts index 3bfe2eea..167f18fb 100644 --- a/service/src/services/domain/builders/communication-organization-mention/communication.organization.mention.notification.builder.ts +++ b/service/src/services/domain/builders/communication-organization-mention/communication.organization.mention.notification.builder.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { CommunicationOrganizationMentionEventPayload } from '@alkemio/notifications-lib'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; @@ -52,7 +52,7 @@ export class CommunicationOrganizationMentionNotificationBuilder private createTemplatePayload( eventPayload: CommunicationOrganizationMentionEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationOrganizationMentionEmailPayload { if (!sender) { @@ -61,9 +61,7 @@ export class CommunicationOrganizationMentionNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const htmlComment: string = convertMarkdownToText(eventPayload.comment); diff --git a/service/src/services/domain/builders/communication-organization-message/communication.organization.message.notification.builder.ts b/service/src/services/domain/builders/communication-organization-message/communication.organization.message.notification.builder.ts index 872826ae..940111d1 100644 --- a/service/src/services/domain/builders/communication-organization-message/communication.organization.message.notification.builder.ts +++ b/service/src/services/domain/builders/communication-organization-message/communication.organization.message.notification.builder.ts @@ -3,7 +3,7 @@ import { NotificationEventType, CommunicationOrganizationMessageEventPayload, } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; import { NotificationBuilder, RoleConfig } from '../../../application'; @@ -59,7 +59,7 @@ export class CommunicationOrganizationMessageNotificationBuilder private createTemplatePayload( eventPayload: CommunicationOrganizationMessageEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationOrganizationMessageEmailPayload { if (!sender) { @@ -68,9 +68,7 @@ export class CommunicationOrganizationMessageNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { diff --git a/service/src/services/domain/builders/communication-update-created/communication.update.created.notification.builder.ts b/service/src/services/domain/builders/communication-update-created/communication.update.created.notification.builder.ts index 84aa5467..55af6936 100644 --- a/service/src/services/domain/builders/communication-update-created/communication.update.created.notification.builder.ts +++ b/service/src/services/domain/builders/communication-update-created/communication.update.created.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { EmailTemplate } from '@common/enums/email.template'; import { CommunicationUpdateEventPayload } from '@alkemio/notifications-lib'; import { UserPreferenceType } from '@alkemio/client-lib'; @@ -66,7 +66,7 @@ export class CommunicationUpdateCreatedNotificationBuilder createTemplatePayload( eventPayload: CommunicationUpdateEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationUpdateCreatedEmailPayload { if (!sender) { @@ -76,9 +76,7 @@ export class CommunicationUpdateCreatedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', diff --git a/service/src/services/domain/builders/communication-user-mention/communication.user.mention.notification.builder.ts b/service/src/services/domain/builders/communication-user-mention/communication.user.mention.notification.builder.ts index cbd16a46..32be9177 100644 --- a/service/src/services/domain/builders/communication-user-mention/communication.user.mention.notification.builder.ts +++ b/service/src/services/domain/builders/communication-user-mention/communication.user.mention.notification.builder.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { CommunicationUserMentionEventPayload } from '@alkemio/notifications-lib'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; @@ -53,7 +53,7 @@ export class CommunicationUserMentionNotificationBuilder private createTemplatePayload( eventPayload: CommunicationUserMentionEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationUserMentionEmailPayload { if (!sender) { @@ -62,9 +62,7 @@ export class CommunicationUserMentionNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const htmlComment: string = convertMarkdownToText(eventPayload.comment); @@ -84,10 +82,6 @@ export class CommunicationUserMentionNotificationBuilder platform: { url: alkemioURL, }, - mentionedUser: { - displayName: recipient.profile.displayName, - firstName: recipient.firstName, - }, commentOrigin: { url: eventPayload.commentOrigin.url, displayName: eventPayload.commentOrigin.displayName, diff --git a/service/src/services/domain/builders/communication-user-message/communication.user.message.notification.builder.ts b/service/src/services/domain/builders/communication-user-message/communication.user.message.notification.builder.ts index 30d7bcda..31c37040 100644 --- a/service/src/services/domain/builders/communication-user-message/communication.user.message.notification.builder.ts +++ b/service/src/services/domain/builders/communication-user-message/communication.user.message.notification.builder.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { CommunicationUserMessageEventPayload } from '@alkemio/notifications-lib'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; @@ -56,7 +56,7 @@ export class CommunicationUserMessageNotificationBuilder private createTemplatePayload( eventPayload: CommunicationUserMessageEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): CommunicationUserMessageEmailPayload { if (!sender) { @@ -65,9 +65,7 @@ export class CommunicationUserMessageNotificationBuilder ); } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { diff --git a/service/src/services/domain/builders/community-application-created/community.application.created.notification.builder.ts b/service/src/services/domain/builders/community-application-created/community.application.created.notification.builder.ts index f55e3f22..0f5dfee6 100644 --- a/service/src/services/domain/builders/community-application-created/community.application.created.notification.builder.ts +++ b/service/src/services/domain/builders/community-application-created/community.application.created.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { CommunityApplicationCreatedEventPayload } from '@alkemio/notifications-lib'; import { AlkemioUrlGenerator, @@ -62,7 +62,7 @@ export class CommunityApplicationCreatedNotificationBuilder private createTemplatePayload( eventPayload: CommunityApplicationCreatedEventPayload, - recipient: User, + recipient: User | ExternalUser, applicant?: User ): CommunityApplicationCreatedEmailPayload { if (!applicant) { @@ -81,9 +81,7 @@ export class CommunityApplicationCreatedNotificationBuilder eventPayload.journey ); const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', @@ -95,7 +93,7 @@ export class CommunityApplicationCreatedNotificationBuilder }, journeyAdminURL: communityAdminURL, recipient: { - firstName: recipient.profile.displayName, + firstName: recipient.firstName, email: recipient.email, notificationPreferences: notificationPreferenceURL, }, diff --git a/service/src/services/domain/builders/community-external-invitation-created/community.external.invitation.created.notification.builder.ts b/service/src/services/domain/builders/community-external-invitation-created/community.external.invitation.created.notification.builder.ts new file mode 100644 index 00000000..7f20386f --- /dev/null +++ b/service/src/services/domain/builders/community-external-invitation-created/community.external.invitation.created.notification.builder.ts @@ -0,0 +1,120 @@ +import { Injectable, Inject } from '@nestjs/common'; +import { NotificationEventType } from '@alkemio/notifications-lib'; +import { INotificationBuilder } from '@core/contracts'; +import { ExternalUser, User } from '@core/models'; +import { CommunityExternalInvitationCreatedEventPayload } from '@alkemio/notifications-lib'; +import { + AlkemioUrlGenerator, + NotificationBuilder, + RoleConfig, +} from '../../../application'; +import { NotificationTemplateType } from '@src/types'; +import { EmailTemplate } from '@common/enums/email.template'; +import { CommunityExternalInvitationCreatedEmailPayload } from '@common/email-template-payload'; +import { ALKEMIO_URL_GENERATOR } from '@src/common/enums/providers'; + +@Injectable() +export class CommunityExternalInvitationCreatedNotificationBuilder + implements INotificationBuilder +{ + constructor( + @Inject(ALKEMIO_URL_GENERATOR) + private readonly alkemioUrlGenerator: AlkemioUrlGenerator, + private readonly notificationBuilder: NotificationBuilder< + CommunityExternalInvitationCreatedEventPayload, + CommunityExternalInvitationCreatedEmailPayload + > + ) {} + + build( + payload: CommunityExternalInvitationCreatedEventPayload + ): Promise { + const roleConfig: RoleConfig[] = [ + { + role: 'inviter', + emailTemplate: EmailTemplate.COMMUNITY_EXTERNAL_INVITATION_INVITER, + }, + { + role: 'invitee', + emailTemplate: EmailTemplate.COMMUNITY_EXTERNAL_INVITATION_INVITEE, + }, + ]; + + const templateVariables = { + inviterID: payload.triggeredBy, + spaceID: payload.journey.spaceID, + challengeID: payload.journey.challenge?.id ?? '', + opportunityID: payload.journey.challenge?.opportunity?.id ?? '', + }; + + const externalUsers = payload.invitees.map(invitee => ({ + email: invitee.email, + firstName: '', + lastName: '', + })); + + return this.notificationBuilder.build({ + payload, + eventUserId: payload.triggeredBy, + roleConfig, + templateType: 'community_external_invitation_created', + templateVariables, + templatePayloadBuilderFn: this.createTemplatePayload.bind(this), + externalUsers, + }); + } + + private createTemplatePayload( + eventPayload: CommunityExternalInvitationCreatedEventPayload, + recipient: User | ExternalUser, + inviter?: User + ): CommunityExternalInvitationCreatedEmailPayload { + if (!inviter) { + throw Error( + `Invitee not provided for '${NotificationEventType.COMMUNITY_INVITATION_CREATED} event'` + ); + } + const inviterProfileURL = this.alkemioUrlGenerator.createUserURL( + inviter.nameID + ); + const communityURL = this.alkemioUrlGenerator.createJourneyURL( + eventPayload.journey + ); + const communityAdminURL = + this.alkemioUrlGenerator.createJourneyAdminCommunityURL( + eventPayload.journey + ); + const notificationPreferenceURL = + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); + const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); + const emails = [...eventPayload.invitees] + .map(invitedUser => invitedUser.email) + .join(', '); + + return { + emailFrom: 'info@alkem.io', + inviter: { + firstName: inviter.firstName, + name: inviter.profile.displayName, + email: inviter.email, + profile: inviterProfileURL, + }, + journeyAdminURL: communityAdminURL, + recipient: { + firstName: recipient.firstName, + email: recipient.email, + notificationPreferences: notificationPreferenceURL, + }, + emails: emails, + welcomeMessage: eventPayload.welcomeMessage, + journey: { + displayName: eventPayload.journey.displayName, + type: eventPayload.journey.type, + url: communityURL, + }, + platform: { + url: alkemioURL, + }, + }; + } +} diff --git a/service/src/services/domain/builders/community-invitation-created/community.invitation.created.notification.builder.ts b/service/src/services/domain/builders/community-invitation-created/community.invitation.created.notification.builder.ts index 68d3e173..f8a99add 100644 --- a/service/src/services/domain/builders/community-invitation-created/community.invitation.created.notification.builder.ts +++ b/service/src/services/domain/builders/community-invitation-created/community.invitation.created.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { CommunityInvitationCreatedEventPayload } from '@alkemio/notifications-lib'; import { AlkemioUrlGenerator, @@ -58,7 +58,7 @@ export class CommunityInvitationCreatedNotificationBuilder private createTemplatePayload( eventPayload: CommunityInvitationCreatedEventPayload, - recipient: User, + recipient: User | ExternalUser, inviter?: User ): CommunityInvitationCreatedEmailPayload { if (!inviter) { @@ -77,9 +77,7 @@ export class CommunityInvitationCreatedNotificationBuilder eventPayload.journey ); const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', @@ -91,7 +89,7 @@ export class CommunityInvitationCreatedNotificationBuilder }, journeyAdminURL: communityAdminURL, recipient: { - firstName: recipient.profile.displayName, + firstName: recipient.firstName, email: recipient.email, notificationPreferences: notificationPreferenceURL, }, diff --git a/service/src/services/domain/builders/community-new-member/community.new.member.notification.builder.ts b/service/src/services/domain/builders/community-new-member/community.new.member.notification.builder.ts index 0d73f0d1..21fa8ed7 100644 --- a/service/src/services/domain/builders/community-new-member/community.new.member.notification.builder.ts +++ b/service/src/services/domain/builders/community-new-member/community.new.member.notification.builder.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { UserPreferenceType } from '@alkemio/client-lib'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { AlkemioUrlGenerator, NotificationBuilder, @@ -62,7 +62,7 @@ export class CommunityNewMemberNotificationBuilder private createTemplatePayload( eventPayload: CommunityNewMemberPayload, - recipient: User, + recipient: User | ExternalUser, member?: User ): CommunityNewMemberEmailPayload { if (!member) { @@ -72,9 +72,7 @@ export class CommunityNewMemberNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); const memberProfileURL = this.alkemioUrlGenerator.createUserURL( diff --git a/service/src/services/domain/builders/index.ts b/service/src/services/domain/builders/index.ts index 4ebb1db6..ac554c5a 100644 --- a/service/src/services/domain/builders/index.ts +++ b/service/src/services/domain/builders/index.ts @@ -1,5 +1,6 @@ export * from './community-application-created/community.application.created.notification.builder'; export * from './community-invitation-created/community.invitation.created.notification.builder'; +export * from './community-external-invitation-created/community.external.invitation.created.notification.builder'; export * from './communication-update-created/communication.update.created.notification.builder'; export * from './communication-user-message/communication.user.message.notification.builder'; export * from './communication-organization-message/communication.organization.message.notification.builder'; diff --git a/service/src/services/domain/builders/platform-forum-discussion-comment/platform.forum.discussion.comment.notification.builder.ts b/service/src/services/domain/builders/platform-forum-discussion-comment/platform.forum.discussion.comment.notification.builder.ts index c447749c..994dd053 100644 --- a/service/src/services/domain/builders/platform-forum-discussion-comment/platform.forum.discussion.comment.notification.builder.ts +++ b/service/src/services/domain/builders/platform-forum-discussion-comment/platform.forum.discussion.comment.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { EmailTemplate } from '@common/enums/email.template'; import { PlatformForumDiscussionCommentEventPayload } from '@alkemio/notifications-lib'; import { UserPreferenceType } from '@alkemio/client-lib'; @@ -54,7 +54,7 @@ export class PlatformForumDiscussionCommentNotificationBuilder createTemplatePayload( eventPayload: PlatformForumDiscussionCommentEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): PlatformForumDiscussionCommentEmailPayload { if (!sender) { @@ -64,9 +64,7 @@ export class PlatformForumDiscussionCommentNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', diff --git a/service/src/services/domain/builders/platform-forum-discussion-created/platform.forum.discussion.created.notification.builder.ts b/service/src/services/domain/builders/platform-forum-discussion-created/platform.forum.discussion.created.notification.builder.ts index b1d65e2c..b0f2a9c9 100644 --- a/service/src/services/domain/builders/platform-forum-discussion-created/platform.forum.discussion.created.notification.builder.ts +++ b/service/src/services/domain/builders/platform-forum-discussion-created/platform.forum.discussion.created.notification.builder.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ALKEMIO_URL_GENERATOR } from '@common/enums'; import { INotificationBuilder } from '@core/contracts'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { EmailTemplate } from '@common/enums/email.template'; import { PlatformForumDiscussionCreatedEventPayload } from '@alkemio/notifications-lib'; import { UserPreferenceType } from '@alkemio/client-lib'; @@ -52,7 +52,7 @@ export class PlatformForumDiscussionCreatedNotificationBuilder createTemplatePayload( eventPayload: PlatformForumDiscussionCreatedEventPayload, - recipient: User, + recipient: User | ExternalUser, sender?: User ): PlatformForumDiscussionCreatedEmailPayload { if (!sender) { @@ -62,9 +62,7 @@ export class PlatformForumDiscussionCreatedNotificationBuilder } const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', diff --git a/service/src/services/domain/builders/platform-user-registered/platform.user.registered.notification.builder.ts b/service/src/services/domain/builders/platform-user-registered/platform.user.registered.notification.builder.ts index b8157362..d708506e 100644 --- a/service/src/services/domain/builders/platform-user-registered/platform.user.registered.notification.builder.ts +++ b/service/src/services/domain/builders/platform-user-registered/platform.user.registered.notification.builder.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { NotificationEventType } from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { ExternalUser, User } from '@core/models'; import { PlatformUserRegistrationEventPayload } from '@alkemio/notifications-lib'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; @@ -53,7 +53,7 @@ export class PlatformUserRegisteredNotificationBuilder private createTemplatePayload( eventPayload: PlatformUserRegistrationEventPayload, - recipient: User, + recipient: User | ExternalUser, registrant?: User ): PlatformUserRegisteredEmailPayload { if (!registrant) { @@ -66,9 +66,7 @@ export class PlatformUserRegisteredNotificationBuilder registrant.nameID ); const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); const alkemioURL = this.alkemioUrlGenerator.createPlatformURL(); return { emailFrom: 'info@alkem.io', diff --git a/service/src/services/domain/builders/platform-user-removed/platform.user.removed.notification.builder.ts b/service/src/services/domain/builders/platform-user-removed/platform.user.removed.notification.builder.ts index a06db6ad..72d37601 100644 --- a/service/src/services/domain/builders/platform-user-removed/platform.user.removed.notification.builder.ts +++ b/service/src/services/domain/builders/platform-user-removed/platform.user.removed.notification.builder.ts @@ -1,9 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; -import { - NotificationEventType, - PlatformUserRemovedEventPayload, -} from '@alkemio/notifications-lib'; -import { User } from '@core/models'; +import { PlatformUserRemovedEventPayload } from '@alkemio/notifications-lib'; +import { ExternalUser, User } from '@core/models'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; import { INotificationBuilder } from '@core/contracts/notification.builder.interface'; import { NotificationBuilder, RoleConfig } from '../../../application'; @@ -51,12 +48,10 @@ export class PlatformUserRemovedNotificationBuilder private createTemplatePayload( eventPayload: PlatformUserRemovedEventPayload, - recipient: User + recipient: User | ExternalUser ): PlatformUserRemovedEmailPayload { const notificationPreferenceURL = - this.alkemioUrlGenerator.createUserNotificationPreferencesURL( - recipient.nameID - ); + this.alkemioUrlGenerator.createUserNotificationPreferencesURL(recipient); return { emailFrom: 'info@alkem.io', registrant: { diff --git a/service/src/services/domain/notification/notification.service.spec.ts b/service/src/services/domain/notification/notification.service.spec.ts index ad202bca..2e943e11 100644 --- a/service/src/services/domain/notification/notification.service.spec.ts +++ b/service/src/services/domain/notification/notification.service.spec.ts @@ -34,6 +34,7 @@ import { PlatformForumDiscussionCommentNotificationBuilder, CommunityInvitationCreatedNotificationBuilder, CommentReplyNotificationBuilder, + CommunityExternalInvitationCreatedNotificationBuilder, } from '../builders'; import { AlkemioUrlGenerator } from '@src/services/application/alkemio-url-generator'; import { @@ -74,6 +75,7 @@ describe('NotificationService', () => { NotificationService, CommunityApplicationCreatedNotificationBuilder, CommunityInvitationCreatedNotificationBuilder, + CommunityExternalInvitationCreatedNotificationBuilder, PlatformUserRegisteredNotificationBuilder, PlatformForumDiscussionCommentNotificationBuilder, PlatformUserRemovedNotificationBuilder, diff --git a/service/src/services/domain/notification/notification.service.ts b/service/src/services/domain/notification/notification.service.ts index 6f1e0d69..29e0e5d1 100644 --- a/service/src/services/domain/notification/notification.service.ts +++ b/service/src/services/domain/notification/notification.service.ts @@ -51,12 +51,14 @@ import { CommunicationUserMentionNotificationBuilder, CommunicationOrganizationMentionNotificationBuilder, CommunityInvitationCreatedNotificationBuilder, + CommunityExternalInvitationCreatedNotificationBuilder, } from '../builders'; import { NotificationNoChannelsException } from '@src/common/exceptions'; import { PlatformUserRemovedNotificationBuilder } from '../builders/platform-user-removed/platform.user.removed.notification.builder'; import { CollaborationWhiteboardCreatedNotificationBuilder } from '../builders/collaboration-whiteboard-created/collaboration.whiteboard.created.notification.builder'; import { CollaborationDiscussionCommentNotificationBuilder } from '../builders/collaboration-discussion-comment/collaboration.discussion.comment.notification.builder'; import { CommentReplyNotificationBuilder } from '../builders/comment-reply/comment.reply.notification.builder'; +import { CommunityExternalInvitationCreatedEventPayload } from '@alkemio/notifications-lib'; @Injectable() export class NotificationService { @@ -69,6 +71,7 @@ export class NotificationService { private readonly notifmeService: NotifmeSdk, private communityApplicationCreatedNotificationBuilder: CommunityApplicationCreatedNotificationBuilder, private communityInvitationCreatedNotificationBuilder: CommunityInvitationCreatedNotificationBuilder, + private communityExternalInvitationCreatedNotificationBuilder: CommunityExternalInvitationCreatedNotificationBuilder, private platformUserRegisteredNotificationBuilder: PlatformUserRegisteredNotificationBuilder, private platformUserRemovedNotificationBuilder: PlatformUserRemovedNotificationBuilder, private platformForumDiscussionCommentNotificationBuilder: PlatformForumDiscussionCommentNotificationBuilder, @@ -130,6 +133,15 @@ export class NotificationService { ); } + async sendExternalInvitationCreatedNotifications( + payload: CommunityExternalInvitationCreatedEventPayload + ): Promise[]> { + return this.sendNotifications( + payload, + this.communityExternalInvitationCreatedNotificationBuilder + ); + } + async sendCommunityNewMemberNotifications( payload: CommunityNewMemberPayload ): Promise[]> { diff --git a/service/src/templates/alkemio.template.blocks.js b/service/src/templates/alkemio.template.blocks.js index b4913c4f..66974bed 100644 --- a/service/src/templates/alkemio.template.blocks.js +++ b/service/src/templates/alkemio.template.blocks.js @@ -11,7 +11,8 @@ module.exports = { >Join our community   -Notification settings -  + > +   +{% endif %} {{inviter.firstName}} has invited you to join {{journey.displayName}}. + {% if welcomeMessage %} + {{inviter.firstName}} has sent you this message: + {{welcomeMessage}} + + {% endif %} + + Sincerely yours, + {% endblock %} + ${templates.footerBlock}`, + }, + }, +}); diff --git a/service/src/templates/community.external.invitation.created.inviter.js b/service/src/templates/community.external.invitation.created.inviter.js new file mode 100644 index 00000000..c0108bda --- /dev/null +++ b/service/src/templates/community.external.invitation.created.inviter.js @@ -0,0 +1,27 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const templates = require('./alkemio.template.blocks'); +/* eslint-disable quotes */ +module.exports = () => ({ + name: 'community-external-invitation-created-inviter', + title: '[{{journey.displayName}}] Invitation sent', + version: 1, + channels: { + email: { + from: '{{emailFrom}}', + to: '{{recipient.email}}', + subject: 'Invitation to join {{journey.displayName}}', + html: `{% extends "src/templates/_layouts/email-transactional.html" %} + {% block content %}Hi {{inviter.name}}, + + You have invited {{emails}} to join {{journey.displayName}}. + {% if welcomeMessage %} + You have sent him this message: + {{welcomeMessage}} + + {% endif %} + Sincerely yours, + {% endblock %} + ${templates.footerBlock}`, + }, + }, +}); diff --git a/service/src/templates/community.invitation.created.invitee.js b/service/src/templates/community.invitation.created.invitee.js index 40a771d2..c2519cff 100644 --- a/service/src/templates/community.invitation.created.invitee.js +++ b/service/src/templates/community.invitation.created.invitee.js @@ -3,7 +3,7 @@ const templates = require('./alkemio.template.blocks'); /* eslint-disable quotes */ module.exports = () => ({ name: 'community-invitation-created-invitee', - title: '[{{journey.displayName}}] Application from {{applicant.firstName}}', + title: '[{{journey.displayName}}] Invitation from {{inviter.name}}', version: 1, channels: { email: { @@ -14,6 +14,7 @@ module.exports = () => ({ {% block content %}Hi {{recipient.firstName}}, {{inviter.firstName}} has invited you to join {{journey.displayName}}. + {{welcomeMessage}} Sincerely yours, {% endblock %}