6657 Refactor and fix blocklist (#6803)

Closes #6657
- Fix listeners
- Refactor jobs to take array of events
- Fix calendar events and messages deletion

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Raphaël Bosi
2024-08-31 16:38:47 +02:00
committed by GitHub
parent d9650fd5cf
commit cd66ea74a2
37 changed files with 799 additions and 699 deletions

View File

@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Any } from 'typeorm';
import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service';
import { InjectCacheStorage } from 'src/engine/integrations/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum';
@ -12,10 +14,6 @@ import {
MessageChannelSyncStatus,
MessageChannelWorkspaceEntity,
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
import {
MessageImportException,
MessageImportExceptionCode,
} from 'src/modules/messaging/message-import-manager/exceptions/message-import.exception';
@Injectable()
export class MessageChannelSyncStatusService {
@ -26,216 +24,235 @@ export class MessageChannelSyncStatusService {
private readonly accountsToReconnectService: AccountsToReconnectService,
) {}
public async scheduleFullMessageListFetch(messageChannelId: string) {
public async scheduleFullMessageListFetch(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.FULL_MESSAGE_LIST_FETCH_PENDING,
});
}
public async schedulePartialMessageListFetch(messageChannelId: string) {
public async schedulePartialMessageListFetch(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING,
});
}
public async scheduleMessagesImport(messageChannelId: string) {
public async scheduleMessagesImport(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_PENDING,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_PENDING,
});
}
public async resetAndScheduleFullMessageListFetch(
messageChannelId: string,
messageChannelIds: string[],
workspaceId: string,
) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
if (!messageChannelIds.length) {
return;
}
for (const messageChannelId of messageChannelIds) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncCursor: '',
syncStageStartedAt: null,
throttleFailureCount: 0,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncCursor: '',
syncStageStartedAt: null,
throttleFailureCount: 0,
});
await this.scheduleFullMessageListFetch(messageChannelId);
await this.scheduleFullMessageListFetch(messageChannelIds);
}
public async resetSyncStageStartedAt(messageChannelId: string) {
public async resetSyncStageStartedAt(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStageStartedAt: null,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStageStartedAt: null,
});
}
public async markAsMessagesListFetchOngoing(messageChannelId: string) {
public async markAsMessagesListFetchOngoing(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_ONGOING,
syncStatus: MessageChannelSyncStatus.ONGOING,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_ONGOING,
syncStatus: MessageChannelSyncStatus.ONGOING,
});
}
public async markAsCompletedAndSchedulePartialMessageListFetch(
messageChannelId: string,
messageChannelIds: string[],
) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStatus: MessageChannelSyncStatus.ACTIVE,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStatus: MessageChannelSyncStatus.ACTIVE,
});
await this.schedulePartialMessageListFetch(messageChannelId);
await this.schedulePartialMessageListFetch(messageChannelIds);
}
public async markAsMessagesImportOngoing(messageChannelId: string) {
public async markAsMessagesImportOngoing(messageChannelIds: string[]) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
});
}
public async markAsFailedUnknownAndFlushMessagesToImport(
messageChannelId: string,
messageChannelIds: string[],
workspaceId: string,
) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
if (!messageChannelIds.length) {
return;
}
for (const messageChannelId of messageChannelIds) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.FAILED,
syncStatus: MessageChannelSyncStatus.FAILED_UNKNOWN,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.FAILED,
syncStatus: MessageChannelSyncStatus.FAILED_UNKNOWN,
});
}
public async markAsFailedInsufficientPermissionsAndFlushMessagesToImport(
messageChannelId: string,
messageChannelIds: string[],
workspaceId: string,
) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
if (!messageChannelIds.length) {
return;
}
for (const messageChannelId of messageChannelIds) {
await this.cacheStorage.del(
`messages-to-import:${workspaceId}:gmail:${messageChannelId}`,
);
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
await messageChannelRepository.update(
{ id: messageChannelId },
{
syncStage: MessageChannelSyncStage.FAILED,
syncStatus: MessageChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
},
);
await messageChannelRepository.update(messageChannelIds, {
syncStage: MessageChannelSyncStage.FAILED,
syncStatus: MessageChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
});
const connectedAccountRepository =
await this.twentyORMManager.getRepository<ConnectedAccountWorkspaceEntity>(
'connectedAccount',
);
const messageChannel = await messageChannelRepository.findOne({
where: { id: messageChannelId },
const messageChannels = await messageChannelRepository.find({
select: ['id', 'connectedAccountId'],
where: { id: Any(messageChannelIds) },
});
if (!messageChannel) {
throw new MessageImportException(
`Message channel ${messageChannelId} not found in workspace ${workspaceId}`,
MessageImportExceptionCode.MESSAGE_CHANNEL_NOT_FOUND,
);
}
const connectedAccountId = messageChannel.connectedAccountId;
const connectedAccountIds = messageChannels.map(
(messageChannel) => messageChannel.connectedAccountId,
);
await connectedAccountRepository.update(
{ id: connectedAccountId },
{ id: Any(connectedAccountIds) },
{
authFailedAt: new Date(),
},
);
await this.addToAccountsToReconnect(messageChannelId, workspaceId);
await this.addToAccountsToReconnect(
messageChannels.map((messageChannel) => messageChannel.id),
workspaceId,
);
}
private async addToAccountsToReconnect(
messageChannelId: string,
messageChannelIds: string[],
workspaceId: string,
) {
if (!messageChannelIds.length) {
return;
}
const messageChannelRepository =
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
'messageChannel',
);
const messageChannel = await messageChannelRepository.findOne({
where: { id: messageChannelId },
const messageChannels = await messageChannelRepository.find({
where: { id: Any(messageChannelIds) },
relations: {
connectedAccount: {
accountOwner: true,
@ -243,18 +260,16 @@ export class MessageChannelSyncStatusService {
},
});
if (!messageChannel) {
return;
for (const messageChannel of messageChannels) {
const userId = messageChannel.connectedAccount.accountOwner.userId;
const connectedAccountId = messageChannel.connectedAccount.id;
await this.accountsToReconnectService.addAccountToReconnectByKey(
AccountsToReconnectKeys.ACCOUNTS_TO_RECONNECT_INSUFFICIENT_PERMISSIONS,
userId,
workspaceId,
connectedAccountId,
);
}
const userId = messageChannel.connectedAccount.accountOwner.userId;
const connectedAccountId = messageChannel.connectedAccount.id;
await this.accountsToReconnectService.addAccountToReconnectByKey(
AccountsToReconnectKeys.ACCOUNTS_TO_RECONNECT_INSUFFICIENT_PERMISSIONS,
userId,
workspaceId,
connectedAccountId,
);
}
}