Skip to content

Commit

Permalink
Merge pull request #686 from chaynHQ/develop
Browse files Browse the repository at this point in the history
Merge Develop onto Main
  • Loading branch information
annarhughes authored Oct 29, 2024
2 parents 4af82b7 + f5b1d16 commit 14936b2
Show file tree
Hide file tree
Showing 36 changed files with 821 additions and 336 deletions.
4 changes: 2 additions & 2 deletions docs/key-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ User authentication is handled by [Firebase Auth](https://firebase.google.com/do

Crisp is the messaging platform used to message the Chayn team in relation to bloom course content or other queries and support. For public users, this 1-1 chat feature is available on _live_ courses only. For partner users, This 1-1 chat feature is available to users with a `PartnerAccess` that has 1-1 chat enabled.

Users who have access to 1-1 chat also have a profile on Crisp that reflects data from our database regarding their partners, access and course progress. See [crisp-api.ts](src/api/crisp/crisp-api.ts)
Users who have access to 1-1 chat also have a profile on Crisp that reflects data from our database regarding their partners, access and course progress. See [crisp.service.ts](src/crisp/crisp.service.ts)

### Reporting

Google Data Studio is an online tool for converting data into customizable informative reports and dashboards.

The reports are generated by writing custom sql queries that return actionable data to Data Studio. Filters are applied in Data Studio allowing
data to be segregated into different time periods based on the data createdAt date
data to be segregated into different time periods based on the data createdAt date
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"axios": "^1.7.7",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"crisp-api": "^9.2.0",
"date-fns": "^3.6.0",
"dotenv": "^16.4.5",
"firebase": "^10.10.0",
Expand Down
127 changes: 0 additions & 127 deletions src/api/crisp/crisp-api.ts

This file was deleted.

4 changes: 4 additions & 0 deletions src/api/mailchimp/mailchimp-api.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export enum MAILCHIMP_MERGE_FIELD_TYPES {
ZIP = 'zip',
}

export enum MAILCHIMP_CUSTOM_EVENTS {
CRISP_MESSAGE_RECEIVED = 'CRISP_MESSAGE_RECEIVED',
}

export interface ListMemberCustomFields {
NAME?: string;
SIGNUPD?: string;
Expand Down
11 changes: 11 additions & 0 deletions src/api/mailchimp/mailchimp-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Logger } from '../../logger/logger';
import {
ListMember,
ListMemberPartial,
MAILCHIMP_CUSTOM_EVENTS,
MAILCHIMP_MERGE_FIELD_TYPES,
UpdateListMemberRequest,
} from './mailchimp-api.interfaces';
Expand Down Expand Up @@ -128,3 +129,13 @@ export const deleteCypressMailchimpProfiles = async () => {
throw new Error(`Delete cypress mailchimp profiles API call failed: ${error}`);
}
};

export const sendMailchimpUserEvent = async (email: string, event: MAILCHIMP_CUSTOM_EVENTS) => {
try {
await mailchimp.lists.createListMemberEvent(mailchimpAudienceId, getEmailMD5Hash(email), {
name: event,
});
} catch (error) {
throw new Error(`Send mailchimp user event failed: ${error}`);
}
};
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { AuthModule } from './auth/auth.module';
import { CoursePartnerModule } from './course-partner/course-partner.module';
import { CourseUserModule } from './course-user/course-user.module';
import { CourseModule } from './course/course.module';
import { CrispListenerModule } from './crisp-listener/crisp-listener.module';
import { CrispModule } from './crisp/crisp.module';
import { EventLoggerModule } from './event-logger/event-logger.module';
import { FeatureModule } from './feature/feature.module';
import { HealthModule } from './health/health.module';
Expand Down Expand Up @@ -43,6 +45,8 @@ import { WebhooksModule } from './webhooks/webhooks.module';
PartnerFeatureModule,
EventLoggerModule,
HealthModule,
CrispModule,
CrispListenerModule,
],
})
export class AppModule {}
13 changes: 13 additions & 0 deletions src/crisp-listener/crisp-listener.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CrispService } from 'src/crisp/crisp.service';
import { EventLogEntity } from 'src/entities/event-log.entity';
import { UserEntity } from 'src/entities/user.entity';
import { EventLoggerService } from 'src/event-logger/event-logger.service';
import { CrispListenerService } from './crisp-listener.service';

