Skip to content

Commit ba81626

Browse files
authored
Merge pull request #975 from techmatters/CHI-3568-conversation_cleanup
CHI-3568: Conversation cleanup job
2 parents 6a21bde + 4c4372b commit ba81626

File tree

18 files changed

+710
-46
lines changed

18 files changed

+710
-46
lines changed

hrm-domain/hrm-core/case/caseService.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import {
4747
hrmSearchConfiguration,
4848
} from '@tech-matters/hrm-search-config';
4949
import { publishCaseChangeNotification } from '../notifications/entityChangeNotify';
50-
import { enablePublishHrmSearchIndex } from '../featureFlags';
5150
import { getClient } from '@tech-matters/elasticsearch-client';
5251
import {
5352
CaseListCondition,
@@ -123,10 +122,6 @@ const doCaseChangeNotification =
123122
caseRecord?: CaseRecord;
124123
}) => {
125124
try {
126-
if (!enablePublishHrmSearchIndex) {
127-
return;
128-
}
129-
130125
const caseObj =
131126
caseRecord ?? (await getById(parseInt(caseId), accountSid, maxPermissions.user));
132127

hrm-domain/hrm-core/contact/contactService.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ import { actionsMaps } from '../permissions';
5959
import type { TwilioUser } from '@tech-matters/twilio-worker-auth';
6060
import { createReferral } from '../referral/referralService';
6161
import { createContactJob } from '../contact-job/contact-job';
62-
import { enablePublishHrmSearchIndex } from '../featureFlags';
6362
import {
6463
type ConversationMedia,
6564
type NewConversationMedia,
@@ -207,10 +206,6 @@ const doContactChangeNotification =
207206
contactId: Contact['id'];
208207
}) => {
209208
try {
210-
if (!enablePublishHrmSearchIndex) {
211-
return;
212-
}
213-
214209
const contact = await getById(accountSid, parseInt(contactId));
215210

216211
if (contact) {

hrm-domain/hrm-core/featureFlags.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,8 @@
1313
* You should have received a copy of the GNU Affero General Public License
1414
* along with this program. If not, see https://www.gnu.org/licenses/.
1515
*/
16-
export const enableCleanupJobs = /^true$/i.test(process.env.ENABLE_CLEANUP_JOBS);
17-
export const enableProfileFlagsCleanup = /^true$/i.test(
18-
process.env.ENABLE_PROFILE_FLAGS_CLEANUP,
19-
);
20-
export const enablePublishHrmSearchIndex = /^true$/i.test(
21-
process.env.ENABLE_PUBLISH_HRM_SEARCH_INDEX,
22-
);
23-
export const enableSnsHrmSearchIndex = /^true$/i.test(
24-
process.env.ENABLE_SNS_HRM_SEARCH_INDEX,
16+
export const enableConversationsCleanup = /^true$/i.test(
17+
process.env.ENABLE_CONVERSATIONS_CLEANUP,
2518
);
2619
export const enableDbUserPerAccount = /^true$/i.test(
2720
process.env.ENABLE_DB_USER_PER_ACCOUNT,

hrm-domain/hrm-service/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"start": "cd dist && node ./www",
77
"start:job-processor": "cd dist && node ./jobProcessor",
88
"start:job-cleanup": "cd dist && node ./jobCleanup",
9+
"start:conversation-cleanup": "cd dist && node ./conversationCleanup",
910
"start:job-case-status-transition": "cd dist && node ./jobCaseStatusTransition",
1011
"start:job-cleanup:local": "AWS_REGION=us-east-1 SSM_ENDPOINT=http://localhost:4566 SQS_ENDPOINT=http://localhost:4566 run-s start:job-cleanup",
1112
"start:generate-ai-training-set": "cd dist && node ./generateAiTrainingSet",
@@ -46,6 +47,7 @@
4647
"dependencies": {
4748
"@tech-matters/case-status-transition": "^1.0.0",
4849
"@tech-matters/contact-job-cleanup": "^1.0.0",
50+
"@tech-matters/conversation-cleanup": "^1.0.0",
4951
"@tech-matters/generate-ai-training-set": "^1.0.0",
5052
"@tech-matters/hrm-core": "^1.0.0",
5153
"@tech-matters/hrm-types": "^1.0.0",

hrm-domain/hrm-service/service-tests/contact-job/contactJobCleanup.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ beforeAll(async () => {
7070
process.env.TWILIO_AUTH_TOKEN = 'mockAuthToken';
7171
process.env.TWILIO_CLIENT_USE_ENV_AUTH_TOKEN = 'true';
7272
const client = await getClient({ accountSid });
73-
twilioSpy = jest.spyOn(client.chat.v2, 'services');
73+
twilioSpy = jest.spyOn(client.conversations.v1.conversations, 'get');
7474

7575
await mockingProxy.start();
7676
const mockttp = await mockingProxy.mockttpServer();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (C) 2021-2023 Technology Matters
3+
* This program is free software: you can redistribute it and/or modify
4+
* it under the terms of the GNU Affero General Public License as published
5+
* by the Free Software Foundation, either version 3 of the License, or
6+
* (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU Affero General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU Affero General Public License
14+
* along with this program. If not, see https://www.gnu.org/licenses/.
15+
*/
16+
17+
import { handleSignals } from './handleSignals';
18+
import { cleanupConversations } from '@tech-matters/conversation-cleanup';
19+
import { enableConversationsCleanup } from '@tech-matters/hrm-core/featureFlags';
20+
21+
const gracefulExit = async () => {
22+
//Only a Twilio and AWS client is used, so nothing to do here.
23+
};
24+
25+
if (enableConversationsCleanup) {
26+
cleanupConversations();
27+
28+
handleSignals(gracefulExit);
29+
} else {
30+
console.debug('enableCleanupJobs not set, skipping conversation cleanup.');
31+
}

hrm-domain/hrm-service/src/jobCleanup.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@
1616

1717
import { handleSignals } from './handleSignals';
1818
import { cleanupContactJobs } from '@tech-matters/contact-job-cleanup';
19-
import { enableCleanupJobs } from '@tech-matters/hrm-core/featureFlags';
2019

2120
const gracefulExit = async () => {
2221
//TODO: this should probably handle closing any running processes and open db connections
2322
};
2423

25-
if (enableCleanupJobs) {
26-
cleanupContactJobs();
24+
cleanupContactJobs();
2725

28-
handleSignals(gracefulExit);
29-
}
26+
handleSignals(gracefulExit);

hrm-domain/hrm-service/src/profileFlagsCleanup.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,12 @@
1515
*/
1616

1717
import { handleSignals } from './handleSignals';
18-
import { enableProfileFlagsCleanup } from '@tech-matters/hrm-core/featureFlags';
1918
import { cleanupProfileFlags } from '@tech-matters/profile-flags-cleanup';
2019

2120
const gracefulExit = async () => {
2221
//TODO: this should probably handle closing any running processes and open db connections
2322
};
2423

25-
if (enableProfileFlagsCleanup) {
26-
cleanupProfileFlags();
24+
cleanupProfileFlags();
2725

28-
handleSignals(gracefulExit);
29-
}
26+
handleSignals(gracefulExit);

hrm-domain/hrm-service/tsconfig.build.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
{ "path": "hrm-domain/packages/hrm-search-config" },
2121
{ "path": "hrm-domain/hrm-core" },
2222
{ "path": "hrm-domain/scheduled-tasks/contact-job-cleanup" },
23+
{ "path": "hrm-domain/scheduled-tasks/conversation-cleanup" },
2324
{ "path": "hrm-domain/scheduled-tasks/case-status-transition" },
2425
{ "path": "hrm-domain/scheduled-tasks/profile-flags-cleanup" },
2526
{ "path": "hrm-domain/scheduled-tasks/generate-ai-training-set" },

hrm-domain/scheduled-tasks/contact-job-cleanup/index.ts

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { ContactJobType } from '@tech-matters/types';
1818
import { getClient } from '@tech-matters/twilio-client';
19-
import { getSsmParameter } from '@tech-matters/ssm-cache';
19+
import { getSsmParameter, SsmParameterNotFound } from '@tech-matters/ssm-cache';
2020
import {
2121
ContactJob,
2222
deleteContactJob,
@@ -82,17 +82,27 @@ const deleteTranscript = async (job: RetrieveContactTranscriptJob): Promise<bool
8282
}
8383

8484
await setContactJobCleanupActive(id);
85+
const client = await getClient({ accountSid });
8586
try {
86-
const client = await getClient({ accountSid });
87-
await client.chat.v2
88-
.services(job.resource.serviceSid)
89-
.channels.get(job.resource.channelSid)
90-
.remove();
87+
await client.conversations.v1.conversations.get(job.resource.channelSid).remove();
9188
} catch (err) {
9289
if (err.status === 404) {
93-
console.log(
94-
`Channel ${channelSid} not found, assuming it has already been deleted`,
90+
console.info(
91+
`Conversation ${channelSid} not found, checking legacy chat API just in case.`,
9592
);
93+
try {
94+
await client.chat.v2
95+
.services(job.resource.serviceSid)
96+
.channels.get(job.resource.channelSid)
97+
.remove();
98+
} catch (chatError) {
99+
if (err.status === 404) {
100+
console.info(
101+
`${channelSid} not found as a chat channel or conversation, assuming it has already been deleted`,
102+
);
103+
return true;
104+
}
105+
}
96106
} else {
97107
console.error(
98108
new ContactJobCleanupError(
@@ -118,9 +128,11 @@ const cleanupContactJob = async (job: ContactJob): Promise<void> => {
118128
if (!(await deleteTranscript(job))) return;
119129
}
120130

121-
const { accountSid, id } = job;
131+
const { accountSid, id, jobType, contactId } = job;
122132
await deleteContactJob(accountSid, id);
123-
console.log(`Successfully cleaned up contact job ${id}`);
133+
console.info(
134+
`Successfully cleaned up contact job ${id} (${jobType}) for contact ${contactId}`,
135+
);
124136
};
125137

126138
/**
@@ -137,10 +149,20 @@ const getCleanupRetentionDays = async (accountSid): Promise<number | undefined>
137149
`/${process.env.NODE_ENV}/hrm/${accountSid}/transcript_retention_days`,
138150
),
139151
) || MAX_CLEANUP_JOB_RETENTION_DAYS;
140-
} catch (err) {
141-
console.error(
142-
`Error trying to fetch /${process.env.NODE_ENV}/hrm/${accountSid}/transcript_retention_days ${err}, using default`,
152+
console.debug(
153+
`SSM parameter for transcript retention days set to ${ssmRetentionDays} for account ${accountSid}, so using that`,
143154
);
155+
} catch (err) {
156+
if ((err as any) instanceof SsmParameterNotFound) {
157+
console.debug(
158+
`SSM parameter for transcript retention days not set for account ${accountSid}, so using default ${MAX_CLEANUP_JOB_RETENTION_DAYS}`,
159+
);
160+
} else {
161+
console.error(
162+
`Error trying to fetch /${process.env.NODE_ENV}/hrm/${accountSid}/transcript_retention_days ${err}, using default`,
163+
err,
164+
);
165+
}
144166
ssmRetentionDays = MAX_CLEANUP_JOB_RETENTION_DAYS;
145167
}
146168

@@ -159,10 +181,10 @@ export const cleanupContactJobs = async (): Promise<void> => {
159181
try {
160182
const accountSids = await getPendingCleanupJobAccountSids();
161183

162-
console.log(`Cleaning up contact jobs for accounts:`, accountSids);
184+
console.info(`Cleaning up contact jobs for accounts:`, accountSids);
163185

164186
for (const accountSid of accountSids) {
165-
console.log(`Cleaning up contact jobs for account:`, accountSid);
187+
console.info(`Cleaning up contact jobs for account:`, accountSid);
166188
const cleanupRetentionDays = await getCleanupRetentionDays(accountSid);
167189
const pendingJobs = await getPendingCleanupJobs(accountSid, cleanupRetentionDays);
168190

@@ -171,7 +193,9 @@ export const cleanupContactJobs = async (): Promise<void> => {
171193
await cleanupContactJob(job);
172194
} catch (err) {
173195
console.error(
174-
new ContactJobCleanupError(`Error processing job ${job.id}: ${err}`),
196+
new ContactJobCleanupError(
197+
`Error processing job ${job.id} (contact: ${job.contactId}): ${err}`,
198+
),
175199
);
176200
}
177201
}

0 commit comments

Comments
 (0)