diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts
index ac52eb6ab6d..23b2cdf4655 100644
--- a/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts
+++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/isMatchingSelectFilter.ts
@@ -21,6 +21,9 @@ export const isMatchingSelectFilter = ({
case selectFilter.eq !== undefined: {
return value === selectFilter.eq;
}
+ case selectFilter.neq !== undefined: {
+ return value !== selectFilter.neq;
+ }
default: {
throw new Error(
`Unexpected value for select filter : ${JSON.stringify(selectFilter)}`,
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx
index 0344c573fce..4cb0caa20c4 100644
--- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx
@@ -101,16 +101,33 @@ export const SettingsAccountsMessageChannelDetails = ({
return (
{isFolderControlEnabled && messageChannel.messageFolders && (
-
+ <>
+
+
+
+
+ handleIsGroupEmailExcludedToggle(
+ !messageChannel.excludeGroupEmails,
+ )
+ }
+ />
+
+
+ >
)}
{
handleIsNonProfessionalEmailExcludedToggle(
@@ -146,17 +162,6 @@ export const SettingsAccountsMessageChannelDetails = ({
);
}}
/>
-
- handleIsGroupEmailExcludedToggle(
- !messageChannel.excludeGroupEmails,
- )
- }
- />
diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module.ts
index 77bd3216ae6..ed18dd3a131 100644
--- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module.ts
+++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module.ts
@@ -10,6 +10,7 @@ import { CalendarQueryHookModule } from 'src/modules/calendar/common/query-hooks
import { ConnectedAccountQueryHookModule } from 'src/modules/connected-account/query-hooks/connected-account-query-hook.module';
import { DashboardQueryHookModule } from 'src/modules/dashboard/query-hooks/dashboard-query-hook.module';
import { MessagingQueryHookModule } from 'src/modules/messaging/common/query-hooks/messaging-query-hook.module';
+import { MessageChannelQueryHookModule } from 'src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module';
import { WorkspaceMemberQueryHookModule } from 'src/modules/workspace-member/query-hooks/workspace-member-query-hook.module';
@Module({
@@ -19,6 +20,7 @@ import { WorkspaceMemberQueryHookModule } from 'src/modules/workspace-member/que
ConnectedAccountQueryHookModule,
DashboardQueryHookModule,
BlocklistQueryHookModule,
+ MessageChannelQueryHookModule,
WorkspaceMemberQueryHookModule,
DiscoveryModule,
],
diff --git a/packages/twenty-server/src/engine/core-modules/auth/services/create-message-channel.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/create-message-channel.service.ts
index 6b58f077a88..bd1873ba9fb 100644
--- a/packages/twenty-server/src/engine/core-modules/auth/services/create-message-channel.service.ts
+++ b/packages/twenty-server/src/engine/core-modules/auth/services/create-message-channel.service.ts
@@ -1,9 +1,11 @@
import { Injectable } from '@nestjs/common';
+import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
+import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import {
MessageChannelSyncStage,
MessageChannelSyncStatus,
@@ -11,6 +13,7 @@ import {
MessageChannelVisibility,
type MessageChannelWorkspaceEntity,
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
+import { SyncMessageFoldersService } from 'src/modules/messaging/message-folder-manager/services/sync-message-folders.service';
export type CreateMessageChannelInput = {
workspaceId: string;
@@ -24,6 +27,7 @@ export type CreateMessageChannelInput = {
export class CreateMessageChannelService {
constructor(
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
+ private readonly syncMessageFoldersService: SyncMessageFoldersService,
) {}
async createMessageChannel(
@@ -37,6 +41,16 @@ export class CreateMessageChannelService {
manager,
} = input;
+ const connectedAccountRepository =
+ await this.twentyORMGlobalManager.getRepositoryForWorkspace(
+ workspaceId,
+ 'connectedAccount',
+ );
+
+ const connectedAccount = await connectedAccountRepository.findOne({
+ where: { id: connectedAccountId },
+ });
+
const messageChannelRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
@@ -58,6 +72,15 @@ export class CreateMessageChannelService {
manager,
);
+ if (isDefined(connectedAccount)) {
+ await this.syncMessageFoldersService.syncMessageFolders({
+ workspaceId,
+ messageChannelId: newMessageChannel.id,
+ connectedAccount,
+ manager,
+ });
+ }
+
return newMessageChannel.id;
}
}
diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
index e405b0ff0a3..9ba624f8c68 100644
--- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts
@@ -247,6 +247,8 @@ export const MESSAGE_CHANNEL_STANDARD_FIELD_IDS = {
messageChannelMessageAssociations: '20202020-49b8-4766-88fd-75f1e21b3d5f',
messageFolders: '20202020-cc39-4432-9fe8-ec8ab8bbed94',
messageFolderImportPolicy: '20202020-cc39-4432-9fe8-ec8ab8bbed95',
+ syncAllFolders: '20202020-e36b-409c-a9bd-79071596cdc0',
+ pendingGroupEmailsAction: '20202020-17c5-4e9f-bc50-af46a89fdd42',
isSyncEnabled: '20202020-d9a6-48e9-990b-b97fdf22e8dd',
syncCursor: '20202020-79d1-41cf-b738-bcf5ed61e256',
syncedAt: '20202020-263d-4c6b-ad51-137ada56f7d4',
@@ -263,6 +265,7 @@ export const MESSAGE_FOLDER_STANDARD_FIELD_IDS = {
isSentFolder: '20202020-2af5-4a25-b2de-3c9386da941b',
isSynced: '20202020-764f-4e09-8f95-cd46b6bfe3c4',
externalId: '20202020-f3a8-4d2b-9c7e-1b5f9a8e4c6d',
+ pendingSyncAction: '20202020-4f97-4c79-9517-16387fe237f7',
} as const;
export const MESSAGE_PARTICIPANT_STANDARD_FIELD_IDS = {
diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
index 7ecc7dd4266..17a9ba0517b 100644
--- a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
+++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-channel.workspace-entity.ts
@@ -65,6 +65,12 @@ export enum MessageFolderImportPolicy {
SELECTED_FOLDERS = 'SELECTED_FOLDERS',
}
+export enum MessageChannelPendingGroupEmailsAction {
+ GROUP_EMAILS_DELETION = 'GROUP_EMAILS_DELETION',
+ GROUP_EMAILS_IMPORT = 'GROUP_EMAILS_IMPORT',
+ NONE = 'NONE',
+}
+
registerEnumType(MessageChannelVisibility, {
name: 'MessageChannelVisibility',
});
@@ -89,6 +95,10 @@ registerEnumType(MessageFolderImportPolicy, {
name: 'MessageFolderImportPolicy',
});
+registerEnumType(MessageChannelPendingGroupEmailsAction, {
+ name: 'MessageChannelPendingGroupEmailsAction',
+});
+
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.messageChannel,
namePlural: 'messageChannels',
@@ -249,6 +259,46 @@ export class MessageChannelWorkspaceEntity extends BaseWorkspaceEntity {
})
excludeGroupEmails: boolean;
+ @WorkspaceField({
+ standardId: MESSAGE_CHANNEL_STANDARD_FIELD_IDS.syncAllFolders,
+ type: FieldMetadataType.BOOLEAN,
+ label: msg`Sync all folders`,
+ description: msg`Sync all folders including new ones`,
+ icon: 'IconFolders',
+ defaultValue: true,
+ })
+ syncAllFolders: boolean;
+
+ @WorkspaceField({
+ standardId: MESSAGE_CHANNEL_STANDARD_FIELD_IDS.pendingGroupEmailsAction,
+ type: FieldMetadataType.SELECT,
+ label: msg`Pending group emails action`,
+ description: msg`Pending action for group emails`,
+ icon: 'IconUsersGroup',
+ options: [
+ {
+ value: MessageChannelPendingGroupEmailsAction.GROUP_EMAILS_DELETION,
+ label: 'Group emails deletion',
+ position: 0,
+ color: 'red',
+ },
+ {
+ value: MessageChannelPendingGroupEmailsAction.GROUP_EMAILS_IMPORT,
+ label: 'Group emails import',
+ position: 1,
+ color: 'green',
+ },
+ {
+ value: MessageChannelPendingGroupEmailsAction.NONE,
+ label: 'None',
+ position: 2,
+ color: 'blue',
+ },
+ ],
+ defaultValue: `'${MessageChannelPendingGroupEmailsAction.NONE}'`,
+ })
+ pendingGroupEmailsAction: MessageChannelPendingGroupEmailsAction;
+
@WorkspaceField({
standardId: MESSAGE_CHANNEL_STANDARD_FIELD_IDS.isSyncEnabled,
type: FieldMetadataType.BOOLEAN,
diff --git a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts
index 0505319f6bc..e8ab95b10de 100644
--- a/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts
+++ b/packages/twenty-server/src/modules/messaging/common/standard-objects/message-folder.workspace-entity.ts
@@ -1,3 +1,5 @@
+import { registerEnumType } from '@nestjs/graphql';
+
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared/types';
import { Relation } from 'typeorm';
@@ -18,6 +20,16 @@ import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sy
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
+export enum MessageFolderPendingSyncAction {
+ FOLDER_DELETION = 'FOLDER_DELETION',
+ FOLDER_IMPORT = 'FOLDER_IMPORT',
+ NONE = 'NONE',
+}
+
+registerEnumType(MessageFolderPendingSyncAction, {
+ name: 'MessageFolderPendingSyncAction',
+});
+
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.messageFolder,
namePlural: 'messageFolders',
@@ -90,6 +102,36 @@ export class MessageFolderWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceIsNullable()
externalId: string | null;
+ @WorkspaceField({
+ standardId: MESSAGE_FOLDER_STANDARD_FIELD_IDS.pendingSyncAction,
+ type: FieldMetadataType.SELECT,
+ label: msg`Pending Sync Action`,
+ description: msg`Pending action for folder sync`,
+ icon: 'IconReload',
+ options: [
+ {
+ value: MessageFolderPendingSyncAction.FOLDER_DELETION,
+ label: 'Folder deletion',
+ position: 0,
+ color: 'red',
+ },
+ {
+ value: MessageFolderPendingSyncAction.FOLDER_IMPORT,
+ label: 'Folder import',
+ position: 1,
+ color: 'green',
+ },
+ {
+ value: MessageFolderPendingSyncAction.NONE,
+ label: 'None',
+ position: 2,
+ color: 'blue',
+ },
+ ],
+ defaultValue: `'${MessageFolderPendingSyncAction.NONE}'`,
+ })
+ pendingSyncAction: MessageFolderPendingSyncAction;
+
@WorkspaceJoinColumn('messageChannel')
messageChannelId: string;
}
diff --git a/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module.ts b/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module.ts
new file mode 100644
index 00000000000..00e2dfe18d5
--- /dev/null
+++ b/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module.ts
@@ -0,0 +1,9 @@
+import { Module } from '@nestjs/common';
+
+import { MessageChannelUpdateOnePreQueryHook } from 'src/modules/messaging/message-channel-manager/query-hooks/message-channel-update-one.pre-query.hook';
+
+@Module({
+ providers: [MessageChannelUpdateOnePreQueryHook],
+ exports: [MessageChannelUpdateOnePreQueryHook],
+})
+export class MessageChannelQueryHookModule {}
diff --git a/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-update-one.pre-query.hook.ts b/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-update-one.pre-query.hook.ts
new file mode 100644
index 00000000000..51a8c26fa42
--- /dev/null
+++ b/packages/twenty-server/src/modules/messaging/message-channel-manager/query-hooks/message-channel-update-one.pre-query.hook.ts
@@ -0,0 +1,106 @@
+import { msg } from '@lingui/core/macro';
+import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
+import { Not } from 'typeorm';
+
+import { type WorkspacePreQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
+import { type UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
+
+import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
+import {
+ WorkspaceQueryRunnerException,
+ WorkspaceQueryRunnerExceptionCode,
+} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
+import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
+import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
+import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
+import {
+ MessageChannelPendingGroupEmailsAction,
+ MessageChannelSyncStage,
+ type MessageChannelWorkspaceEntity,
+} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
+import {
+ MessageFolderPendingSyncAction,
+ type MessageFolderWorkspaceEntity,
+} from 'src/modules/messaging/common/standard-objects/message-folder.workspace-entity';
+
+const ONGOING_SYNC_STAGES = [
+ MessageChannelSyncStage.MESSAGE_LIST_FETCH_ONGOING,
+ MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
+];
+
+@WorkspaceQueryHook(`messageChannel.updateOne`)
+export class MessageChannelUpdateOnePreQueryHook
+ implements WorkspacePreQueryHookInstance
+{
+ constructor(
+ private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
+ ) {}
+
+ async execute(
+ authContext: AuthContext,
+ _objectName: string,
+ payload: UpdateOneResolverArgs,
+ ): Promise> {
+ const workspace = authContext.workspace;
+
+ assertIsDefinedOrThrow(workspace, WorkspaceNotFoundDefaultError);
+
+ const messageChannelRepository =
+ await this.twentyORMGlobalManager.getRepositoryForWorkspace(
+ workspace.id,
+ 'messageChannel',
+ );
+
+ const messageChannel = await messageChannelRepository.findOne({
+ where: { id: payload.id },
+ });
+
+ if (!messageChannel) {
+ throw new WorkspaceQueryRunnerException(
+ 'Message channel not found',
+ WorkspaceQueryRunnerExceptionCode.DATA_NOT_FOUND,
+ {
+ userFriendlyMessage: msg`Message channel not found`,
+ },
+ );
+ }
+
+ const isSyncOngoing = ONGOING_SYNC_STAGES.includes(
+ messageChannel.syncStage,
+ );
+
+ const messageFolderRepository =
+ await this.twentyORMGlobalManager.getRepositoryForWorkspace(
+ workspace.id,
+ 'messageFolder',
+ );
+
+ const folderWithPendingAction = await messageFolderRepository.findOne({
+ where: {
+ messageChannelId: messageChannel.id,
+ pendingSyncAction: Not(MessageFolderPendingSyncAction.NONE),
+ },
+ });
+
+ const hasPendingFolderActions = !!folderWithPendingAction;
+
+ const hasPendingGroupEmailsAction =
+ messageChannel.pendingGroupEmailsAction !==
+ MessageChannelPendingGroupEmailsAction.NONE;
+
+ if (
+ isSyncOngoing &&
+ (hasPendingFolderActions || hasPendingGroupEmailsAction)
+ ) {
+ throw new WorkspaceQueryRunnerException(
+ 'Cannot update message channel while sync is ongoing with pending actions',
+ WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
+ {
+ userFriendlyMessage: msg`Cannot update message channel while sync is ongoing. Please wait for the sync to complete.`,
+ },
+ );
+ }
+
+ return payload;
+ }
+}
diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service.ts
index bb50d8dc4a7..d4081e6fc79 100644
--- a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service.ts
+++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service.ts
@@ -81,13 +81,19 @@ export class ImapGetAllFoldersService implements MessageFolderDriver {
for (const mailbox of validMailboxes) {
const isInbox = await this.isInboxFolder(mailbox);
const uidValidity = await this.getUidValidity(client, mailbox);
+ const standardFolder = getStandardFolderByRegex(mailbox.path);
+ const isSynced = this.shouldSyncByDefault(
+ mailbox,
+ standardFolder,
+ isInbox,
+ );
folders.push({
externalId: uidValidity
? `${mailbox.path}:${uidValidity}`
: mailbox.path,
name: mailbox.path,
- isSynced: isInbox,
+ isSynced,
isSentFolder: false,
});
}
@@ -126,23 +132,35 @@ export class ImapGetAllFoldersService implements MessageFolderDriver {
return true;
}
+ return false;
+ }
+
+ private shouldSyncByDefault(
+ mailbox: ListResponse,
+ standardFolder: StandardFolder | null,
+ isInbox: boolean,
+ ): boolean {
if (
mailbox.specialUse === '\\Drafts' ||
mailbox.specialUse === '\\Trash' ||
mailbox.specialUse === '\\Junk'
) {
- return true;
- }
- const standardFolder = getStandardFolderByRegex(mailbox.path);
-
- if (!standardFolder) {
return false;
}
- return (
- standardFolder !== StandardFolder.SENT &&
- standardFolder !== StandardFolder.INBOX
- );
+ if (
+ standardFolder === StandardFolder.DRAFTS ||
+ standardFolder === StandardFolder.TRASH ||
+ standardFolder === StandardFolder.JUNK
+ ) {
+ return false;
+ }
+
+ if (isInbox) {
+ return true;
+ }
+
+ return false;
}
private async getUidValidity(
diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service.ts
index b13209a1b25..eb83e33068f 100644
--- a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service.ts
+++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service.ts
@@ -67,18 +67,13 @@ export class MicrosoftGetAllFoldersService implements MessageFolderDriver {
}
const standardFolder = getStandardFolderByRegex(folder.displayName);
-
- if (this.shouldExcludeFolder(standardFolder)) {
- continue;
- }
-
- const isInbox = this.isInboxFolder(standardFolder);
const isSentFolder = this.isSentFolder(standardFolder);
+ const isSynced = this.shouldSyncByDefault(standardFolder);
folderInfos.push({
externalId: folder.id,
name: folder.displayName,
- isSynced: isInbox || isSentFolder,
+ isSynced,
isSentFolder,
});
}
@@ -98,19 +93,19 @@ export class MicrosoftGetAllFoldersService implements MessageFolderDriver {
}
}
- private isInboxFolder(standardFolder: StandardFolder | null): boolean {
- return standardFolder === StandardFolder.INBOX;
- }
-
private isSentFolder(standardFolder: StandardFolder | null): boolean {
return standardFolder === StandardFolder.SENT;
}
- private shouldExcludeFolder(standardFolder: StandardFolder | null): boolean {
- return (
- standardFolder !== null &&
- standardFolder !== StandardFolder.SENT &&
- standardFolder !== StandardFolder.INBOX
- );
+ private shouldSyncByDefault(standardFolder: StandardFolder | null): boolean {
+ if (
+ standardFolder === StandardFolder.JUNK ||
+ standardFolder === StandardFolder.DRAFTS ||
+ standardFolder === StandardFolder.TRASH
+ ) {
+ return false;
+ }
+
+ return true;
}
}
diff --git a/packages/twenty-server/src/modules/messaging/messaging.module.ts b/packages/twenty-server/src/modules/messaging/messaging.module.ts
index 698f1ef999c..afc27cf2f25 100644
--- a/packages/twenty-server/src/modules/messaging/messaging.module.ts
+++ b/packages/twenty-server/src/modules/messaging/messaging.module.ts
@@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { MessagingBlocklistManagerModule } from 'src/modules/messaging/blocklist-manager/messaging-blocklist-manager.module';
+import { MessageChannelQueryHookModule } from 'src/modules/messaging/message-channel-manager/query-hooks/message-channel-query-hook.module';
import { MessagingMessageCleanerModule } from 'src/modules/messaging/message-cleaner/messaging-message-cleaner.module';
import { MessagingImportManagerModule } from 'src/modules/messaging/message-import-manager/messaging-import-manager.module';
import { MessageParticipantManagerModule } from 'src/modules/messaging/message-participant-manager/message-participant-manager.module';
@@ -13,6 +14,7 @@ import { MessagingMonitoringModule } from 'src/modules/messaging/monitoring/mess
MessageParticipantManagerModule,
MessagingBlocklistManagerModule,
MessagingMonitoringModule,
+ MessageChannelQueryHookModule,
],
providers: [],
exports: [MessagingImportManagerModule],
diff --git a/packages/twenty-shared/src/types/RecordGqlOperationFilter.ts b/packages/twenty-shared/src/types/RecordGqlOperationFilter.ts
index 78ce99b03af..e30d8e9cce6 100644
--- a/packages/twenty-shared/src/types/RecordGqlOperationFilter.ts
+++ b/packages/twenty-shared/src/types/RecordGqlOperationFilter.ts
@@ -114,6 +114,7 @@ export type SelectFilter = {
is?: IsFilter;
in?: string[];
eq?: string;
+ neq?: string;
};
export type MultiSelectFilter = {