3216 request a new access token for the gmail api when it expires (#3224)
* refresh access token * refresh and save access token * update module * refreshing access token before fetching the emails * remove log
This commit is contained in:
@ -5,10 +5,15 @@ import { EnvironmentModule } from 'src/integrations/environment/environment.modu
|
||||
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
||||
import { FetchBatchMessagesService } from 'src/workspace/messaging/services/fetch-batch-messages.service';
|
||||
import { FetchWorkspaceMessagesService } from 'src/workspace/messaging/services/fetch-workspace-messages.service';
|
||||
import { RefreshAccessTokenService } from 'src/workspace/messaging/services/refresh-access-token.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeORMModule, DataSourceModule, EnvironmentModule],
|
||||
providers: [FetchWorkspaceMessagesService, FetchBatchMessagesService],
|
||||
providers: [
|
||||
FetchWorkspaceMessagesService,
|
||||
FetchBatchMessagesService,
|
||||
RefreshAccessTokenService,
|
||||
],
|
||||
exports: [FetchWorkspaceMessagesService],
|
||||
})
|
||||
export class FetchWorkspaceMessagesModule {}
|
||||
|
||||
@ -11,6 +11,7 @@ import { FetchBatchMessagesService } from 'src/workspace/messaging/services/fetc
|
||||
import { GmailMessage } from 'src/workspace/messaging/types/gmailMessage';
|
||||
import { MessageOrThreadQuery } from 'src/workspace/messaging/types/messageOrThreadQuery';
|
||||
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
||||
import { RefreshAccessTokenService } from 'src/workspace/messaging/services/refresh-access-token.service';
|
||||
|
||||
@Injectable()
|
||||
export class FetchWorkspaceMessagesService {
|
||||
@ -19,9 +20,14 @@ export class FetchWorkspaceMessagesService {
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly typeORMService: TypeORMService,
|
||||
private readonly fetchBatchMessagesService: FetchBatchMessagesService,
|
||||
private readonly refreshAccessTokenService: RefreshAccessTokenService,
|
||||
) {}
|
||||
|
||||
async fetchWorkspaceMessages(workspaceId: string): Promise<void> {
|
||||
await this.refreshAccessTokenService.refreshAndSaveAccessToken(
|
||||
workspaceId,
|
||||
'20202020-0687-4c41-b707-ed1bfca972a7',
|
||||
);
|
||||
await this.fetchWorkspaceMemberThreads(
|
||||
workspaceId,
|
||||
'20202020-0687-4c41-b707-ed1bfca972a7',
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
||||
|
||||
@Injectable()
|
||||
export class RefreshAccessTokenService {
|
||||
constructor(
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly typeORMService: TypeORMService,
|
||||
) {}
|
||||
|
||||
async refreshAndSaveAccessToken(
|
||||
workspaceId: string,
|
||||
workspaceMemberId: string,
|
||||
): Promise<void> {
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const workspaceDataSource = await this.typeORMService.connectToDataSource(
|
||||
dataSourceMetadata,
|
||||
);
|
||||
|
||||
if (!workspaceDataSource) {
|
||||
throw new Error('No workspace data source found');
|
||||
}
|
||||
|
||||
const connectedAccounts = await workspaceDataSource?.query(
|
||||
`SELECT * FROM ${dataSourceMetadata.schema}."connectedAccount" WHERE "provider" = 'gmail' AND "accountOwnerId" = $1`,
|
||||
[workspaceMemberId],
|
||||
);
|
||||
|
||||
if (!connectedAccounts || connectedAccounts.length === 0) {
|
||||
throw new Error('No connected account found');
|
||||
}
|
||||
|
||||
const refreshToken = connectedAccounts[0]?.refreshToken;
|
||||
|
||||
if (!refreshToken) {
|
||||
throw new Error('No refresh token found');
|
||||
}
|
||||
|
||||
const accessToken = await this.refreshAccessToken(refreshToken);
|
||||
|
||||
await workspaceDataSource?.query(
|
||||
`UPDATE ${dataSourceMetadata.schema}."connectedAccount" SET "accessToken" = $1 WHERE "id" = $2`,
|
||||
[accessToken, connectedAccounts[0].id],
|
||||
);
|
||||
}
|
||||
|
||||
async refreshAccessToken(refreshToken: string): Promise<string> {
|
||||
const response = await axios.post(
|
||||
'https://oauth2.googleapis.com/token',
|
||||
{
|
||||
client_id: this.environmentService.getAuthGoogleClientId(),
|
||||
client_secret: this.environmentService.getAuthGoogleClientSecret(),
|
||||
refresh_token: refreshToken,
|
||||
grant_type: 'refresh_token',
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return response.data.access_token;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user