Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:Add integration with Close CRM #484

Merged
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ FRESHSALES_CRM_CLOUD_CLIENT_SECRET=
# Attio
ATTIO_CRM_CLOUD_CLIENT_ID=
ATTIO_CRM_CLOUD_CLIENT_SECRET=
#close
CLOSE_CRM_CLOUD_CLIENT_ID=
CLOSE_CRM_CLOUD_CLIENT_SECRET=
# ================================================
# Ticketing
# ================================================
Expand Down
32 changes: 16 additions & 16 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,22 @@ services:
volumes:
- .:/app

ngrok:
image: ngrok/ngrok:latest
restart: always
command:
- "start"
- "--all"
- "--config"
- "/etc/ngrok.yml"
volumes:
- ./ngrok.yml:/etc/ngrok.yml
ports:
- 4040:4040
depends_on:
api:
condition: service_healthy
network_mode: "host"
#ngrok:
#image: ngrok/ngrok:latest
#restart: always
#command:
# - "start"
# - "--all"
# - "--config"
# - "/etc/ngrok.yml"
#volumes:
# - ./ngrok.yml:/etc/ngrok.yml
#ports:
# - 4040:4040
#epends_on:
# api:
# condition: service_healthy
#network_mode: "host"

docs:
build:
Expand Down
66 changes: 66 additions & 0 deletions packages/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,12 @@ model projects {
id_connector_set String @db.Uuid
api_keys api_keys[]
connections connections[]
fs_folders fs_folders[]
linked_users linked_users[]
users users @relation(fields: [id_user], references: [id_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_46_1")
connector_sets connector_sets @relation(fields: [id_connector_set], references: [id_connector_set], onDelete: NoAction, onUpdate: NoAction, map: "fk_project_connectorsetid")

@@index([id_connector_set], map: "fk_connectors_sets")
}

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
Expand Down Expand Up @@ -647,6 +650,8 @@ model connector_sets {
crm_hubspot Boolean
crm_zoho Boolean
crm_attio Boolean
crm_close Boolean
crm_zendesk Boolean
crm_pipedrive Boolean
tcg_zendesk Boolean
tcg_jira Boolean
Expand All @@ -668,3 +673,64 @@ model managed_webhooks {
modified_at DateTime @db.Timestamp(6)
created_at DateTime @db.Timestamp(6)
}

model fs_drives {
id_fs_drive String @id(map: "pk_fs_drives") @db.Uuid
remote_created_at DateTime? @db.Timestamp(6)
drive_url String?
created_at DateTime @db.Timestamp(6)
modified_at DateTime @db.Timestamp(6)
remote_id String?
}

model fs_files {
id_fs_file String @id(map: "pk_fs_files") @db.Uuid
name String?
type String?
path String?
mime_type String?
size BigInt?
remote_id String?
id_fs_folder String? @db.Uuid
created_at DateTime @db.Timestamp(6)
modified_at DateTime @db.Timestamp(6)
id_fs_permission String @db.Uuid

@@index([id_fs_folder], map: "fk_fs_file_folderid")
@@index([id_fs_permission], map: "fk_fs_file_permissionid")
}

model fs_folders {
id_project_connector String @id(map: "pk_project_connectors") @db.Uuid
id_project String @db.Uuid
crm_hubspot Boolean
crm_zoho Boolean
crm_zendesk Boolean
crm_pipedrive Boolean
crm_attio Boolean
crm_close Boolean
tcg_zendesk Boolean
tcg_gorgias Boolean
tcg_front Boolean
tcg_jira Boolean
tcg_gitlab Boolean
projects projects @relation(fields: [id_project], references: [id_project], onDelete: NoAction, onUpdate: NoAction, map: "fk_project_connectors")
}

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model fs_permissions {
id_fs_permission String @id(map: "pk_fs_permissions") @db.Uuid
remote_id String?
created_at DateTime @db.Timestamp(6)
modified_at DateTime @db.Timestamp(6)
user String @db.Uuid
group String @db.Uuid
type String[]
roles String[]
}

model fs_shared_links {
id_fs_shared_link String @id(map: "pk_fs_shared_links") @db.Uuid
created_at DateTime @db.Timestamp(6)
modified_at DateTime @db.Timestamp(6)
}
38 changes: 17 additions & 21 deletions packages/api/scripts/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ CREATE TABLE connector_sets
crm_hubspot boolean NOT NULL,
crm_zoho boolean NOT NULL,
crm_attio boolean NOT NULL,
crm_close boolean NOT NULL,
crm_zendesk boolean NOT NULL,
crm_pipedrive boolean NOT NULL,
tcg_zendesk boolean NOT NULL,
tcg_jira boolean NOT NULL,
Expand Down Expand Up @@ -542,27 +544,21 @@ ex 3600 for one hour';

CREATE TABLE fs_folders
(
id_fs_folder uuid NOT NULL,
folder_url text NULL,
"size" bigint NULL,
description text NULL,
parent_folder uuid NULL,
remote_id text NULL,
created_at timestamp NOT NULL,
modified_at timestamp NOT NULL,
id_fs_drive uuid NULL,
id_fs_permission uuid NOT NULL,
CONSTRAINT PK_fs_folders PRIMARY KEY ( id_fs_folder )
);

CREATE INDEX FK_fs_folder_driveID ON fs_folders
(
id_fs_drive
);

CREATE INDEX FK_fs_folder_permissionID ON fs_folders
(
id_fs_permission
id_project_connector uuid NOT NULL,
id_project uuid NOT NULL,
crm_hubspot boolean NOT NULL,
crm_zoho boolean NOT NULL,
crm_zendesk boolean NOT NULL,
crm_pipedrive boolean NOT NULL,
crm_attio boolean NOT NULL,
crm_close boolean NOT NULL,
tcg_zendesk boolean NOT NULL,
tcg_gorgias boolean NOT NULL,
tcg_front boolean NOT NULL,
tcg_jira boolean NOT NULL,
tcg_gitlab boolean NOT NULL,
CONSTRAINT PK_project_connectors PRIMARY KEY ( id_project_connector ),
CONSTRAINT FK_project_connectors FOREIGN KEY ( id_project ) REFERENCES projects ( id_project )
);


Expand Down
8 changes: 4 additions & 4 deletions packages/api/scripts/seed.sql
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
INSERT INTO users (id_user, identification_strategy, email, password_hash, first_name, last_name) VALUES
('0ce39030-2901-4c56-8db0-5e326182ec6b', 'b2c','local@panora.dev', '$2b$10$Y7Q8TWGyGuc5ecdIASbBsuXMo3q/Rs3/cnY.mLZP4tUgfGUOCUBlG', 'local', 'Panora');

INSERT INTO connector_sets (id_connector_set, crm_hubspot, crm_zoho, crm_pipedrive, crm_attio, tcg_zendesk, tcg_gorgias, tcg_front, tcg_jira, tcg_gitlab) VALUES
('1709da40-17f7-4d3a-93a0-96dc5da6ddd7', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE),
('852dfff8-ab63-4530-ae49-e4b2924407f8', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE),
('aed0f856-f802-4a79-8640-66d441581a99', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
INSERT INTO connector_sets (id_connector_set, crm_hubspot, crm_zoho, crm_pipedrive, crm_attio, crm_zendesk, crm_close, tcg_zendesk, tcg_gorgias, tcg_front, tcg_jira, tcg_gitlab) VALUES
('852dfff8-ab63-4530-ae49-e4b2924407f8', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE),
('aed0f856-f802-4a79-8640-66d441581a99', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE),
('1709da40-17f7-4d3a-93a0-96dc5da6ddd7', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);

INSERT INTO projects (id_project, name, sync_mode, id_user, id_connector_set) VALUES
('1e468c15-aa57-4448-aa2b-7fed640d1e3d', 'Project 1', 'pool', '0ce39030-2901-4c56-8db0-5e326182ec6b', '1709da40-17f7-4d3a-93a0-96dc5da6ddd7'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ZendeskConnectionService } from './services/zendesk/zendesk.service';
import { PipedriveConnectionService } from './services/pipedrive/pipedrive.service';
import { AttioConnectionService } from './services/attio/attio.service';
import { ConnectionsStrategiesService } from '@@core/connections-strategies/connections-strategies.service';
import { CloseConnectionService } from './services/close/close.service';

@Module({
imports: [WebhookModule],
Expand All @@ -31,6 +32,7 @@ import { ConnectionsStrategiesService } from '@@core/connections-strategies/conn
ZohoConnectionService,
ZendeskConnectionService,
PipedriveConnectionService,
CloseConnectionService,
],
exports: [CrmConnectionsService],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ export class CloseConnectionService implements ICrmConnectionService {
},
);
const data: CloseOAuthResponse = res.data;
this.logger.log(
'OAuth credentials : close ticketing ' + JSON.stringify(data),
);

this.logger.log('OAuth credentials : close CRM ' + JSON.stringify(data));
let db_res;
const connection_token = uuidv4();

Expand All @@ -100,7 +97,7 @@ export class CloseConnectionService implements ICrmConnectionService {
data: {
access_token: this.cryptoService.encrypt(data.access_token),
refresh_token: this.cryptoService.encrypt(data.refresh_token),
account_url: CONNECTORS_METADATA['crm']['close'].urls.apiUrl,
account_url: CONNECTORS_METADATA['crm']['close']?.urls?.apiUrl,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify the computed expression for better readability.

- account_url: CONNECTORS_METADATA['crm']['close']?.urls?.apiUrl
+ account_url: CONNECTORS_METADATA.crm.close?.urls?.apiUrl
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
account_url: CONNECTORS_METADATA['crm']['close']?.urls?.apiUrl,
account_url: CONNECTORS_METADATA.crm.close?.urls?.apiUrl,
Tools
Biome

[error] 103-103: The computed expression can be simplified without the use of a string literal. (lint/complexity/useLiteralKeys)

Unsafe fix: Use a literal key instead.


[error] 103-103: The computed expression can be simplified without the use of a string literal. (lint/complexity/useLiteralKeys)

Unsafe fix: Use a literal key instead.

expiration_timestamp: new Date(
new Date().getTime() + Number(data.expires_in) * 1000,
),
Expand All @@ -116,7 +113,7 @@ export class CloseConnectionService implements ICrmConnectionService {
provider_slug: 'close',
vertical: 'crm',
token_type: 'oauth',
account_url: CONNECTORS_METADATA['crm']['close'].urls.apiUrl,
account_url: CONNECTORS_METADATA['crm']?.close?.urls?.apiUrl,
access_token: this.cryptoService.encrypt(data.access_token),
refresh_token: this.cryptoService.encrypt(data.refresh_token),
expiration_timestamp: new Date(
Expand Down Expand Up @@ -153,10 +150,10 @@ export class CloseConnectionService implements ICrmConnectionService {
)) as OAuth2AuthData;

const formData = new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: this.cryptoService.decrypt(refreshToken),
client_id: CREDENTIALS.CLIENT_ID,
client_secret: CREDENTIALS.CLIENT_SECRET,
grant_type: 'refresh_token',
});
const res = await axios.post(
'https://api.close.com/oauth2/token',
Expand All @@ -168,18 +165,21 @@ export class CloseConnectionService implements ICrmConnectionService {
},
);
const data: CloseOAuthResponse = res.data;
await this.prisma.connections.update({
where: {
id_connection: connectionId,
},
data: {
access_token: this.cryptoService.encrypt(data.access_token),
refresh_token: this.cryptoService.encrypt(data.refresh_token),
expiration_timestamp: new Date(
new Date().getTime() + Number(data.expires_in) * 1000,
),
},
});
if (res?.data?.access_token) {
//only update when it is successful
await this.prisma.connections.update({
where: {
id_connection: connectionId,
},
data: {
access_token: this.cryptoService.encrypt(data?.access_token),
refresh_token: this.cryptoService.encrypt(data?.refresh_token),
expiration_timestamp: new Date(
new Date().getTime() + Number(data?.expires_in) * 1000,
),
},
});
}
this.logger.log('OAuth credentials updated : close ');
} catch (error) {
handleServiceError(error, this.logger, 'close', Action.oauthRefresh);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface TypeCustom {
tcg_front: boolean;
tcg_jira: boolean;
tcg_gitlab: boolean;
crm_close: boolean;
}
@ApiTags('project-connectors')
@Controller('project-connectors')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export class ProjectConnectorsService {
tcg_front: data.tcg_front,
tcg_jira: data.tcg_jira,
tcg_gitlab: data.tcg_gitlab,
crm_close: data.crm_close,
};

const res = await this.prisma.connector_sets.create({
Expand Down
Loading
Loading