Skip to content

Commit a3ec6b9

Browse files
committed
feat: 서비스 종료 멘트 발송 기능 추가
1 parent ad65671 commit a3ec6b9

File tree

2 files changed

+49
-62
lines changed

2 files changed

+49
-62
lines changed
+47-55
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,55 @@
1-
import { Injectable, Logger } from '@nestjs/common';
2-
import { Motivation } from '@src/modules/motivation/entities/motivation.entity';
3-
import * as dayjs from 'dayjs';
4-
import { CategoryType } from '@src/modules/motivation/movitation.type';
5-
import { Cron, CronExpression } from '@nestjs/schedule';
6-
import { SlackInteractiveService } from '@src/modules/slack/service/slack.interactive.service';
7-
import { InjectRepository } from '@nestjs/typeorm';
8-
import { Repository } from 'typeorm';
9-
import { UserService } from '@src/modules/user/user.service';
10-
import { HolidayService } from '@src/modules/holiday/holiday.service';
11-
import { OnlineDatabaseInterfaceService } from '@lib/online-database-interface';
12-
import { MotivationModel } from '@lib/online-database-interface/online-database-interface.type';
13-
import { CategoryWeight } from '@src/modules/motivation/category.weight';
14-
import { ConfigService } from '@nestjs/config';
15-
import { getRandomNumber } from '@src/modules/common/utils';
1+
import { Injectable, Logger } from "@nestjs/common";
2+
import { Motivation } from "@src/modules/motivation/entities/motivation.entity";
3+
import * as dayjs from "dayjs";
4+
import { CategoryType } from "@src/modules/motivation/movitation.type";
5+
import { Cron, CronExpression } from "@nestjs/schedule";
6+
import { SlackInteractiveService } from "@src/modules/slack/service/slack.interactive.service";
7+
import { InjectRepository } from "@nestjs/typeorm";
8+
import { Repository } from "typeorm";
9+
import { UserService } from "@src/modules/user/user.service";
10+
import { HolidayService } from "@src/modules/holiday/holiday.service";
11+
import { OnlineDatabaseInterfaceService } from "@lib/online-database-interface";
12+
import { MotivationModel } from "@lib/online-database-interface/online-database-interface.type";
13+
import { CategoryWeight } from "@src/modules/motivation/category.weight";
14+
import { ConfigService } from "@nestjs/config";
15+
import { getRandomNumber } from "@src/modules/common/utils";
16+
import { User } from "@src/modules/user/entities/user.entity";
1617

1718
@Injectable()
1819
export class MotivationService {
1920
private readonly logger: Logger = new Logger(this.constructor.name);
21+
2022
constructor(
2123
@InjectRepository(Motivation) private motivationRepository: Repository<Motivation>,
2224
private readonly userService: UserService,
2325
private readonly holidayService: HolidayService,
2426
private readonly configService: ConfigService,
2527
private readonly slackInteractiveService: SlackInteractiveService,
26-
private readonly onlineDatabaseService: OnlineDatabaseInterfaceService,
27-
) {}
28+
private readonly onlineDatabaseService: OnlineDatabaseInterfaceService
29+
) {
30+
}
2831

