From 11d1c4c161e6e4b9a70616a1c2f6fe3aff3efb74 Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:28:35 +0100 Subject: [PATCH] 3808 auto creation of company when importing emails (#3881) * create service * wip * use raw queries * creating companies is working * Fix participant handle domain name extraction * Add HTTP service to fetch company info from domain name * Handle 404 * Fix missing parameter in INSERT query * wip * renaming * Add typing --- .../workspace/messaging/messaging.module.ts | 2 + .../services/create-company.service.ts | 65 +++++++++++++++++++ .../services/messaging-utils.service.ts | 15 +++++ 3 files changed, 82 insertions(+) create mode 100644 packages/twenty-server/src/workspace/messaging/services/create-company.service.ts diff --git a/packages/twenty-server/src/workspace/messaging/messaging.module.ts b/packages/twenty-server/src/workspace/messaging/messaging.module.ts index f4079f866..72613cd9f 100644 --- a/packages/twenty-server/src/workspace/messaging/messaging.module.ts +++ b/packages/twenty-server/src/workspace/messaging/messaging.module.ts @@ -9,6 +9,7 @@ import { EnvironmentModule } from 'src/integrations/environment/environment.modu import { MessagingPersonListener } from 'src/workspace/messaging/listeners/messaging-person.listener'; import { MessageModule } from 'src/workspace/messaging/message/message.module'; import { GmailClientProvider } from 'src/workspace/messaging/providers/gmail/gmail-client.provider'; +import { CreateCompanyService } from 'src/workspace/messaging/services/create-company.service'; import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service'; import { GmailFullSyncService } from 'src/workspace/messaging/services/gmail-full-sync.service'; import { GmailPartialSyncService } from 'src/workspace/messaging/services/gmail-partial-sync.service'; @@ -35,6 +36,7 @@ import { MessagingWorkspaceMemberListener } from 'src/workspace/messaging/listen GmailRefreshAccessTokenService, MessagingUtilsService, GmailClientProvider, + CreateCompanyService, MessagingPersonListener, MessagingWorkspaceMemberListener, ], diff --git a/packages/twenty-server/src/workspace/messaging/services/create-company.service.ts b/packages/twenty-server/src/workspace/messaging/services/create-company.service.ts new file mode 100644 index 000000000..5ca92c13c --- /dev/null +++ b/packages/twenty-server/src/workspace/messaging/services/create-company.service.ts @@ -0,0 +1,65 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; +import axios, { AxiosInstance } from 'axios'; +import { v4 } from 'uuid'; + +import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity'; +import { capitalize } from 'src/utils/capitalize'; +@Injectable() +export class CreateCompanyService { + private readonly httpService: AxiosInstance; + + constructor() { + this.httpService = axios.create({ + baseURL: 'https://companies.twenty.com', + }); + } + + async createCompanyFromDomainName( + domainName: string, + dataSourceMetadata: DataSourceEntity, + manager: EntityManager, + ): Promise { + const existingCompany = await manager.query( + `SELECT * FROM ${dataSourceMetadata.schema}.company WHERE "domainName" = '${domainName}'`, + ); + + if (existingCompany.length > 0) { + return existingCompany[0].id; + } + + const companyId = v4(); + + const { name, city } = await this.getCompanyInfoFromDomainName(domainName); + + await manager.query( + `INSERT INTO ${dataSourceMetadata.schema}.company (id, name, "domainName", address) + VALUES ($1, $2, $3, $4)`, + [companyId, name, domainName, city], + ); + + 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, + city: data.city, + }; + } catch (e) { + return { + name: capitalize(domainName.split('.')[0]), + city: '', + }; + } + } +} diff --git a/packages/twenty-server/src/workspace/messaging/services/messaging-utils.service.ts b/packages/twenty-server/src/workspace/messaging/services/messaging-utils.service.ts index 328b81d80..51436215d 100644 --- a/packages/twenty-server/src/workspace/messaging/services/messaging-utils.service.ts +++ b/packages/twenty-server/src/workspace/messaging/services/messaging-utils.service.ts @@ -14,6 +14,7 @@ import { MessageService } from 'src/workspace/messaging/message/message.service' import { MessageThreadService } from 'src/workspace/messaging/message-thread/message-thread.service'; import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object-record'; import { ConnectedAccountObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/connected-account.object-metadata'; +import { CreateCompanyService } from 'src/workspace/messaging/services/create-company.service'; @Injectable() export class MessagingUtilsService { @@ -21,6 +22,7 @@ export class MessagingUtilsService { private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, private readonly messageService: MessageService, private readonly messageThreadService: MessageThreadService, + private readonly createCompaniesService: CreateCompanyService, ) {} public createQueriesFromMessageIds( @@ -201,6 +203,19 @@ export class MessagingUtilsService { participantWorkspaceMemberId, ], ); + + const companyDomainName = participant.handle + .split('@')?.[1] + .split('.') + .slice(-2) + .join('.') + .toLowerCase(); + + await this.createCompaniesService.createCompanyFromDomainName( + companyDomainName, + dataSourceMetadata, + manager, + ); } }