@Module({
imports: [TypeOrmModule.forFeature([EventLogEntity, UserEntity])],
providers: [CrispService, CrispListenerService, EventLoggerService],
})
export class CrispListenerModule {}
48 changes: 48 additions & 0 deletions src/crisp-listener/crisp-listener.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import Crisp from 'crisp-api';
import { EVENT_NAME } from 'src/crisp/crisp.interface';
import { CrispService } from 'src/crisp/crisp.service';
import { CrispEventDto } from 'src/crisp/dtos/crisp.dto';
import { crispPluginId, crispPluginKey } from 'src/utils/constants';
const CrispClient = new Crisp();
const logger = new Logger('CrispLogger');

// This service is split from CrispService due to CrispService being imported/initiated multiple times
// To avoid creating duplicate listeners and events, this CrispListenerService was decoupled
@Injectable()
export class CrispListenerService implements OnModuleInit {
constructor(private crispService: CrispService) {
CrispClient.authenticateTier('plugin', crispPluginId, crispPluginKey);
}

onModuleInit() {
logger.log(`Crisp service initiated`);

try {
const handleCrispEvent = async (message, eventName) =>
await this.crispService.handleCrispEvent(message, eventName);

CrispClient.on('message:send', async function (message: CrispEventDto) {
handleCrispEvent(message, EVENT_NAME.CHAT_MESSAGE_SENT);
})
.then(function () {
logger.log('Crisp service listening to sent messages');
})
.catch(function (error) {
logger.error('Crisp service failed listening to sent messages:', error);
});

CrispClient.on('message:received', function (message: CrispEventDto) {
handleCrispEvent(message, EVENT_NAME.CHAT_MESSAGE_RECEIVED);
})
.then(function () {
logger.log('Crisp service listening to received messages');
})
.catch(function (error) {
logger.error('Crisp service failed listening to sent messages:', error);
});
} catch (error) {
logger.error('Crisp service failed to initiate:', error);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import { EMAIL_REMINDERS_FREQUENCY } from '../../utils/constants';
import { EMAIL_REMINDERS_FREQUENCY } from 'src/utils/constants';

export enum EVENT_NAME {
CHAT_MESSAGE_SENT = 'CHAT_MESSAGE_SENT',
CHAT_MESSAGE_RECEIVED = 'CHAT_MESSAGE_RECEIVED',
LOGGED_IN = 'LOGGED_IN',
LOGGED_OUT = 'LOGGED_OUT',
}

export interface ICreateEventLog {
date: Date | string;
event: EVENT_NAME;
userId: string;
}

export interface CrispProfileCustomFields {
signed_up_at?: string;
Expand Down Expand Up @@ -32,8 +45,8 @@ export interface CrispProfileCustomFields {
export interface CrispProfileBase {
email?: string;
person?: {
nickname: string;
locales: string[];
nickname?: string;
locales?: string[];
};
segments?: string[];
notepad?: string;
Expand Down
12 changes: 12 additions & 0 deletions src/crisp/crisp.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EventLogEntity } from 'src/entities/event-log.entity';
import { UserEntity } from 'src/entities/user.entity';
import { EventLoggerService } from 'src/event-logger/event-logger.service';
import { CrispService } from './crisp.service';

@Module({
imports: [TypeOrmModule.forFeature([EventLogEntity, UserEntity])],
providers: [CrispService, EventLoggerService],
})
export class CrispModule {}
Loading

0 comments on commit 14936b2

Please sign in to comment.