diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/services/google-calendar-get-events.service.ts b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/services/google-calendar-get-events.service.ts index 0e891d52a98..03b0288e4a4 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/services/google-calendar-get-events.service.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/services/google-calendar-get-events.service.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { type GaxiosError } from 'gaxios'; -import { type calendar_v3 as calendarV3 } from 'googleapis'; +import { google, type calendar_v3 as calendarV3 } from 'googleapis'; import { formatGoogleCalendarEvents } from 'src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/utils/format-google-calendar-event.util'; import { parseGaxiosError } from 'src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/utils/parse-gaxios-error.util'; @@ -31,7 +31,10 @@ export class GoogleCalendarGetEventsService { connectedAccount, ); - const googleCalendarClient = oAuth2Client.calendar({ version: 'v3' }); + const googleCalendarClient = google.calendar({ + version: 'v3', + auth: oAuth2Client, + }); let nextSyncToken: string | null | undefined; let nextPageToken: string | undefined; diff --git a/packages/twenty-server/src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service.ts b/packages/twenty-server/src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service.ts index 71e40c2dd4d..aaa62dd9be5 100644 --- a/packages/twenty-server/src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service.ts +++ b/packages/twenty-server/src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { google } from 'googleapis'; + import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service'; import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; @@ -17,11 +19,12 @@ export class GoogleEmailAliasManagerService { connectedAccount, ); - const people = oAuth2Client.people({ + const peopleClient = google.people({ version: 'v1', + auth: oAuth2Client, }); - const emailsResponse = await people.people.get({ + const emailsResponse = await peopleClient.people.get({ resourceName: 'people/me', personFields: 'emailAddresses', }); diff --git a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service.ts b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service.ts index 1a5a177c71d..2f051a688be 100644 --- a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service.ts +++ b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service.ts @@ -1,6 +1,6 @@ import { Injectable, Logger } from '@nestjs/common'; -import { google, GoogleApis } from 'googleapis'; +import { google, type Auth } from 'googleapis'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; @@ -11,7 +11,9 @@ export class GoogleOAuth2ClientManagerService { private readonly logger: Logger, ) {} - public async getOAuth2Client(refreshToken: string): Promise { + public async getOAuth2Client( + refreshToken: string, + ): Promise { const gmailClientId = this.twentyConfigService.get('AUTH_GOOGLE_CLIENT_ID'); const gmailClientSecret = this.twentyConfigService.get( 'AUTH_GOOGLE_CLIENT_SECRET', @@ -27,9 +29,7 @@ export class GoogleOAuth2ClientManagerService { refresh_token: refreshToken, }); - google.options({ auth: oAuth2Client }); - - return google; + return oAuth2Client; } catch (error) { this.logger.error( `Error in ${GoogleOAuth2ClientManagerService.name}`, diff --git a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts index be722854799..abd13440743 100644 --- a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts +++ b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { type Client } from '@microsoft/microsoft-graph-client'; -import { GoogleApis } from 'googleapis'; +import { type Auth } from 'googleapis'; import { GoogleOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service'; import { MicrosoftOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service'; @@ -19,7 +19,7 @@ export class OAuth2ClientManagerService { ConnectedAccountWorkspaceEntity, 'provider' | 'refreshToken' >, - ): Promise { + ): Promise { return this.googleOAuth2ClientManagerService.getOAuth2Client( connectedAccount.refreshToken, ); diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service.ts index 5d03d1245e0..60b8af7b9ed 100644 --- a/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service.ts @@ -1,5 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; +import { google } from 'googleapis'; + import { MessageFolder, MessageFolderDriver, @@ -39,7 +41,10 @@ export class GmailGetAllFoldersService implements MessageFolderDriver { connectedAccount, ); - const gmailClient = oAuth2Client.gmail({ version: 'v1' }); + const gmailClient = google.gmail({ + version: 'v1', + auth: oAuth2Client, + }); const response = await gmailClient.users.labels .list({ userId: 'me' }) diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.spec.ts index ce76e25cf5c..e71aefb734d 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.spec.ts @@ -1,5 +1,6 @@ import { Test, type TestingModule } from '@nestjs/testing'; +import { google } from 'googleapis'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service'; @@ -63,6 +64,10 @@ describe('GmailGetMessageListService', () => { ); }); + afterEach(() => { + jest.restoreAllMocks(); + }); + describe('getMessageList', () => { it('should return 0 messageExternalIds when gmail returns 0 messages', async () => { const mockGmailClient = { @@ -78,13 +83,11 @@ describe('GmailGetMessageListService', () => { }, }; - const mockOAuth2Client = { - gmail: jest.fn().mockReturnValue(mockGmailClient), - }; + jest.spyOn(google, 'gmail').mockReturnValue(mockGmailClient as never); ( oAuth2ClientManagerService.getGoogleOAuth2Client as jest.Mock - ).mockResolvedValue(mockOAuth2Client); + ).mockResolvedValue({}); const result = await service.getMessageLists({ messageChannel: { syncCursor: '', id: 'my-id' }, @@ -133,13 +136,11 @@ describe('GmailGetMessageListService', () => { }, }; - const mockOAuth2Client = { - gmail: jest.fn().mockReturnValue(mockGmailClient), - }; + jest.spyOn(google, 'gmail').mockReturnValue(mockGmailClient as never); ( oAuth2ClientManagerService.getGoogleOAuth2Client as jest.Mock - ).mockResolvedValue(mockOAuth2Client); + ).mockResolvedValue({}); const result = await service.getMessageLists({ messageChannel: { syncCursor: '', id: 'my-id' }, @@ -188,13 +189,11 @@ describe('GmailGetMessageListService', () => { }, }; - const mockOAuth2Client = { - gmail: jest.fn().mockReturnValue(mockGmailClient), - }; + jest.spyOn(google, 'gmail').mockReturnValue(mockGmailClient as never); ( oAuth2ClientManagerService.getGoogleOAuth2Client as jest.Mock - ).mockResolvedValue(mockOAuth2Client); + ).mockResolvedValue({}); const result = await service.getMessageLists({ messageChannel: { syncCursor: '', id: 'my-id' }, @@ -224,13 +223,11 @@ describe('GmailGetMessageListService', () => { }, }; - const mockOAuth2Client = { - gmail: jest.fn().mockReturnValue(mockGmailClient), - }; + jest.spyOn(google, 'gmail').mockReturnValue(mockGmailClient as never); ( oAuth2ClientManagerService.getGoogleOAuth2Client as jest.Mock - ).mockResolvedValue(mockOAuth2Client); + ).mockResolvedValue({}); const result = await service.getMessageLists({ messageChannel: { syncCursor: '', id: 'my-id' }, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.ts index 6443b441a25..badbc3bdab5 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-message-list.service.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { isNonEmptyString } from '@sniptt/guards'; -import { type gmail_v1 as gmailV1 } from 'googleapis'; +import { google, type gmail_v1 as gmailV1 } from 'googleapis'; import { isDefined } from 'twenty-shared/utils'; import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service'; @@ -42,7 +42,10 @@ export class GmailGetMessageListService { await this.oAuth2ClientManagerService.getGoogleOAuth2Client( connectedAccount, ); - const gmailClient = oAuth2Client.gmail({ version: 'v1' }); + const gmailClient = google.gmail({ + version: 'v1', + auth: oAuth2Client, + }); let pageToken: string | undefined; let hasMoreMessages = true; @@ -143,7 +146,10 @@ export class GmailGetMessageListService { await this.oAuth2ClientManagerService.getGoogleOAuth2Client( connectedAccount, ); - const gmailClient = oAuth2Client.gmail({ version: 'v1' }); + const gmailClient = google.gmail({ + version: 'v1', + auth: oAuth2Client, + }); if (!isNonEmptyString(messageChannel.syncCursor)) { return this.getMessageListWithoutCursor(connectedAccount, messageFolders); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts index 9b78d616dc1..2628c9c2c45 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts @@ -1,5 +1,6 @@ import { Test, type TestingModule } from '@nestjs/testing'; +import { google } from 'googleapis'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service'; @@ -27,7 +28,7 @@ describe('MessagingSendMessageService - Gmail HTML Support', () => { }, getProfile: jest .fn() - .mockResolvedValue({ data: { emailAdress: 'test@example.com' } }), + .mockResolvedValue({ data: { emailAddress: 'test@example.com' } }), }, }; @@ -45,12 +46,12 @@ describe('MessagingSendMessageService - Gmail HTML Support', () => { }, }; - const mockOAuth2Client = { - gmail: jest.fn().mockReturnValue(mockGmailClient), - people: jest.fn().mockReturnValue(mockPeopleClient), - }; + const mockOAuth2Client = {}; beforeEach(async () => { + jest.spyOn(google, 'gmail').mockReturnValue(mockGmailClient as never); + jest.spyOn(google, 'people').mockReturnValue(mockPeopleClient as never); + const module: TestingModule = await Test.createTestingModule({ providers: [ MessagingSendMessageService, @@ -79,7 +80,8 @@ describe('MessagingSendMessageService - Gmail HTML Support', () => { }); afterEach(() => { - jest.clearAllMocks(); + mockSend.mockClear(); + jest.restoreAllMocks(); }); it('should send multipart/alternative email with both text and HTML parts via Gmail', async () => { diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts index 5b9e2a79708..ae3df05e974 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; +import { google } from 'googleapis'; import MailComposer from 'nodemailer/lib/mail-composer'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { assertUnreachable, isDefined } from 'twenty-shared/utils'; @@ -47,12 +48,14 @@ export class MessagingSendMessageService { connectedAccount, ); - const gmailClient = oAuth2Client.gmail({ + const gmailClient = google.gmail({ version: 'v1', + auth: oAuth2Client, }); - const peopleClient = oAuth2Client.people({ + const peopleClient = google.people({ version: 'v1', + auth: oAuth2Client, }); const { data: gmailData } = await gmailClient.users.getProfile({