4285 timebox create google calendar full sync (#4442)

* calendar module

* wip

* creating a folder for common files between calendar and messages

* wip

* wip

* wip

* wip

* update calendar search filter

* wip

* working on full sync service

* reorganizing folders

* adding repositories

* fix typo

* working on full-sync service

* Add calendarQueue to MessageQueue enum and update dependencies

* start transaction

* wip

* add save and update functions for event

* wip

* save events

* improving step by step

* add calendar scope

* fix nest modules imports

* renaming

* create calendar channel

* create job for google calendar full-sync

* call GoogleCalendarFullSyncJob after connected account creation

* ask for scope conditionnally

* fixes

* create channels conditionnally

* fix

* fixes

* fix FK bug

* filter out canceled events

* create save and update functions for calendarEventAttendee repository

* saving messageParticipants is working

* save calendarEventAttendees is working

* add calendarEvent cleaner

* calendar event cleaner is working

* working on updating attendees

* wip

* reintroducing google-gmail endpoint to ensure smooth deploy

* modify callbackURL

* modify front url

* changes to be able to merge

* put back feature flag

* fixes after PR comments

* add feature flag check

* remove unused modules

* separate delete connected account associated job data in two jobs

* fix error

* rename calendar_v3 as calendarV3

* Update packages/twenty-server/src/workspace/calendar-and-messaging/utils/valueStringForBatchRawQuery.util.ts

Co-authored-by: Jérémy M <jeremy.magrin@gmail.com>

* improve readability

* renaming to remove plural

* renaming to remove plural

* don't throw if no connected account is found

* use calendar queue

* modify usage of HttpService in fetch-by-batch

* modify valuesStringForBatchRawQuery to improve api and return flattened values

* fix auth module feature flag import

* fix getFlattenedValuesAndValuesStringForBatchRawQuery

---------

Co-authored-by: Jérémy M <jeremy.magrin@gmail.com>
This commit is contained in:
bosiraphael
2024-03-14 11:23:31 +01:00
committed by GitHub
parent e0dac82e07
commit 3caf860848
76 changed files with 1856 additions and 280 deletions

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
import { CreateCompanyService } from 'src/workspace/auto-companies-and-contacts-creation/create-company/create-company.service';
import { CompanyModule } from 'src/workspace/messaging/repositories/company/company.module';
@Module({
imports: [WorkspaceDataSourceModule, CompanyModule],
providers: [CreateCompanyService],
exports: [CreateCompanyService],
})
export class CreateCompanyModule {}

View File

@ -0,0 +1,117 @@
import { Injectable } from '@nestjs/common';
import { EntityManager } from 'typeorm';
import { v4 } from 'uuid';
import axios, { AxiosInstance } from 'axios';
import { CompanyService } from 'src/workspace/messaging/repositories/company/company.service';
import { getCompanyNameFromDomainName } from 'src/workspace/messaging/utils/get-company-name-from-domain-name.util';
@Injectable()
export class CreateCompanyService {
private readonly httpService: AxiosInstance;
constructor(private readonly companyService: CompanyService) {
this.httpService = axios.create({
baseURL: 'https://companies.twenty.com',
});
}
async createCompanies(
domainNames: string[],
workspaceId: string,
transactionManager?: EntityManager,
): Promise<{
[domainName: string]: string;
}> {
if (domainNames.length === 0) {
return {};
}
const uniqueDomainNames = [...new Set(domainNames)];
const existingCompanies =
await this.companyService.getExistingCompaniesByDomainNames(
uniqueDomainNames,
workspaceId,
transactionManager,
);
const companiesObject = existingCompanies.reduce(
(
acc: {
[domainName: string]: string;
},
company: {
domainName: string;
id: string;
},
) => ({
...acc,
[company.domainName]: company.id,
}),
{},
);
const filteredDomainNames = uniqueDomainNames.filter(
(domainName) =>
!existingCompanies.some(
(company: { domainName: string }) =>
company.domainName === domainName,
),
);
for (const domainName of filteredDomainNames) {
companiesObject[domainName] = await this.createCompany(
domainName,
workspaceId,
transactionManager,
);
}
return companiesObject;
}
async createCompany(
domainName: string,
workspaceId: string,
transactionManager?: EntityManager,
): Promise<string> {
const companyId = v4();
const { name, city } = await this.getCompanyInfoFromDomainName(domainName);
this.companyService.createCompany(
workspaceId,
{
id: companyId,
domainName,
name,
city,
},
transactionManager,
);
return companyId;
}
async getCompanyInfoFromDomainName(domainName: string): Promise<{
name: string;
city: string;
}> {
try {
const response = await this.httpService.get(`/${domainName}`);
const data = response.data;
return {
name: data.name ?? getCompanyNameFromDomainName(domainName),
city: data.city,
};
} catch (e) {
return {
name: getCompanyNameFromDomainName(domainName),
city: '',
};
}
}
}