Skip to content

Commit

Permalink
🐛 Fixed sync test
Browse files Browse the repository at this point in the history
  • Loading branch information
naelob committed Jan 9, 2024
1 parent 56c9ae4 commit eb947b8
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 34 deletions.
3 changes: 2 additions & 1 deletion packages/api/src/ticketing/@utils/@types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { contactUnificationMapping } from '@crm/contact/types/mappingsTypes';
import { contactUnificationMapping as contactTicketingUnificationMapping } from '@ticketing/contact/types/mappingsTypes';
import { IAccountService } from '@ticketing/account/types';
import { accountUnificationMapping } from '@ticketing/account/types/mappingsTypes';
import {
Expand Down Expand Up @@ -80,7 +81,7 @@ export const unificationMapping = {
[TicketingObject.comment]: commentUnificationMapping,
[TicketingObject.user]: userUnificationMapping,
[TicketingObject.account]: accountUnificationMapping,
[TicketingObject.contact]: contactUnificationMapping,
[TicketingObject.contact]: contactTicketingUnificationMapping,
[TicketingObject.team]: teamUnificationMapping,
[TicketingObject.tag]: tagUnificationMapping,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/ticketing/account/services/zendesk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class ZendeskService implements IAccountService {
});

const resp = await axios.get(
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/accounts`,
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/organizations.json`,
{
headers: {
'Content-Type': 'application/json',
Expand All @@ -54,7 +54,7 @@ export class ZendeskService implements IAccountService {
this.logger.log(`Synced zendesk accounts !`);

return {
data: resp.data.accounts,
data: resp.data.organizations,
message: 'Zendesk accounts retrieved',
statusCode: 200,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ export class ZendeskAccountMapper implements IAccountMapper {
}

private mapSingleAccountToUnified(
ticket: ZendeskAccountOutput,
account: ZendeskAccountOutput,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): UnifiedAccountOutput {
return;
const unifiedAccount: UnifiedAccountOutput = {
name: account.name,
domains: account.domain_names,
};

return unifiedAccount;
}
}
17 changes: 15 additions & 2 deletions packages/api/src/ticketing/account/services/zendesk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ export type ZendeskAccountInput = {
_: string;
};

export type ZendeskAccountOutput = ZendeskAccountInput & {
id: number; // Read-only. Automatically assigned when the ticket is created.
export type ZendeskAccountOutput = {
created_at: string; // The time the organization was created
details?: string; // Any details about the organization, such as the address
domain_names?: string[]; // An array of domain names associated with this organization
external_id?: string; // A unique external id to associate organizations to an external record
group_id?: number; // New tickets from users in this organization are automatically put in this group
id: number; // Automatically assigned when the organization is created
name: string; // A unique name for the organization
notes?: string; // Any notes you have about the organization
organization_fields?: { [key: string]: any }; // Custom fields for this organization
shared_comments?: boolean; // End users in this organization are able to see each other's comments on tickets
shared_tickets?: boolean; // End users in this organization are able to see each other's tickets
tags?: string[]; // The tags of the organization
updated_at: string; // The time of the last update of the organization
url?: string; // The API url of this organization
};
4 changes: 3 additions & 1 deletion packages/api/src/ticketing/account/sync/sync.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ export class SyncService implements OnModuleInit {
this.serviceRegistry.getService(integrationId);
const resp: ApiResponse<OriginalAccountOutput[]> =
await service.syncAccounts(linkedUserId, remoteProperties);
this.logger.log('bdbdbdbdbdb ');

const sourceObject: OriginalAccountOutput[] = resp.data;
//this.logger.log('SOURCE OBJECT DATA = ' + JSON.stringify(sourceObject));
this.logger.log('resp is ' + sourceObject);

//unify the data according to the target obj wanted
const unifiedObject = (await unify<OriginalAccountOutput[]>({
sourceObject,
Expand Down
8 changes: 6 additions & 2 deletions packages/api/src/ticketing/contact/services/zendesk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class ZendeskService implements IContactService {
});

const resp = await axios.get(
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/contacts`,
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/users`,
{
headers: {
'Content-Type': 'application/json',
Expand All @@ -51,10 +51,14 @@ export class ZendeskService implements IContactService {
},
},
);
const contacts: ZendeskContactOutput[] = resp.data.users;
const filteredContacts = contacts.filter(
(contact) => contact.role === 'end-user',
);
this.logger.log(`Synced zendesk contacts !`);

return {
data: resp.data.contacts,
data: filteredContacts,
message: 'Zendesk contacts retrieved',
statusCode: 200,
};
Expand Down
16 changes: 14 additions & 2 deletions packages/api/src/ticketing/contact/services/zendesk/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,24 @@ export class ZendeskContactMapper implements IContactMapper {
}

private mapSingleContactToUnified(
ticket: ZendeskContactOutput,
contact: ZendeskContactOutput,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): UnifiedContactOutput {
return;
const field_mappings = customFieldMappings?.map((mapping) => ({
[mapping.slug]: contact.user_fields?.[mapping.remote_id],
}));

const unifiedContact: UnifiedContactOutput = {
name: contact.name,
email_address: contact.email,
phone_number: contact.phone,
details: contact.details,
field_mappings: field_mappings,
};

return unifiedContact;
}
}
49 changes: 46 additions & 3 deletions packages/api/src/ticketing/contact/services/zendesk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,49 @@ export type ZendeskContactInput = {
_: string;
};

export type ZendeskContactOutput = ZendeskContactInput & {
id: number; // Read-only. Automatically assigned when the ticket is created.
};
export type ZendeskContactOutput = Partial<{
active: boolean;
alias?: string;
chat_only: boolean;
created_at: string;
custom_role_id?: number;
default_group_id?: number;
details?: string;
email: string;
external_id?: string;
iana_time_zone: string;
id: number;
last_login_at: string;
locale?: string;
locale_id?: number;
moderator?: boolean;
name: string;
notes?: string;
only_private_comments?: boolean;
organization_id?: number;
phone?: string;
photo?: { [key: string]: any }; // Assuming an object type for the Attachment object
remote_photo_url?: string;
report_csv: boolean;
restricted_agent?: boolean;
role?: string;
role_type: number;
shared: boolean;
shared_agent: boolean;
shared_phone_number?: boolean;
signature?: string;
suspended?: boolean;
tags?: string[];
ticket_restriction?:
| 'organization'
| 'groups'
| 'assigned'
| 'requested'
| null;
time_zone?: string;
two_factor_auth_enabled: boolean;
updated_at: string;
url: string;
user_fields?: { [key: string]: any }; // Assuming an object type for custom fields
verified?: boolean;
}>;
8 changes: 6 additions & 2 deletions packages/api/src/ticketing/tag/services/zendesk/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export class ZendeskTagMapper implements ITagMapper {
remote_id: string;
}[],
): UnifiedTagOutput | UnifiedTagOutput[] {
const tags = source.tags;
if (!source) return [];

return tags.map((tag) =>
return source.map((tag) =>
this.mapSingleTagToUnified(tag, customFieldMappings),
);
}
Expand All @@ -38,6 +38,10 @@ export class ZendeskTagMapper implements ITagMapper {
}[],
): UnifiedTagOutput {
const unifiedTag: UnifiedTagOutput = {
id: `zendesk_tag_uuid_${tag}`,
// this is used so we can have a remote_id inside our Tag table
//this id is a fake id put in place as Zendesk does not store any uuid for it,it must not be onsidered the same as the uuid from panora which is stored also in this id field
// actually this fake id would be just used inside the sync function SHORT TERM and would be replaced in its final form by the real uuid inside Panora db
name: tag,
};

Expand Down
4 changes: 1 addition & 3 deletions packages/api/src/ticketing/tag/services/zendesk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ export type ZendeskTagInput = {
_: string;
};

export type ZendeskTagOutput = {
tags: string[];
};
export type ZendeskTagOutput = string[];
19 changes: 13 additions & 6 deletions packages/api/src/ticketing/tag/sync/sync.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,13 @@ export class SyncService implements OnModuleInit {
);

const sourceObject: OriginalTagOutput[] = resp.data;
//this.logger.log('SOURCE OBJECT DATA = ' + JSON.stringify(sourceObject));

//TODO; do it in every file
if (!sourceObject || sourceObject.length == 0) {
this.logger.warn('Source object is empty, returning :) ....');
return;
}

//unify the data according to the target obj wanted
const unifiedObject = (await unify<OriginalTagOutput[]>({
sourceObject,
Expand All @@ -141,8 +147,8 @@ export class SyncService implements OnModuleInit {
customFieldMappings,
})) as UnifiedTagOutput[];

//TODO
const tagIds = sourceObject.map((tag) =>
//TODO: exceptionally we use the unifiedObject as we might need to get the fake remote ids from Zendesk store in id field
const tagIds = unifiedObject.map((tag) =>
'id' in tag ? String(tag.id) : undefined,
);

Expand Down Expand Up @@ -191,10 +197,10 @@ export class SyncService implements OnModuleInit {
let tags_results: TicketingTag[] = [];
for (let i = 0; i < tags.length; i++) {
const tag = tags[i];
let originId = originIds[i];
const originId = originIds[i];

if (!originId || originId == '') {
originId = 'zendesk_id_tag'; //zendesk does not return a uuid so we put that as default value
return;
}

const existingTag = await this.prisma.tcg_tags.findFirst({
Expand Down Expand Up @@ -223,13 +229,14 @@ export class SyncService implements OnModuleInit {
} else {
// Create a new tag
this.logger.log('not existing tag ' + tag.name);

const data = {
id_tcg_tag: uuidv4(),
name: tag.name,
created_at: new Date(),
modified_at: new Date(),
id_tcg_ticket: id_ticket,
id_linked_users: linkedUserId,
id_linked_user: linkedUserId,
remote_id: originId,
remote_platform: originSource,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/ticketing/team/services/zendesk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ZendeskService implements ITeamService {
});

const resp = await axios.get(
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/teams`,
`https://${this.env.getZendeskTicketingSubdomain()}.zendesk.com/api/v2/groups.json`,
{
headers: {
'Content-Type': 'application/json',
Expand All @@ -51,7 +51,7 @@ export class ZendeskService implements ITeamService {
this.logger.log(`Synced zendesk teams !`);

return {
data: resp.data.teams,
data: resp.data.groups,
message: 'Zendesk teams retrieved',
statusCode: 200,
};
Expand Down
9 changes: 7 additions & 2 deletions packages/api/src/ticketing/team/services/zendesk/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ export class ZendeskTeamMapper implements ITeamMapper {
}

private mapSingleTeamToUnified(
ticket: ZendeskTeamOutput,
team: ZendeskTeamOutput,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): UnifiedTeamOutput {
return;
const unifiedTeam: UnifiedTeamOutput = {
name: team.name,
description: team.description,
};

return unifiedTeam;
}
}
12 changes: 10 additions & 2 deletions packages/api/src/ticketing/team/services/zendesk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ export type ZendeskTeamInput = {
_: string;
};

export type ZendeskTeamOutput = ZendeskTeamInput & {
id: number; // Read-only. Automatically assigned when the ticket is created.
export type ZendeskTeamOutput = {
created_at: string; // The time the group was created
default: boolean; // If the group is the default one for the account
deleted: boolean; // Deleted groups get marked as such
description?: string; // The description of the group
id: number; // Automatically assigned when creating groups
is_public?: boolean; // If true, the group is public. If false, the group is private
name: string; // The name of the group
updated_at: string; // The time of the last update of the group
url: string; // The API url of the group
};
1 change: 0 additions & 1 deletion packages/api/src/ticketing/ticket/sync/sync.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ export class SyncService implements OnModuleInit {
if (existingTicket) {
// Update the existing ticket
let data: any = {
id_tcg_ticket: uuidv4(),
modified_at: new Date(),
};
if (ticket.name) {
Expand Down
4 changes: 3 additions & 1 deletion packages/api/src/ticketing/user/services/zendesk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ export class ZendeskService implements IUserService {
},
);
this.logger.log(`Synced zendesk users !`);
const users: ZendeskUserOutput[] = resp.data.users;
const filteredUsers = users.filter((user) => user.role === 'agent');

return {
data: resp.data.users,
data: filteredUsers,
message: 'Zendesk users retrieved',
statusCode: 200,
};
Expand Down

0 comments on commit eb947b8

Please sign in to comment.