Skip to content

Commit

Permalink
✨ Crm Vertical Tested
Browse files Browse the repository at this point in the history
  • Loading branch information
naelob committed Jan 20, 2024
1 parent d0cb5dc commit bdd6761
Show file tree
Hide file tree
Showing 58 changed files with 514 additions and 249 deletions.
2 changes: 1 addition & 1 deletion apps/frontend-snippet/src/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const providersConfig: ProvidersConfig = {
logoPath: 'assets/crm/freshsales_logo.webp',
},
'zendesk': {
clientId: '26cd23a81a8fefc134edec2c533a1cb1761d359cfcf438fc159543931e92fc93',
clientId: 'fbb3125a89f366daf02c09f201522245c4453c1310f07ec2223c614fac130c78',
scopes: 'read write',
authBaseUrl: 'https://api.getbase.com/oauth2/authorize',
logoPath: 'assets/crm/zendesk_logo.png',
Expand Down
8 changes: 4 additions & 4 deletions packages/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ model crm_companies {
id_linked_user String? @db.Uuid
crm_addresses crm_addresses[]
crm_users crm_users? @relation(fields: [id_crm_user], references: [id_crm_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_24")
crm_deals crm_deals[]
crm_email_addresses crm_email_addresses[]
crm_engagements crm_engagements[]
crm_notes crm_notes[]
Expand Down Expand Up @@ -138,13 +139,14 @@ model crm_deals {
id_crm_user String? @db.Uuid
id_crm_deals_stage String? @db.Uuid
id_linked_user String? @db.Uuid
id_crm_company String? @db.Uuid
crm_deals_stages crm_deals_stages? @relation(fields: [id_crm_deals_stage], references: [id_crm_deals_stage], onDelete: NoAction, onUpdate: NoAction, map: "fk_21")
crm_users crm_users? @relation(fields: [id_crm_user], references: [id_crm_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_22")
crm_notes crm_notes[]
crm_tasks crm_tasks[]
crm_companies crm_companies? @relation(fields: [id_crm_company], references: [id_crm_company], onDelete: NoAction, onUpdate: NoAction, map: "fk_47_1")
@@index([id_crm_user], map: "crm_deal_crm_userid")
@@index([id_crm_deals_stage], map: "crm_deal_deal_stageid")
@@index([id_crm_company], map: "fk_crm_deal_crmcompanyid")
}

model crm_deals_stages {
Expand Down Expand Up @@ -223,7 +225,6 @@ model crm_notes {
id_crm_user String? @db.Uuid
crm_companies crm_companies? @relation(fields: [id_crm_company], references: [id_crm_company], onDelete: NoAction, onUpdate: NoAction, map: "fk_18")
crm_contacts crm_contacts? @relation(fields: [id_crm_contact], references: [id_crm_contact], onDelete: NoAction, onUpdate: NoAction, map: "fk_19")
crm_deals crm_deals? @relation(fields: [id_crm_deal], references: [id_crm_deal], onDelete: NoAction, onUpdate: NoAction, map: "fk_20")
@@index([id_crm_contact], map: "fk_crm_note_crm_companyid")
@@index([id_crm_company], map: "fk_crm_note_crm_contactid")
Expand Down Expand Up @@ -265,7 +266,6 @@ model crm_tasks {
remote_platform String?
crm_users crm_users? @relation(fields: [id_crm_user], references: [id_crm_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_25")
crm_companies crm_companies? @relation(fields: [id_crm_company], references: [id_crm_company], onDelete: NoAction, onUpdate: NoAction, map: "fk_26")
crm_deals crm_deals? @relation(fields: [id_crm_deal], references: [id_crm_deal], onDelete: NoAction, onUpdate: NoAction, map: "fk_27")
@@index([id_crm_company], map: "fk_crm_task_companyid")
@@index([id_crm_user], map: "fk_crm_task_userid")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export class ZendeskConnectionService implements ICrmConnectionService {
});

//reconstruct the redirect URI that was passed in the frontend it must be the same
const REDIRECT_URI = `${this.env.getOAuthRredirectBaseUrl()}/connections/oauth/callback`;
//const REDIRECT_URI = `${this.env.getOAuthRredirectBaseUrl()}/connections/oauth/callback`;
const REDIRECT_URI = `http://localhost:3000/connections/oauth/callback`;

const formData = new URLSearchParams({
grant_type: 'authorization_code',
Expand Down
1 change: 0 additions & 1 deletion packages/api/src/crm/company/services/freshsales/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export class FreshsalesService implements ICompanyService {
linkedUserId: string,
): Promise<ApiResponse<FreshsalesCompanyOutput[]>> {
try {
//TODO: check required scope => crm.objects.companys.READ
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
Expand Down
2 changes: 0 additions & 2 deletions packages/api/src/crm/company/services/hubspot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export class HubspotService implements ICompanyService {
linkedUserId: string,
): Promise<ApiResponse<HubspotCompanyOutput>> {
try {
//TODO: check required scope => crm.objects.companys.write
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
Expand Down Expand Up @@ -75,7 +74,6 @@ export class HubspotService implements ICompanyService {
custom_properties?: string[],
): Promise<ApiResponse<HubspotCompanyOutput[]>> {
try {
//TODO: check required scope => crm.objects.companys.READ
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
Expand Down
2 changes: 0 additions & 2 deletions packages/api/src/crm/company/services/pipedrive/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export class PipedriveService implements ICompanyService {
linkedUserId: string,
): Promise<ApiResponse<PipedriveCompanyOutput>> {
try {
//TODO: check required scope => crm.objects.companys.write
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
Expand Down Expand Up @@ -72,7 +71,6 @@ export class PipedriveService implements ICompanyService {
linkedUserId: string,
): Promise<ApiResponse<PipedriveCompanyOutput[]>> {
try {
//TODO: check required scope => crm.objects.companys.READ
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
Expand Down
74 changes: 26 additions & 48 deletions packages/api/src/crm/company/services/pipedrive/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import {
} from '@crm/company/types/model.unified';
import { ICompanyMapper } from '@crm/company/types';
import { Utils } from '@crm/contact/utils';
import { OriginalCompanyOutput } from '@@core/utils/types/original/original.crm';

export class PipedriveCompanyMapper implements ICompanyMapper {
private readonly utils: Utils;

constructor() {
this.utils = new Utils();
}

async desunify(
source: UnifiedCompanyInput,
customFieldMappings?: {
Expand All @@ -24,33 +26,10 @@ export class PipedriveCompanyMapper implements ICompanyMapper {
): Promise<PipedriveCompanyInput> {
const result: PipedriveCompanyInput = {
name: source.name,
email: source.email_addresses?.find(
(email) => email.email_address_type === 'primary',
)?.email_address
? [
{
value: source.email_addresses.find(
(email) => email.email_address_type === 'primary',
)?.email_address,
primary: true,
label: 'Primary Email',
},
]
: undefined,
phone: source.phone_numbers?.find(
(phone) => phone.phone_type === 'primary',
)?.phone_number
? [
{
value: source.phone_numbers.find(
(phone) => phone.phone_type === 'primary',
)?.phone_number,
primary: true,
label: 'Primary Phone',
},
]
: undefined,
// Add additional fields mapping here
address: source.addresses[0].street_1,
address_locality: source.addresses[0].city,
address_country: source.addresses[0].country,
address_postal_code: source.addresses[0].postal_code,
};

if (source.user_id) {
Expand Down Expand Up @@ -110,6 +89,16 @@ export class PipedriveCompanyMapper implements ICompanyMapper {
[mapping.slug]: company[mapping.remote_id],
})) || [];

let res = {
name: company.name,
industry: '', // Pipedrive may not directly provide this, need custom mapping
number_of_employees: 0, // Placeholder, as there's no direct mapping provided
email_addresses: [],
phone_numbers: [],
addresses: [],
field_mappings,
};

let opts: any = {};
if (company.owner_id.id) {
const user_id = await this.utils.getUserUuidFromRemoteId(
Expand All @@ -122,26 +111,15 @@ export class PipedriveCompanyMapper implements ICompanyMapper {
};
}
}

return {
name: company.name,
industry: '', // Pipedrive may not directly provide this, need custom mapping
number_of_employees: 0, // Placeholder, as there's no direct mapping provided
email_addresses: [
{
email_address: company.primary_email,
email_address_type: 'primary',
owner_type: 'company',
},
],
addresses: [], // Add address mapping if available
phone_numbers: company.phone?.map((phone) => ({
phone_number: phone.value,
phone_type: phone.primary ? 'primary' : 'secondary',
owner_type: 'company',
})),
field_mappings,
...opts,
};
if (company.address) {
res.addresses[0] = {
street_1: company.address,
city: company.address_locality,
country: company.address_country,
postal_code: company.address_postal_code,
};
}
res = { ...res, ...opts };
return res;
}
}
41 changes: 17 additions & 24 deletions packages/api/src/crm/company/services/pipedrive/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,13 @@ export interface PipedriveCompany {
active_flag: boolean;
value: number;
};
org_id: {
name: string;
people_count: number;
owner_id: number;
address: string;
active_flag: boolean;
cc_email: string;
value: number;
};
name: string;
first_name: string;
last_name: string;
open_deals_count: number;
related_open_deals_count: number;
closed_deals_count: number;
related_closed_deals_count: number;
participant_open_deals_count: number;
participant_closed_deals_count: number;
email_messages_count: number;
people_count: number;
activities_count: number;
done_activities_count: number;
undone_activities_count: number;
Expand All @@ -40,14 +28,6 @@ export interface PipedriveCompany {
lost_deals_count: number;
related_lost_deals_count: number;
active_flag: boolean;
phone: { value: string; primary: boolean; label: string }[];
email: { value: string; primary: boolean; label: string }[];
primary_email: string;
first_char: string;
update_time: Date;
add_time: Date;
visible_to: string;
marketing_status: string;
picture_id: {
item_type: string;
item_id: number;
Expand All @@ -61,15 +41,28 @@ export interface PipedriveCompany {
};
value: number;
};
country_code: string;
first_char: string;
update_time: Date;
add_time: Date;
visible_to: string;
next_activity_date: string;
next_activity_time: string;
next_activity_id: number;
last_activity_id: number;
last_activity_date: string;
last_incoming_mail_time: string;
last_outgoing_mail_time: string;
label: number;
org_name: string;
address: string;
address_subpremise: string;
address_street_number: string;
address_route: string;
address_sublocality: string;
address_locality: string;
address_admin_area_level_1: string;
address_admin_area_level_2: string;
address_country: string;
address_postal_code: string;
address_formatted_address: string;
owner_name: string;
cc_email: string;
[key: string]: any;
Expand Down
19 changes: 9 additions & 10 deletions packages/api/src/crm/company/services/zendesk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,19 @@ export class ZendeskService implements ICompanyService {
this.registry.registerService('zendesk', this);
}

//TODO: CANT ADD A COMPANY WITH ZENDESK
async addCompany(
companyData: ZendeskCompanyInput,
linkedUserId: string,
): Promise<ApiResponse<ZendeskCompanyOutput>> {
try {
//TODO: check required scope => crm.objects.companys.write
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'zendesk',
},
});
const resp = await axios.post(
`https://api.getbase.com/v2/accounts/self`,
`https://api.getbase.com/v2/contacts`,
{
data: companyData,
},
Expand Down Expand Up @@ -75,29 +73,30 @@ export class ZendeskService implements ICompanyService {
linkedUserId: string,
): Promise<ApiResponse<ZendeskCompanyOutput[]>> {
try {
//TODO: check required scope => crm.objects.companys.READ
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'zendesk',
},
});
const resp = await axios.get(`https://api.getbase.com/v2/accounts/self`, {
const resp = await axios.get(`https://api.getbase.com/v2/contacts`, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
},
});
const finalData = resp.data.items.map((item) => {
return item.data;
});
this.logger.log(`Synced zendesk companys !`);
const finalData = resp.data.items
.filter((item) => item.data.is_organization === true)
.map((item) => {
return item.data;
});
this.logger.log(`Synced zendesk companies !`);

return {
data: finalData,
message: 'Zendesk companys retrieved',
message: 'Zendesk companies retrieved',
statusCode: 200,
};
} catch (error) {
Expand Down
Loading

0 comments on commit bdd6761

Please sign in to comment.