2932
/**
3033
*
3134
* @private
3235
*/
3336
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, {
34-
timeZone: 'Asia/Seoul',
37+
timeZone: "Asia/Seoul"
3538
})
3639
private async createConfirmMotivation() {
3740
try {
3841
const modelList = await this.onlineDatabaseService.searchConfirmMotivation();
3942

4043
if (modelList.length === 0) {
41-
this.logger.log('승인된 추천 글귀가 없습니다.');
44+
this.logger.log("승인된 추천 글귀가 없습니다.");
4245
return;
4346
}
4447

4548
const makeEntityList = (resultList: MotivationModel[]) => {
4649
return resultList.map(({ contents, category }) => {
4750
return this.motivationRepository.create({
4851
contents: contents,
49-
category: CategoryType[category],
52+
category: CategoryType[category]
5053
});
5154
});
5255
};
@@ -57,7 +60,7 @@ export class MotivationService {
5760
await this.onlineDatabaseService.updateMotivationRecord(modelList);
5861
} catch (e) {
5962
if (e instanceof Error) {
60-
this.logger.error('추천 글귀 추가 과정 중 문제가 발생했습니다.');
63+
this.logger.error("추천 글귀 추가 과정 중 문제가 발생했습니다.");
6164
throw e;
6265
}
6366
}
@@ -68,23 +71,23 @@ export class MotivationService {
6871
* 지정한 공휴일의 경우 발송하지 않습니다.
6972
* @private
7073
*/
71-
@Cron('*/10 * * * 1-5', {
72-
timeZone: 'Asia/Seoul',
74+
@Cron("*/10 * * * 1-5", {
75+
timeZone: "Asia/Seoul"
7376
})
7477
private async sendMotivation(): Promise<void> {
7578
try {
76-
if (this.configService.get<string>('APP_ENV') !== 'prod') {
77-
this.logger.debug('운영환경이 아니기 때문에 종료합니다.');
79+
if (this.configService.get<string>("APP_ENV") !== "prod") {
80+
this.logger.debug("운영환경이 아니기 때문에 종료합니다.");
7881
return;
7982
}
8083

81-
const holiday = await this.holidayService.findOne(dayjs().format('YYYYMMDD'));
84+
const holiday = await this.holidayService.findOne(dayjs().format("YYYYMMDD"));
8285
if (holiday) {
83-
this.logger.log('공휴일이기 때문에 메시지 발송을 종료합니다.');
86+
this.logger.log("공휴일이기 때문에 메시지 발송을 종료합니다.");
8487
return;
8588
}
8689

87-
const time = dayjs().format('HH:mm');
90+
const time = dayjs().format("HH:mm");
8891
this.logger.log(`메시지 수신 대상자를 조회합니다. (${time})`);
8992
const userList = await this.userService.findSubscriberOnPushTime(time);
9093

@@ -102,12 +105,16 @@ export class MotivationService {
102105
await this.slackInteractiveService.postMessage(
103106
user.channelId,
104107
`${user.name}. 오늘의 메시지가 도착했어요. 오늘 하루도 힘내세요!
105-
>>>${motivation.contents}`,
108+
>>>${motivation.contents}`
106109
);
110+
const now = dayjs();
111+
if (now.year() === 2024 && now.month() === 10 && now.date() === 13 && !user.jerry) {
112+
await this.slackInteractiveService.postMessage(user.channelId, await this.getServiceClosedMessage(user));
113+
}
107114
}
108115
this.logger.log(`${userList.length}명에게 메시지 전송 완료. (${time})`);
109116
} catch (e) {
110-
if (e instanceof Error) this.logger.error('글귀 발송 과정 중 문제가 발생했습니다.');
117+
if (e instanceof Error) this.logger.error("글귀 발송 과정 중 문제가 발생했습니다.");
111118
throw e;
112119
}
113120
}
@@ -123,33 +130,18 @@ export class MotivationService {
123130
private async getMotivation(motivationList: Motivation[], category: CategoryType, isModernText: boolean) {
124131
const filteredMotivationList = motivationList.filter((item) => item.category === category);
125132
if (isModernText) {
126-
filteredMotivationList.push(...filteredMotivationList.filter((item) => item.category === CategoryType['기타']));
133+
filteredMotivationList.push(...filteredMotivationList.filter((item) => item.category === CategoryType["기타"]));
127134
}
128135
return filteredMotivationList[Math.floor(getRandomNumber() * filteredMotivationList.length)];
129136
}
130137

131-
// 이벤트 종료
132-
// /**
133-
// * 1주년 메시지 발송
134-
// * 2023-01-13 11:00 기준 구독자에게 전체 발송
135-
// private async sendEventMessage() {
136-
// const now = dayjs();
137-
// if (now.year() === 2023 && now.month() === 0 && now.date() === 13 && now.hour() === 11 && now.minute() === 0) {
138-
// const message = await this.notionService.searchEasterEgg(process.env.FIRST_YEAR_MESSAGE);
139-
//
140-
// const userList = await this.userRepository.find({
141-
// where: { isSubscribe: true },
142-
// });
143-
// userList.map(async (user) => {
144-
// let newMessage = message.replace(/\${name}/gi, user.name);
145-
// newMessage = newMessage.replace(/\${josa}/gi, isEndWithConsonant(user.name) ? '을' : '를');
146-
// try {
147-
// await this.slackInteractiveService.postMessage(user.channelId, newMessage);
148-
// } catch (e) {
149-
// this.logger.error(`${user.name} 오류`);
150-
// throw e;
151-
// }
152-
// });
153-
// }
154-
// }*/
138+
/**
139+
* 서비스 종료 메시지 발송
140+
* 2024-11-13 기준 구독자에게 전체 발송
141+
* */
142+
private async getServiceClosedMessage(user: User) {
143+
await this.userService.updateJerry(user.id);
144+
const message = await this.onlineDatabaseService.searchEasterEgg("서비스 종료");
145+
return message.replace(/\${name}/gi, user.name);
146+
}
155147
}

src/modules/user/user.service.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Injectable, Logger } from '@nestjs/common';
22
import { User } from '@src/modules/user/entities/user.entity';
33
import { InjectRepository } from '@nestjs/typeorm';
44
import { Repository, UpdateResult } from 'typeorm';
5-
import { Cron, CronExpression } from '@nestjs/schedule';
65
import { DeepPartial } from 'typeorm/common/DeepPartial';
76
import { CategoryType } from '@src/modules/motivation/movitation.type';
87

@@ -12,12 +11,8 @@ export class UserService {
1211

1312
constructor(@InjectRepository(User) private userRepository: Repository<User>) {}
1413

15-
/**
16-
* 매달 1일 jerry 리셋
17-
*/
18-
@Cron(CronExpression.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT, { timeZone: 'Asia/Seoul' })
19-
async resetJerry(): Promise<void> {
20-
await this.userRepository.update({ jerry: true }, { jerry: false });
14+
async updateJerry(id: string): Promise<void> {
15+
await this.userRepository.update({ id }, { jerry: true });
2116
this.logger.log('jerry 리셋 완료');
2217
}
2318
/**

0 commit comments

Comments
 (0)