feat: IMAP Driver Integration (#12576)
### Added IMAP integration This PR adds support for connecting email accounts via IMAP protocol, allowing users to sync their emails without OAuth. #### DB Changes: - Added customConnectionParams and connectionType fields to ConnectedAccountWorkspaceEntity #### UI: - Added settings pages for creating and editing IMAP connections with proper validation and connection testing. - Implemented reconnection flows for handling permission issues. #### Backend: - Built ImapConnectionModule with corresponding resolver and service for managing IMAP connections. - Created MessagingIMAPDriverModule to handle IMAP client operations, message fetching/parsing, and error handling. #### Dependencies: Integrated `imapflow` and `mailparser` libraries with their type definitions to handle the IMAP protocol communication. --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
@ -12,8 +12,9 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconArrowBackUp } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: flex;
|
||||
@ -41,6 +42,12 @@ const StyledButtonContainer = styled.div<{ isMobile: boolean }>`
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
|
||||
const ALLOWED_REPLY_PROVIDERS = [
|
||||
ConnectedAccountProvider.GOOGLE,
|
||||
ConnectedAccountProvider.MICROSOFT,
|
||||
ConnectedAccountProvider.IMAP_SMTP_CALDAV,
|
||||
];
|
||||
|
||||
export const CommandMenuMessageThreadPage = () => {
|
||||
const setMessageThread = useSetRecoilComponentStateV2(
|
||||
messageThreadComponentState,
|
||||
@ -58,6 +65,7 @@ export const CommandMenuMessageThreadPage = () => {
|
||||
messageChannelLoading,
|
||||
connectedAccountProvider,
|
||||
lastMessageExternalId,
|
||||
connectedAccountConnectionParameters,
|
||||
} = useEmailThreadInCommandMenu();
|
||||
|
||||
useEffect(() => {
|
||||
@ -83,10 +91,14 @@ export const CommandMenuMessageThreadPage = () => {
|
||||
return (
|
||||
connectedAccountHandle &&
|
||||
connectedAccountProvider &&
|
||||
ALLOWED_REPLY_PROVIDERS.includes(connectedAccountProvider) &&
|
||||
(connectedAccountProvider !== ConnectedAccountProvider.IMAP_SMTP_CALDAV ||
|
||||
isDefined(connectedAccountConnectionParameters?.SMTP)) &&
|
||||
lastMessage &&
|
||||
messageThreadExternalId != null
|
||||
);
|
||||
}, [
|
||||
connectedAccountConnectionParameters,
|
||||
connectedAccountHandle,
|
||||
connectedAccountProvider,
|
||||
lastMessage,
|
||||
@ -108,6 +120,8 @@ export const CommandMenuMessageThreadPage = () => {
|
||||
url = `https://mail.google.com/mail/?authuser=${connectedAccountHandle}#all/${messageThreadExternalId}`;
|
||||
window.open(url, '_blank');
|
||||
break;
|
||||
case ConnectedAccountProvider.IMAP_SMTP_CALDAV:
|
||||
throw new Error('Account provider not supported');
|
||||
case null:
|
||||
throw new Error('Account provider not provided');
|
||||
default:
|
||||
|
||||
@ -139,6 +139,7 @@ export const useEmailThreadInCommandMenu = () => {
|
||||
connectedAccount: {
|
||||
id: true,
|
||||
provider: true,
|
||||
connectionParameters: true,
|
||||
},
|
||||
},
|
||||
skip: !lastMessageChannelId,
|
||||
@ -175,12 +176,16 @@ export const useEmailThreadInCommandMenu = () => {
|
||||
? messageChannelData[0]?.connectedAccount
|
||||
: null;
|
||||
const connectedAccountProvider = connectedAccount?.provider ?? null;
|
||||
const connectedAccountConnectionParameters =
|
||||
connectedAccount?.connectionParameters;
|
||||
|
||||
return {
|
||||
thread,
|
||||
messages: messagesWithSender,
|
||||
messageThreadExternalId,
|
||||
connectedAccountHandle,
|
||||
connectedAccountProvider,
|
||||
connectedAccountConnectionParameters,
|
||||
threadLoading: messagesLoading,
|
||||
messageChannelLoading,
|
||||
lastMessageExternalId,
|
||||
|
||||
Reference in New Issue
Block a user