[messaging] add fallback if lastHistoryId has been invalidated (#3782)

This commit is contained in:
Weiko
2024-02-02 15:28:38 +01:00
committed by GitHub
parent 8816b7fb31
commit ae5f82df59

View File

@ -28,31 +28,6 @@ export class GmailPartialSyncService {
private readonly messageChannelService: MessageChannelService, private readonly messageChannelService: MessageChannelService,
) {} ) {}
private async getHistoryFromGmail(
workspaceId: string,
connectedAccountId: string,
lastSyncHistoryId: string,
maxResults: number,
) {
const connectedAccount = await this.connectedAccountService.getByIdOrFail(
connectedAccountId,
workspaceId,
);
const gmailClient = await this.gmailClientProvider.getGmailClient(
connectedAccount.refreshToken,
);
const history = await gmailClient.users.history.list({
userId: 'me',
startHistoryId: lastSyncHistoryId,
historyTypes: ['messageAdded', 'messageDeleted'],
maxResults,
});
return history.data;
}
public async fetchConnectedAccountThreads( public async fetchConnectedAccountThreads(
workspaceId: string, workspaceId: string,
connectedAccountId: string, connectedAccountId: string,
@ -71,15 +46,7 @@ export class GmailPartialSyncService {
const lastSyncHistoryId = connectedAccount.lastSyncHistoryId; const lastSyncHistoryId = connectedAccount.lastSyncHistoryId;
if (!lastSyncHistoryId) { if (!lastSyncHistoryId) {
// Fall back to full sync await this.fallbackToFullSync(workspaceId, connectedAccountId);
await this.messageQueueService.add<GmailFullSyncJobData>(
GmailFullSyncJob.name,
{ workspaceId, connectedAccountId },
{
id: `${workspaceId}-${connectedAccount.id}`,
retryLimit: 2,
},
);
return; return;
} }
@ -91,30 +58,25 @@ export class GmailPartialSyncService {
throw new Error('No refresh token found'); throw new Error('No refresh token found');
} }
const history = await this.getHistoryFromGmail( const { history, error } = await this.getHistoryFromGmail(
workspaceId, refreshToken,
connectedAccountId,
lastSyncHistoryId, lastSyncHistoryId,
maxResults, maxResults,
); );
const historyId = history.historyId; if (error && error.code === 404) {
await this.fallbackToFullSync(workspaceId, connectedAccountId);
if (!historyId) {
throw new Error('No history id found');
}
if (historyId === lastSyncHistoryId) {
return; return;
} }
if (!history.history) { const newHistoryId = history?.historyId;
await this.connectedAccountService.saveLastSyncHistoryId(
historyId,
connectedAccountId,
workspaceId,
);
if (!newHistoryId) {
throw new Error('No history id found');
}
if (newHistoryId === lastSyncHistoryId) {
return; return;
} }
@ -156,7 +118,7 @@ export class GmailPartialSyncService {
if (errors.length) throw new Error('Error fetching messages'); if (errors.length) throw new Error('Error fetching messages');
await this.connectedAccountService.saveLastSyncHistoryId( await this.connectedAccountService.saveLastSyncHistoryId(
historyId, newHistoryId,
connectedAccount.id, connectedAccount.id,
workspaceId, workspaceId,
); );
@ -207,4 +169,49 @@ export class GmailPartialSyncService {
messagesDeleted: uniqueMessagesDeleted, messagesDeleted: uniqueMessagesDeleted,
}; };
} }
private async getHistoryFromGmail(
refreshToken: string,
lastSyncHistoryId: string,
maxResults: number,
): Promise<{
history?: gmail_v1.Schema$ListHistoryResponse;
error?: any;
}> {
const gmailClient =
await this.gmailClientProvider.getGmailClient(refreshToken);
try {
const history = await gmailClient.users.history.list({
userId: 'me',
startHistoryId: lastSyncHistoryId,
historyTypes: ['messageAdded', 'messageDeleted'],
maxResults,
});
return { history: history.data };
} catch (error) {
const errorData = error?.response?.data?.error;
if (errorData) {
return { error: errorData };
}
throw error;
}
}
private async fallbackToFullSync(
workspaceId: string,
connectedAccountId: string,
) {
await this.messageQueueService.add<GmailFullSyncJobData>(
GmailFullSyncJob.name,
{ workspaceId, connectedAccountId },
{
id: `${workspaceId}-${connectedAccountId}`,
retryLimit: 2,
},
);
}
} }