Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger ortto activity when user saves their profile info for the first time #90

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions migrations/1714582062587-seedNotificationTypeForCreateOrttoUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MigrationInterface, QueryRunner } from "typeorm"
import { NOTIFICATION_CATEGORY, NOTIFICATION_TYPE_NAMES } from '../src/types/general';
import { MICRO_SERVICES } from '../src/utils/utils';
import { NotificationType, SCHEMA_VALIDATORS_NAMES } from '../src/entities/notificationType';

const OrttoUserNotificationType = [
{
name: NOTIFICATION_TYPE_NAMES.CREATE_ORTTO_PROFILE,
description: NOTIFICATION_TYPE_NAMES.CREATE_ORTTO_PROFILE,
microService: MICRO_SERVICES.givethio,
category: NOTIFICATION_CATEGORY.ORTTO,
schemaValidator: SCHEMA_VALIDATORS_NAMES.CREATE_ORTTO_PROFILE,
}
]

export class seedNotificationTypeForCreateOrttoUser1714582062587 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.manager.save(NotificationType, OrttoUserNotificationType);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DELETE FROM notification_type WHERE "name" = 'Create Ortto profile';`,
);
}
}
1 change: 1 addition & 0 deletions src/entities/notificationType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { NotificationSetting } from './notificationSetting';

// Export Object with Schemas to N1 lookup
export const SCHEMA_VALIDATORS_NAMES = {
CREATE_ORTTO_PROFILE: 'createOrttoProfile',
SUPERFLUID: 'userSuperTokensCritical',
ADMIN_MESSAGE: 'adminMessage',
RAW_HTML_BROADCAST: 'rawHtmlBroadcast',
Expand Down
39 changes: 31 additions & 8 deletions src/services/notificationService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
createNotification,
findNotificationByTrackId,
} from '../repositories/notificationRepository';
import { createNotification, findNotificationByTrackId } from '../repositories/notificationRepository';
import { errorMessages } from '../utils/errorMessages';
import { createNewUserAddressIfNotExists } from '../repositories/userAddressRepository';
import { getNotificationTypeByEventNameAndMicroservice } from '../repositories/notificationTypeRepository';
Expand All @@ -13,7 +10,8 @@ import { validateWithJoiSchema } from '../validators/schemaValidators';
import { SendNotificationRequest } from '../types/requestResponses';
import { StandardError } from '../types/StandardError';
import { NOTIFICATIONS_EVENT_NAMES, ORTTO_EVENT_NAMES } from '../types/notifications';
import {getEmailAdapter} from "../adapters/adapterFactory";
import { getEmailAdapter } from '../adapters/adapterFactory';
import { NOTIFICATION_CATEGORY } from '../types/general';

const activityCreator = (payload: any, orttoEventName: NOTIFICATIONS_EVENT_NAMES) : any=> {
const fields = {
Expand All @@ -24,6 +22,14 @@ const activityCreator = (payload: any, orttoEventName: NOTIFICATIONS_EVENT_NAMES
}
let attributes;
switch (orttoEventName) {
case NOTIFICATIONS_EVENT_NAMES.CREATE_ORTTO_PROFILE:
attributes = {
"str:cm:email": payload.email,
"str:cm:firstname": payload.firstName,
"str:cm:lastname": payload.lastName,
"str:cm:userid": payload.userId?.toString(),
}
break;
case NOTIFICATIONS_EVENT_NAMES.SUPER_TOKENS_BALANCE_DEPLETED:
attributes = {
"str:cm:tokensymbol": payload.tokenSymbol,
Expand Down Expand Up @@ -155,14 +161,21 @@ const activityCreator = (payload: any, orttoEventName: NOTIFICATIONS_EVENT_NAMES
logger.debug('activityCreator() invalid ORTTO_EVENT_NAMES', orttoEventName)
return;
}
const merge_by = [];
if (process.env.ENVIRONMENT === 'production') {
merge_by.push("str:cm:userid")
} else {
merge_by.push("str::email")
}
return {
activities: [
{
activity_id: `act:cm:${ORTTO_EVENT_NAMES[orttoEventName]}`,
attributes,
fields,
}
]
],
merge_by
};
}

Expand Down Expand Up @@ -195,7 +208,10 @@ export const sendNotification = async (
httpStatusCode: 400,
});
}
const notificationSetting =

const isOrttoSpecific = notificationType.category === NOTIFICATION_CATEGORY.ORTTO

const notificationSetting = isOrttoSpecific ? null :
await findNotificationSettingByNotificationTypeAndUserAddress({
notificationTypeId: notificationType.id,
userAddressId: userAddress.id,
Expand Down Expand Up @@ -232,7 +248,7 @@ export const sendNotification = async (
eventName: body.eventName,
});

if (shouldSendEmail && body.sendSegment && segmentValidator) {
if (((shouldSendEmail && body.sendSegment) || isOrttoSpecific) && segmentValidator) {
const emailData = body.segment?.payload;
validateWithJoiSchema(emailData, segmentValidator);
const data = activityCreator(emailData, body.eventName as NOTIFICATIONS_EVENT_NAMES);
Expand All @@ -242,6 +258,13 @@ export const sendNotification = async (
emailStatus = EMAIL_STATUSES.SENT;
}

if (isOrttoSpecific) {
return {
success: true,
message: errorMessages.ORTTO_SPECIFIC,
}
}

const metadataValidator =
SEGMENT_METADATA_SCHEMA_VALIDATOR[
notificationType?.schemaValidator as string
Expand Down
2 changes: 2 additions & 0 deletions src/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum NOTIFICATION_CATEGORY {
GIV_ECONOMY = 'givEconomy',
SUPPORTED_PROJECTS = 'supportedProjects',
GIV_POWER = 'givPower',
ORTTO = 'ortto'
}

export enum NOTIFICATION_TYPE_NAMES {
Expand Down Expand Up @@ -50,4 +51,5 @@ export enum NOTIFICATION_TYPE_NAMES {
PROJECT_HAS_A_NEW_RANK = 'Your project has a new rank',
PROJECT_HAS_RISEN_IN_THE_RANK = 'Your Project has risen in the rank',
YOUR_PROJECT_GOT_A_RANK = 'Your project got a rank',
CREATE_ORTTO_PROFILE = 'Create Ortto profile',
}
2 changes: 2 additions & 0 deletions src/types/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export enum NOTIFICATIONS_EVENT_NAMES {
SUPER_TOKENS_BALANCE_WEEK = 'One week left in stream balance',
SUPER_TOKENS_BALANCE_MONTH = 'One month left in stream balance',
SUPER_TOKENS_BALANCE_DEPLETED = 'Stream balance depleted',
CREATE_ORTTO_PROFILE = 'Create Ortto profile',
}

export const ORTTO_EVENT_NAMES = {
Expand All @@ -65,4 +66,5 @@ export const ORTTO_EVENT_NAMES = {
[NOTIFICATIONS_EVENT_NAMES.VERIFICATION_FORM_REJECTED]: 'project-verification',
[NOTIFICATIONS_EVENT_NAMES.PROJECT_BADGE_REVOKE_WARNING]: 'first-update-warning',
[NOTIFICATIONS_EVENT_NAMES.PROJECT_BADGE_REVOKE_LAST_WARNING]: 'second-update-warning',
[NOTIFICATIONS_EVENT_NAMES.CREATE_ORTTO_PROFILE]: 'created-profile'
}
1 change: 1 addition & 0 deletions src/utils/errorMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,5 @@ export const errorMessages = {
'You are not the owner of social profile',
ERROR_IN_GETTING_ACCESS_TOKEN_BY_AUTHORIZATION_CODE:
'Error in getting accessToken by authorization code',
ORTTO_SPECIFIC: 'Ortto specific notification'
};
11 changes: 11 additions & 0 deletions src/utils/validators/segmentAndMetadataValidators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,23 @@ const superFluidTokenSegmentSchema = Joi.object({
isEnded: Joi.boolean(),
});

const createOrttoProfileSegmentSchema = Joi.object({
email: Joi.string().required(),
firstName: Joi.string().required(),
lastName: Joi.string().required(),
userId: Joi.number().required()
})

export const SEGMENT_METADATA_SCHEMA_VALIDATOR: {
[key: string]: {
segment: ObjectSchema | null;
metadata: ObjectSchema | null;
};
} = {
createOrttoProfile: {
segment: createOrttoProfileSegmentSchema,
metadata: null
},
userSuperTokensCritical: {
metadata: superFluidTokenMetadataSchema,
segment: superFluidTokenSegmentSchema,
Expand Down
Loading