Разработка REST-приложений Битрикс24 на TypeScript

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка REST-приложений Битрикс24 на TypeScript
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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 Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка REST-приложений Битрикс24 на TypeScript

Битрикс24 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 недели