Розробка REST-додатків Бітрікс24 на TypeScript

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка REST-додатків Бітрікс24 на TypeScript
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка REST-застосунків Бітрікс24 на TypeScript

Bitrix24 REST API — багатий, але заплутаний. Автодоповнення в IDE для методів crm.deal.list, tasks.task.add, im.message.send працює лише якщо є типи. Без TypeScript розробка REST-застосунку Бітрікс24 — це постійне переключення в документацію та ловіння undefined у рантаймі.

Розробка REST-застосунків Бітрікс24 на TypeScript

Архітектура REST-застосунку Бітрікс24

Три типи застосунків в екосистемі Бітрікс24:

  1. Веб-застосунок (iframe) — завантажується всередині інтерфейсу Бітрікс24 в iframe. JavaScript/TypeScript з доступом до BX24.js SDK.
  2. Серверний застосунок — PHP/Node.js, працює незалежно, обмінюється з Бітрікс24 через REST поверх OAuth.
  3. Віджет — компактний застосунок у sidebar або CRM.

TypeScript застосовний у всіх трьох випадках, але з різними точками входу.

Типізація BX24 SDK

Офіційного TypeScript-пакета для BX24 SDK немає. Пишемо декларацію самостійно:

// types/bx24.d.ts
declare global {
    const BX24: {
        init(callback: () => void): void;
        isAdmin(): boolean;
        getAuth(): BX24Auth;
        refreshAuth(callback: (auth: BX24Auth) => void): void;
        callMethod(
            method:   string,
            params?:  Record<string, unknown>,
            callback?: (result: BX24CallResult) => void
        ): void;
        callBatch(
            calls:    Record<string, [string, Record<string, unknown>?]>,
            callback: (result: Record<string, BX24CallResult>) => void,
            bHaltOnError?: boolean
        ): void;
        resizeWindow(width: number, height: number): void;
        closeApplication(): void;
        placement: {
            info(): BX24PlacementInfo;
            call(command: string, params?: Record<string, unknown>): void;
        };
    };
}

interface BX24Auth {
    access_token:  string;
    refresh_token: string;
    expires_in:    number;
    domain:        string;
    member_id:     string;
}

interface BX24CallResult {
    status():  number;
    data():    unknown;
    error():   string | false;
    more():    boolean;
    next():    void;
    total():   number;
}

interface BX24PlacementInfo {
    placement: string;
    options:   Record<string, string>;
}

export {};

Типи для CRM-даних

// types/crm.ts

export interface BX24Deal {
    ID:                     string;
    TITLE:                  string;
    STAGE_ID:               string;
    OPPORTUNITY:            string;
    CURRENCY_ID:            string;
    ASSIGNED_BY_ID:         string;
    DATE_CREATE:            string;
    DATE_MODIFY:            string;
    CONTACT_ID:             string | null;
    COMPANY_ID:             string | null;
    COMMENTS:               string | null;
    UF_CRM_CUSTOM_FIELD?:   string; // користувацькі поля через UF_
    [key: string]: unknown; // додаткові поля
}

export interface BX24Task {
    id:             string;
    title:          string;
    description:    string;
    status:         string;
    responsible:    { id: string; name: string };
    deadline:       string | null;
    createdDate:    string;
    ufTaskWebdavFiles?: string[]; // користувацькі поля завдань
}

export type StageId =
    | 'NEW' | 'PREPARATION' | 'PREPAYMENT_INVOICE'
    | 'EXECUTING' | 'FINAL_INVOICE' | 'WON' | 'LOSE';

Обгортка над BX24 callMethod з типами

// api/bx24client.ts

export function callMethod<T>(
    method: string,
    params: Record<string, unknown> = {}
): Promise<T[]> {
    return new Promise((resolve, reject) => {
        const results: T[] = [];

        const handleResult = (result: ReturnType<typeof BX24.callMethod extends (...args: unknown[]) => infer R ? R : never>) => {
            if (result.error()) {
                reject(new Error(String(result.error())));
                return;
            }

            const data = result.data() as T[];
            results.push(...(Array.isArray(data) ? data : [data as T]));

            if (result.more()) {
                result.next(); // автоматична пагінація
            } else {
                resolve(results);
            }
        };

        BX24.callMethod(method, params, handleResult);
    });
}

// Використання
import type { BX24Deal } from '@/types/crm';

const deals = await callMethod<BX24Deal>('crm.deal.list', {
    filter: { STAGE_ID: 'NEW' },
    select: ['ID', 'TITLE', 'OPPORTUNITY', 'ASSIGNED_BY_ID'],
    order:  { DATE_CREATE: 'DESC' },
});

result.more() + result.next() — механізм пагінації BX24 SDK. Обгортка автоматично обходить всі сторінки та повертає повний масив.

Batch-запити для продуктивності

Кожен callMethod — окремий HTTP-запит. Для застосунків з високим навантаженням на API — використовуємо callBatch:

export function callBatch<T extends Record<string, unknown>>(
    calls: Record<string, [string, Record<string, unknown>?]>
): Promise<T> {
    return new Promise((resolve, reject) => {
        BX24.callBatch(calls, (results) => {
            const output = {} as T;
            let hasError = false;

            for (const [key, result] of Object.entries(results)) {
                if (result.error()) {
                    hasError = true;
                    console.error(`Batch error for "${key}":`, result.error());
                } else {
                    (output as Record<string, unknown>)[key] = result.data();
                }
            }

            if (hasError) reject(new Error('Batch had errors'));
            else resolve(output);
        });
    });
}

// Завантаження угоди з пов'язаними даними за один запит
const data = await callBatch<{
    deal:    BX24Deal;
    contact: BX24Contact;
    history: BX24Activity[];
}>({
    deal:    ['crm.deal.get',     { id: dealId }],
    contact: ['crm.contact.get',  { id: contactId }],
    history: ['crm.activity.list', { filter: { OWNER_ID: dealId, OWNER_TYPE_ID: '2' } }],
});

React + TypeScript застосунок в iframe Бітрікс24

// main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';

BX24.init(() => {
    const container = document.getElementById('app');
    if (!container) return;

    const root = createRoot(container);
    root.render(<App />);

    // Автопідбір висоти iframe
    const resizeObserver = new ResizeObserver(() => {
        BX24.resizeWindow(
            document.body.scrollWidth,
            document.body.scrollHeight
        );
    });
    resizeObserver.observe(document.body);
});

Терміни

Завдання Терміни
Налаштування TypeScript, типи BX24 SDK та CRM-сутностей 1–2 дні
Простий iframe-застосунок (перегляд/редагування даних CRM) 3–5 днів
Повнофункціональний React-застосунок у Бітрікс24 2–4 тижні
Серверний Node.js/TypeScript застосунок з OAuth 1–2 тижні