Skip to content

Instantly share code, notes, and snippets.

@ChemaCLi
Last active February 25, 2024 08:43
Show Gist options
  • Select an option

  • Save ChemaCLi/9c3b18e8bf59026561f65338d72decc7 to your computer and use it in GitHub Desktop.

Select an option

Save ChemaCLi/9c3b18e8bf59026561f65338d72decc7 to your computer and use it in GitHub Desktop.
Bitrix 24 CRM Rest API - NodeJS Usage
export const API = ({ baseUrl }: { baseUrl: string }) => ({
async get(url: string, options: { params?: any } = {}) {
const paramsString = Object.entries(options.params || {})
.map(([key, value]) => `${key}=${value}`)
.join('&')
const endpoint = `${baseUrl}${url}?${paramsString}`;
const response = await fetch(endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
});
const data = await response.json();
return { data }
},
async post(url: string, data: any = {}) {
const response = await fetch(baseUrl+url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
const result = await response.json();
return { data: result }
},
})
import { API } from "./bitrix.api";
import config from "./config";
const bitrixAPI = API({ baseUrl: config.bitrix.API_URL });
const findItemByContactField = async (
itemType: ItemType,
contactField: ContactField
): Promise<Array<{ id: number; type: ItemType }>> => {
const [type, value] = Object.entries(contactField)[0];
const apiResult = await bitrixAPI.get('/crm.duplicate.findbycomm.json', {
params: {
type,
'values[]': value,
entity_type: itemType
}
});
return (apiResult.data.result[itemType] || [])
.map((id: number) => ({ id, type: itemType }));
};
const getLeadResponsible = async (leadId: number): Promise<number> => {
const apiResult = await bitrixAPI.get('/crm.lead.list.json', {
params: {
'filter[ID]': leadId,
'select[]': 'ASSIGNED_BY_ID'
}
});
return apiResult.data.result[0].ASSIGNED_BY_ID;
};
const getContactResponsible = async (contactId: number): Promise<number> => {
const apiResult = await bitrixAPI.get('/crm.contact.list.json', {
params: {
'filter[ID]': contactId,
'select[]': 'ASSIGNED_BY_ID'
}
});
return apiResult.data.result[0].ASSIGNED_BY_ID;
};
const findLeadOrContactByPhoneOrEmail = async (
criteria: { phone?: string, email?: string }
): Promise<{ id: number; type: ItemType } | null> => {
const [phoneContacts, emailContacts, phoneLeads, emailLeads] = await Promise.all([
findItemByContactField('CONTACT', { PHONE: criteria.phone }),
findItemByContactField('CONTACT', { EMAIL: criteria.email }),
findItemByContactField('LEAD', { PHONE: criteria.phone }),
findItemByContactField('LEAD', { EMAIL: criteria.email })
]);
const foundItemsWithResults = [
...phoneContacts,
...emailContacts,
...phoneLeads,
...emailLeads
];
const [foundItem] = foundItemsWithResults;
return foundItem || null;
};
const registerLead = async (payload: TrackLeadDTO): Promise<{ id: number }> => {
const apiResult = await bitrixAPI.post('/crm.lead.add.json', {
fields: {
NAME: payload.firstName,
LAST_NAME: payload.lastName,
EMAIL: [{ VALUE: payload.email, VALUE_TYPE: 'WORK' }],
COMPANY_TITLE: payload.businessName,
PHONE: [{ VALUE: payload.phone, VALUE_TYPE: 'WORK' }],
STATUS_ID: config.bitrix.DEFAULT_STAGE_ID,
ASSIGNED_BY_ID: config.bitrix.DEFAULT_USER_ID,
// SOURCE_ID: 'FACEBOOK', // use your custom source
// SOURCE_DESCRIPTION: "This lead came from Facebook campain" // use your custom source
}
});
return { id: apiResult.data.result };
};
const createActivityForCRMItem = async (ownerId: number, description: string, responsibleId: number, itemType: ItemType) => {
const deadline = dayjs(new Date()).add(20, 'minutes').toDate();
const ownerTypeId = {
'LEAD': 1,
'CONTACT': 3,
'COMPANY': 4
}[itemType];
// this is the new way to create activities
const apiResult = await bitrixAPI.post('/crm.activity.todo.add.json', {
ownerTypeId,
ownerId, // the id of the lead or contact
description: description,
deadline,
responsibleId
});
return apiResult.data.result?.id || apiResult.data.result;
};
const addReminderToActivity = async (
activityId: number,
leadId: number,
itemType: ItemType
) => {
const ownerTypeIds = {
'LEAD': 1,
'CONTACT': 3,
'COMPANY': 4
};
const minutesBeforeDeadline = 15;
return bitrixAPI.post('/crm.activity.todo.updatePingOffsets.json', {
ownerTypeId: ownerTypeIds[itemType],
ownerId: Number(leadId),
id: activityId,
value: [minutesBeforeDeadline]
});
};
return {
registerLead,
getLeadResponsible,
addReminderToActivity,
getContactResponsible,
createActivityForCRMItem,
findLeadOrContactByPhoneOrEmail
};
};
type ContactField = {
EMAIL?: string;
PHONE?: string;
}
type ItemType = 'LEAD' | 'CONTACT' | 'COMPANY'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment