JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q65029F
  • License MIT

AmoCRM api connector for Node.js

Package Exports

  • amocrm-connector
  • amocrm-connector/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (amocrm-connector) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Test

Node.js AmoCRM api connector

Изначально библиотека создавалась для внутреннего использования. Периодически, с внесением изменений в amocrm api, в интеграции появляются ошибки. Цель данного проекта помочь создать надежный, протестированный инструмент для работы с amocrm. 👌 Поддерживать его актуальным с помощью автотестов и сообщества. Автоматические тесты запускаются каждый день с использованием github actions.

Описание

Основные возможности:

  • OAuth авторизация
  • Запросы к api
  • Частичное покрытие методов api
  • Работа с api чатов

Основные отличия версии 0.3.x от 0.2.x

  • Переход на TypeScript
  • Убраны механизмы контроля частоты запросов и автоматического обновления токена
  • Убрана поддержка стора
  • Добавлены подсистемы и описаны типы некоторых dto
  • Добавлена поддержка chat api

Начало работы

Установка

yarn add amocrm-connector

Пример использования

import {AmoCRM, AmoCRMToken} from 'amocrm-connector'
import rawToken from './token.json'

const {accessUntil, ...rest} = rawToken
const token = {
    accessUntil: new Date(accessUntil),
    ...rest
}

;(async () => {
    const amocrm = new AmoCRM({
        credential: {
            domain: 'your_domain',
            integrationId: 'integration-id',
            secretKey: 'secret-key',
            redirectUri: 'redirect-uri'
        },
        token
    })

    const {amojoId} = await amocrm.account.get(AccountWith.amojoId)
    if (!amojoId) return

    const scopeId = await amocrm.chat.connectChannel(amojoId, 'Название канала')

    const result = await amocrm.chat.addMessage(
        scopeId,
        {
            date: new Date(),
            // id беседы из вашей системы
            conversationId: 'conversation-id',
            sender: {
                id: 'sender-id',
                name: 'Имя клиента',
                profile: {
                    phone: '71234567890'
                }
            },
            id: 'message-id',
            message: {
                type: MessageType.Text,
                text: 'Тест сообщения'
            }
        }
    )
})()

Другие примеры смотрите в папке examples

Документация

Создание объекта AmoCRM

Методы AmoCRM

Подсистемы

Аккаунт

Чаты

Прочее

AmoCRM

const amocrm = new AmoCRM({
    credential: {
        // Домен вашего аккаунта. Ссылка на ваш аккаунт выглядит как https://[domain].amocrm.ru
        domain: string,
        // ID интеграции из "ключи и доступы" вашей интеграции
        integrationId: string,
        // Секретный ключ из "ключи и доступы" вашей интеграции
        secretKey: string,
        // url из настроек вашей интеграции
        redirectUri: string,
        // Секретный ключ канала чатов (secret_key)
        chatSecret?: string,
        // id зарегистрированного канала чатов
        chatId?: string
    },
    // необязательный параметр, объект токена полученный ранее
    token: AmoCRMToken
})

Методы

amocrm.on(event, eventListener)

Алиас для amocrm.addListener(event, eventListener)

amocrm.addListener(event, eventListener)

amocrm.addListener(event: 'token', eventListener: (token: AmoCRMToken) => void): void
События
  • token - при получении нового токена

amocrm.removeListener(event, eventListener)

amocrm.addListener(event: 'token', eventListener: (token: AmoCRMToken) => void): void

amocrm.tokenIsActual()

amocrm.tokenIsActual(): boolean

amocrm.getToken(options)

Запрашивает новый токен по коду авторизации или токену обновления

async amocrm.getToken(options: { code?: string, refreshToken?: string })): Promise<void>

amocrm.getOAuthLink(state, mode)

amocrm.getOAuthLink(state: string = '', mode: 'post_message' | 'popup' = 'post_message'): string

amocrm.request(config)

HTTP запрос к amocrm. Основано на библиотеке axios.

async amocrm.request<T = unknown, D = unknown>(config: AmoCRMRequestConfig<D>): Promise<AxiosResponse<T, D>>

type AmoCRMRequestConfig<D = undefined> = AxiosRequestConfig<D> & {
    useToken?: boolean,
    ifModifiedSince?: Date
}

// Описание некоторых полей AmoCRMRequestConfig
{
    // Добавлять ли заголовок Authorization
    useToken: boolean = true,
    // Добавляет заголовок If-Modified-Since
    ifModifiedSince?: Date,
    // Тело запроса
    data?: D,
    // Заголовки запроса
    headers: Record<string, string | number | boolean> = {},
    // Метод запроса
    method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET',
    // URL относительно BaseURL
    url: string,
    baseURL: string = `https://${this.credential.domain}.amocrm.ru`
}

amocrm.get(config)

amocrm.request({method: 'GET', ...config})

amocrm.post(config)

amocrm.request({method: 'POST', ...config})

amocrm.patch(config)

amocrm.request({method: 'PATCH', ...config})

amocrm.delete(config)

amocrm.request({method: 'DELETE', ...config})

amocrm.account.get(withParams)

Запрос параметров аккаунта

async amocrm.account.get(withParams ? : AccountWith | AccountWith[]): Promise<AccountInfo>

AccountInfo

amocrm.chat.request(config)

HTTP запрос к api чатов Автоматически добавляет заголовки для авторизации запроса

async amocrm.chat.request<T = unknown, D = unknown>(config: AmoCRMRequestConfig<D>): Promise<AxiosResponse<T, D>>

amocrm.chat.get(config)

amocrm.chat.request({method: 'GET', ...config})

amocrm.chat.post(config)

amocrm.chat.request({method: 'POST', ...config})

amocrm.chat.checkSignature(body, signature)

Проверяет подпись для входящих запросов (вебхуков)

amocrm.chat.checkSignature(body: unknown, signature?: string | string[]): boolean

amocrm.chat.connectChannel(amojoId, title)

Подключение канала чата в аккаунте

async amocrm.chat.connectChannel(amojoId: string, title: string): Promise<string>

Возвращаемое значение - scopeId amojoId может быть получен следующим образом

const {amojoId} = await amocrm.account.get(AccountWith.amojoId)

amocrm.chat.addMessage(scopeId, payload)

Отправка или импорт сообщения

async amocrm.chat.addMessage(scopeId: string, addMessagePayload: AmoLike<AddMessagePayload>): Promise<AddMessageResponse>

AddMessagePayload AddMessageResponse

amocrm.chat.deliveryStatus(scopeId, messageId, data)

Обновление статуса доставки сообщения

async amocrm.chat.deliveryStatus(scopeId: string, messageId: string, deliveryStatusRequest: AmoLike<DeliveryStatusRequest>): Promise<void>

DeliveryStatusRequest

amocrm.chat.typing(scopeId, data)

Передача информации о печатании

async amocrm.chat.typing(scopeId: string, typingRequest: AmoLike<TypingRequest>)

TypingRequest

AmoDTO

Цель данного класса - описать объекты передачи данных AmoCRM API. Какие задачи решает данный класс

  • Преобразование названий свойств camelCase <-> snake_case
  • Валидация объекта [нереализовано]
  • Типизация объекта
  • Сериализация/десериализация

AmoEntity

AmoEntity - некая сущность обладающая уникальным идентификатором. Свойства содержащие ссылки (идентификаторы) на объекты такого типа при десериализации автоматически заменяются на объекты этого тип, и наоборот.

AmoLike

AmoDTO и AmoEntity - классы, и для передачи значений в методы api необходимо создать каждый объект, создать вложенные объекты и т.п. Это создает много лишнего кода. Для возможности более лаконичного описания передаваемого аргумента используется AmoLike.

type AmoLike<T extends AmoDTO = AmoDTO> = T | DeepPartial<T>

Таким образом мы можем передавать в качестве аргумента как сам объект AmoDTO, так и плоский объект.

Пример

    // Плоский объект
    const result = await amocrm.chat.addMessage(
        scopeId,
        {
            date: new Date(),
            // id беседы из вашей системы
            conversationId: 'conversation-id',
            sender: {
                id: 'sender-id',
                name: 'Имя клиента',
                profile: {
                    phone: '71234567890'
                }
            },
            id: 'message-id',
            message: {
                type: MessageType.Text,
                text: 'Тест сообщения'
            }
        }
    )

    //AmoDTO
    const result = await amocrm.chat.addMessage(
        scopeId,
        new AddMessagePayload({
            date: new Date(),
            // id беседы из вашей системы
            conversationId: 'conversation-id',
            sender: new MessageParticipant({
                id: 'sender-id',
                name: 'Имя клиента',
                profile: new MessageParticipantProfile({
                    phone: '71234567890'
                })
            }),
            id: 'message-id',
            message: new AddMessageContent({
                type: MessageType.Text,
                text: 'Тест сообщения'
            })
        })
    )

Авторизация

Подробно про AmoCRM реализацию OAuth2 авторизации в официальной документации Также можете посмотреть видео от создателей другой библиотеки https://github.com/UsefulWeb/AmoCRM.

Коротко, шаги:

  1. Регистрация вашей интеграции
  2. Переход пользователя по ссылке выдачи доступа пользователем вашему приложению. Ссылку получить можно методом amocrm.getOAuthLink
  3. Обработка запроса на redirect uri, здесь должен быть запущен ваш сервер. В виде гет параметра amocrm передаст код авторизации. Его необходимо обменять на токен с помощью метода amocrm.getToken. Пример реализации смотрите в файле testing/server.js

Ошибки и пожелания

Если в процессе использования вы обнаружили ошибку, расскажите о ней, откройте issue с подробным описанием. Спасибо за помощь в тестировании! 👍 Если у вас есть пожелания, также открывайте issue! 👀

Планы

  • Покрыть все методы api
  • Реализовать унифицированный механизм работы с сущностями (Leads, Contacts, Pipelines, Companies, Catalogs, ...)
    • create(data: AmoEntity | AmoEntity[])
    • find(type: typeof AmoEntity, findOptions)
    • findOne(type: typeof AmoEntity, findOptionsOrId)
    • update(data: AmoEntity | AmoEntity[])
    • delete(data: AmoEntity | AmoEntity[])
  • Валидация AmoDTO

Разработка

Команды

  • yarn build сборка проекта
  • yarn serve запуск сервера для обработки запросов от amocrm. Необходима настройка окружения.
  • yarn tunnel создает туннель с использованием утилиты localtunnel. Необходима настройка окружения.
  • yarn cypress запуск cypress тестов, используется для проверки работы OAuth и автоматического получения токена. Необходимо:
    • Настроить окружение. Токен сохраняется в testing/token.json. Про настройку окружения ниже.
    • Запустить сервер для обработки запросов от amocrm.
    • Создать туннель с публичного адреса на ваш локальный сервер.
  • yarn cypress:open запуск cypress тестов в интерактивном режиме. Необходима настройка окружения.
  • yarn jest запуск jest тестов. Для работы необходимо настроить окружение, а также токен в testing/token.json. Поэтому полезно сначала запустить cypress тест. [Пока тестов нет]
  • yarn test запуск cypress и jest тестов

Настройка окружения

Необходимо создать файл .evn.test с переменными окружения в корне проекта. Для удобства можно воспользоваться шаблоном .env.test.example (здесь также описано для чего нужны переменные)

cp .env.test.example .env.test

Если у вас есть вопросы касательно разработки - пишите мне в телеграм @lybrus. 👈

Любая помощь в разработке и тестировании данного проекта приветствуется! 👍