Comparing version 2.0.10 to 3.0.0
{ | ||
"name": "amocrm-js", | ||
"version": "2.0.10", | ||
"version": "3.0.0", | ||
"description": "JS Library for AmoCRM", | ||
"main": "dist/AmoCRM.js", | ||
"main": "dist/Client.js", | ||
"directories": { | ||
@@ -10,5 +10,5 @@ "test": "test" | ||
"scripts": { | ||
"test-build": "npm run build && babel-node spec/run.js", | ||
"test": "babel-node spec/run.js", | ||
"build": "babel src -d dist" | ||
"test": "jest --no-cache --verbose false --silent false", | ||
"build": "tsc", | ||
"docs": "typedoc" | ||
}, | ||
@@ -31,14 +31,26 @@ "repository": { | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"@babel/core": "^7.17.10", | ||
"@babel/plugin-proposal-decorators": "^7.17.12", | ||
"@babel/preset-env": "^7.17.10", | ||
"@babel/preset-typescript": "^7.17.12", | ||
"@types/events": "^3.0.0", | ||
"@types/jest": "^27.5.1", | ||
"@types/node": "^17.0.34", | ||
"@types/qs": "^6.9.7", | ||
"@typescript-eslint/eslint-plugin": "^5.23.0", | ||
"@typescript-eslint/parser": "^5.23.0", | ||
"babel-jest": "^28.1.0", | ||
"babel-preset-env": "^1.7.0", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babel-preset-stage-0": "^6.24.1", | ||
"eslint-plugin-jasmine": "^2.10.1", | ||
"jasmine": "^3.3.0" | ||
"jest": "^28.1.0", | ||
"ngrok": "^4.3.1", | ||
"ts-jest": "^28.0.2", | ||
"tslib": "^2.4.0", | ||
"typedoc": "^0.22.15" | ||
}, | ||
"dependencies": { | ||
"promise-queue": "^2.2.5", | ||
"qs": "^6.5.2", | ||
"xml2js": "^0.4.19" | ||
"qs": "^6.10.3", | ||
"reflect-metadata": "^0.1.13", | ||
"typescript": "^4.6.4" | ||
} | ||
} |
428
README.md
# AmoCRM | ||
Javascript библиотека для работы с AmoCRM | ||
[![npm version](https://img.shields.io/npm/v/amocrm-js.svg?style=flat-square)](https://github.com/UsefulWeb/AmoCRM/stargazers) | ||
[![GitHub stars](https://img.shields.io/github/stars/UsefulWeb/AmoCRM)](https://github.com/UsefulWeb/AmoCRM/stargazers) | ||
[![GitHub license](https://img.shields.io/github/license/UsefulWeb/AmoCRM)](https://github.com/UsefulWeb/AmoCRM/blob/master/LICENSE) | ||
Данная версия библиотеки поддерживает OAuth авторизацию и использует адреса AmoCRM API v4. | ||
JavaScript библиотека для работы с AmoCRM | ||
[Поблагодарить можно тут](https://yasobe.ru/na/cisterna_kofe_dlya_razrabot4ika_biblioteki_amocrm) | ||
Поддерживает OAuth авторизацию и использует адреса AmoCRM API v4. | ||
## Изменения в 2.x.x по сравнению с 1.x.x | ||
По вопросам сотрудничества и проектам [пишите в Telegram](https://t.me/neizerth). | ||
1. Поддержка AmoCRM API v4 | ||
2. Поддержка OAuth | ||
3. Поддержка метода PATCH | ||
4. Расширенная информация об ответе (статус ответа, время ответа и т.д) | ||
## Изменения в 3.x.x по сравнению с 2.x.x | ||
Если вам нужна поддержка AmoCRM API v2, используйте версии 1.x.x данного пакета. | ||
1. TypeScript исходная версия кода | ||
2. Подсветка синтаксиса на основе TS-интерфейсов | ||
3. Удобная передача GET-параметров | ||
4. Добавлен выброс ошибок приложения и API-запросов | ||
5. Добавлены новые события в компоненты приложения | ||
## Установка | ||
npm | ||
``` | ||
@@ -24,2 +28,19 @@ npm install amocrm-js | ||
Yarn | ||
``` | ||
yarn add amocrm-js | ||
``` | ||
## Использование | ||
```js | ||
const Client = require('amocrm-js'); | ||
``` | ||
ES6: | ||
```js | ||
import Client from 'amocrm-js'; | ||
``` | ||
## Подключение к CRM | ||
@@ -33,6 +54,2 @@ | ||
## Что такое OAuth и как всё настроить? | ||
Я снял для вас отдельное видео, ознакомьтесь с основами работы нового протокола и библиотеки: https://youtu.be/eK7xYAbxJHo | ||
### Код авторизации известен | ||
@@ -44,5 +61,8 @@ | ||
```js | ||
const AmoCRM = require( 'amocrm-js' ); | ||
const crm = new AmoCRM({ | ||
/* | ||
const Client = | ||
*/ | ||
const client = new Client({ | ||
// логин пользователя в портале, где адрес портала domain.amocrm.ru | ||
@@ -58,3 +78,8 @@ domain: 'domain', // может быть указан полный домен вида domain.amocrm.ru, domain.amocrm.com | ||
redirect_uri: 'redirectUri', // Ссылка для перенаправления | ||
code: 'code' // Код авторизации | ||
code: 'code', // Код для упрощённой авторизации, необязательный | ||
/* | ||
Параметр состояния для проверки на корректность. Необязательный. Используется встроенным сервером авторизации | ||
см. https://www.amocrm.ru/developers/content/oauth/step-by-step#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-Authorization-code | ||
*/ | ||
state: 'state', | ||
}, | ||
@@ -66,7 +91,8 @@ }); | ||
В AmoCRM API у кода авторизации есть особенность: его можно использовать __только один раз__ для получения | ||
В AmoCRM API код авторизации можно использовать __только один раз__ для получения | ||
токена. Последующие запросы на получение токена будут выдавать ошибку. | ||
Чтобы облегчить процесс получения токена, в данный пакет встроен OAuth-сервер, | ||
который может обрабатывать указанный адрес перенаправления. | ||
который может обрабатывать указанный адрес перенаправления. Сервер включает прослушивание по необходимости | ||
и закрывает соединение по получению кода авторизации. | ||
@@ -76,5 +102,3 @@ Пример настройки без параметра *code*: | ||
```js | ||
const AmoCRM = require( 'amocrm-js' ); | ||
const crm = new AmoCRM({ | ||
const client = new Client({ | ||
// логин пользователя в портале, где адрес портала domain.amocrm.ru | ||
@@ -98,5 +122,5 @@ domain: 'domain', // может быть указан полный домен вида domain.amocrm.ru, domain.amocrm.com | ||
Как выглядит процесс авторизации: | ||
#### Процесс авторизации: | ||
1. Сервер ожидает перехода пользователя по адресу: *crm.connection.getAuthUrl(mode)* | ||
1. Сервер ожидает перехода пользователя по адресу: *crm.auth.getUrl(mode)* | ||
2. При успешном переходе пользователь перенаправляется на {redirectUri}, заданный в интеграции | ||
@@ -113,25 +137,4 @@ 3. Сервер авторизации перехватывает запрос на {redirectUri} | ||
После установки пакета: | ||
[Пример использования ngrok.](./examples/javascript/01-get-development-token.js) | ||
1. Выполните в терминале команду: ```ngrok http 3001``` | ||
2. Полученный в результат адрес вида https://311e923c5281.ngrok.io указываем в настройках интеграции AmoCRM | ||
3. В настройках указываем номер порта (в нашем примере 3001) и полученный ngrok-адрес в {auth.redirect_uri} | ||
4. Получаем адрес ссылке, по которой необходимо будет перейти через *crm.connection.getAuthUrl()* | ||
5. Переходим по ссылке, после этого код автоматически установится и библиотека запросит новый токен | ||
Пример настроек: | ||
```js | ||
const crm = new AmoCRM({ | ||
// ... | ||
auth: { | ||
// ... | ||
redirect_uri: 'https://311e923c5281.ngrok.io', | ||
server: { | ||
port: 3001 | ||
} | ||
}, | ||
}); | ||
``` | ||
#### Разработка на production-сервере | ||
@@ -148,2 +151,15 @@ | ||
```js | ||
const client = new Client({ | ||
// ... | ||
auth: { | ||
// ... | ||
redirect_uri: 'redirectUri', | ||
server: { | ||
port: 3001 | ||
} | ||
}, | ||
}); | ||
``` | ||
## Запросы к порталу | ||
@@ -154,129 +170,276 @@ | ||
```js | ||
const response = await crm.request( 'GET', '/api/v4/account' ); | ||
const result = await client.request.make( 'GET', '/api/v4/account' ); | ||
// возвращает тело ответа | ||
console.log( response.data ); | ||
console.log(result.data); | ||
/* | ||
Возвращает расширенную информацию об ответе - | ||
экземпляр http.ServerResponse: | ||
https://nodejs.org/api/http.html#http_class_http_serverresponse | ||
экземпляр http.IncomingMessage: | ||
https://nodejs.org/api/http.html#class-httpincomingmessage | ||
*/ | ||
console.log( response.info ); | ||
console.log(result.response); | ||
// к примеру, HTTP-статус ответа операции | ||
console.log( response.info.statusCode ); | ||
console.log(result.response.statusCode); | ||
``` | ||
Методы *crm.request*: get, post, patch | ||
## Методы *client.request*: get, post, patch | ||
### GET | ||
```js | ||
const response = await crm.request.get( '/api/v4/contacts') | ||
const response = await client.request.get('/api/v4/contacts') | ||
``` | ||
#### Передача параметров | ||
С помощью querystring: | ||
```js | ||
const response = await crm.request | ||
.post( '/api/v4/contacts', | ||
[ | ||
{ | ||
name: "Walter White", | ||
request_id: 143, | ||
// другие поля ... | ||
} | ||
] | ||
) | ||
const response = await client.request.get('/api/v4/contacts?with=version'); | ||
``` | ||
объектом: | ||
```js | ||
const response = await crm.request | ||
.patch( '/api/v4/leads', | ||
[ | ||
{ | ||
"id": 54886, | ||
"pipeline_id": 47521, | ||
"status_id": 143, | ||
"date_close": 1589297221, | ||
"loss_reason_id": 7323, | ||
"updated_by": 0 | ||
} | ||
] | ||
) | ||
const response = await client.request.get('/api/v4/contacts', { | ||
with: 'version' | ||
}); | ||
``` | ||
### POST | ||
```js | ||
const response = await client.request.post('/api/v4/contacts', [ | ||
{ | ||
name: "Walter White", | ||
request_id: 143, | ||
// другие поля ... | ||
} | ||
] | ||
); | ||
``` | ||
### PATCH | ||
```js | ||
const response = await client.request.patch( '/api/v4/leads', [ | ||
{ | ||
"id": 54886, | ||
"pipeline_id": 47521, | ||
"status_id": 143, | ||
"date_close": 1589297221, | ||
"loss_reason_id": 7323, | ||
"updated_by": 0 | ||
} | ||
] | ||
) | ||
``` | ||
## OAuth | ||
Клиент автоматически получает новый токен по истечению | ||
старого (при необходимости). | ||
Методы: | ||
1. *crm.connection.setCode(code)* - устанавливает код авторизации | ||
и получает токен авторизации. | ||
2. *crm.connection.refreshToken()* - получает новый токен | ||
на основе текущего (по полю *refresh_token*). | ||
Вызывается автоматически при необходимости обновления. | ||
3. *crm.connection.getAuthUrl(mode)* - возвращает адрес ссылки, по которой должен перейти пользователь. | ||
Параметр mode отвечает за обработку запроса на Redirect URI. | ||
В случае popup – окно авторизации будет закрыто, а переход на Redirect URI будет выполнен в основном окне. | ||
В случае передачи значения post_message – перенаправление произойдет в окне, которое было открыто, после обработки кода авторизации вам нужно закрыть окно | ||
4. *crm.connection.setState(state)* - задаёт произвольную строку состояния | ||
(используется для проверки подлинности во встроенном сервере авторизации) | ||
5. *crm.connection.getState(state)* - возвращает строку состояния | ||
6. *crm.connection.getToken()* - возвращает текущий токен авторизации | ||
7. *crm.connection.setToken( token )* - задаёт токен авторизации. Токен должен включать поле expires_at (timestamp, когда токен истечёт) | ||
## Работа с событиями | ||
Клиент автоматически получает новый токен по истечению старого перед формированием запроса | ||
В настоящий момент доступны следующие события: | ||
## Компоненты | ||
1. connection:beforeConnect | ||
2. connection:beforeFetchToken | ||
3. connection:beforeRefreshToken | ||
4. connection:checkToken | ||
5. connection:authError | ||
6. connection:connected | ||
7. connection:error | ||
8. connection:newToken | ||
### client.environment | ||
Добавление обработчика: | ||
В нём хранятся все переданные ранее настройки | ||
```javascript | ||
crm.on( 'connection:error', () => console.log( 'Ошибка соединения' )); | ||
#### client.environment.get(path?) | ||
Получить настройки, переданные конструктору Client | ||
```js | ||
const Client = require('amocrm-js'); | ||
const client = new Client({ | ||
// логин пользователя в портале, где адрес портала domain.amocrm.ru | ||
domain: 'domain', // может быть указан полный домен вида domain.amocrm.ru, domain.amocrm.com | ||
/* | ||
Информация об интеграции (подробности подключения | ||
описаны на https://www.amocrm.ru/developers/content/oauth/step-by-step) | ||
*/ | ||
auth: { | ||
client_id: 'clientId', // ID интеграции | ||
client_secret: 'clientSecret', // Секретный ключ | ||
redirect_uri: 'redirectUri', // Ссылка для перенаправления | ||
code: 'code', // Код для упрощённой авторизации, необязательный | ||
/* | ||
Параметр состояния для проверки на корректность. Необязательный. Используется встроенным сервером авторизации | ||
см. https://www.amocrm.ru/developers/content/oauth/step-by-step#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-Authorization-code | ||
*/ | ||
state: 'state', | ||
}, | ||
}); | ||
client.environment.get(); // возвращает весь объект настроек | ||
client.environment.get('domain'); // 'domain'; | ||
client.environment.get('auth.redirect_uri'); // 'redirectUri' | ||
``` | ||
Удаление обработчика: | ||
#### client.environment.set(path, value) | ||
```javascript | ||
const handler = () => console.log( 'Ошибка соединения' ); | ||
crm.on( 'connection:error', handler ); | ||
Устанавливает новое значение в окружении | ||
// удалить конкретный обработчик | ||
crm.off( 'connection:error', handler ); | ||
```js | ||
client.environment.set('auth.state', 'newsState'); | ||
``` | ||
// удалить все обработчики конкретного события | ||
crm.off( 'connection:error' ); | ||
### client.connection | ||
// удалить все обработчики всех событий | ||
crm.off(); | ||
#### client.connection.connect() | ||
Получает токен на основе (в зависимости от ситуации): | ||
1. Кода авторизации (config.auth.code) | ||
2. Старого токена, если он истёк (refresh_token) | ||
3. Кода авторизации, полученного с помощью перехода пользователя по ссылке. Использует встроенный сервер авторизации | ||
#### client.connection.update() | ||
#### События | ||
- check. Проверка | ||
- beforeConnect. Возникает перед началом соединения | ||
- connected. Успешное соединение | ||
- connectionError. Ошибка соединения | ||
- authServer:code. Успешное получение кода авторизации | ||
- authServer:listen. Начало работы сервера авторизации | ||
- authServer:close. Сервер авторизации завершает прослушивать сооб | ||
- authServer:serverError. Ошибка сервера авторизации | ||
```js | ||
client.connection.on('connectionError', () => { | ||
console.error('Произошла ошибка соединения'); | ||
}) | ||
``` | ||
### Сохранение авторизации между сессиями | ||
### client.auth | ||
Может быть полезным сохранять авторизацию между запусками приложения. Для этого есть событие `connection:newToken`, в которое приходит новый токен при каждом сохранении. | ||
#### client.auth.getUrl(mode) | ||
Возвращает адрес ссылки на портал AmoCRM, по которой должен перейти пользователь для получения кода авторизации. | ||
Параметр mode отвечает за обработку запроса на Redirect URI. | ||
1. _popup_ – окно авторизации будет закрыто, а переход на Redirect URI будет выполнен в основном окне. | ||
2. _post_message_ – перенаправление произойдет в окне, которое было открыто, | ||
после обработки кода авторизации вам нужно закрыть окно | ||
#### client.auth.setCode(code) | ||
Устанавливает код авторизации и удаляет информацию о текущем токене. Желательно применять именно этот метод | ||
в сравнение с client.environment.set('auth.code'); | ||
### client.token | ||
#### client.token.setValue(value) | ||
Устанавливает новое значение токена. | ||
#### client.token.getValue() | ||
Возвращает текущее значение токена. | ||
#### client.token.refresh() | ||
Обновляет токен по значению refresh_token текущего. Явно вызывать нет необходимости, так как | ||
при каждом запросе идёт проверка токена на актуальность. Если время жизни токена истекло, этот метод | ||
будет вызван автоматически. | ||
После обновления, токен автоматически устанавливается в приложении. | ||
#### client.token.fetch() | ||
Получение токена по коду авторизации. После обновления, токен автоматически устанавливается в приложении. | ||
#### События | ||
- beforeChange. Возникает после получения по API токена и до того как он будет установлен в приложении | ||
- change. Возникает после установления нового значения в приложении | ||
- expirationCheck. Возникает при проверке актуальности токена | ||
- beforeFetch. Возникает перед попыткой получения токена по коду авторизации | ||
- fetch. Возникает после получения токена по коду авторизации | ||
- beforeRefresh. Возникает перед попыткой обновления токена по значению refresh_token текущего | ||
- refresh. Возникает после получения нового токена по значению refresh_token старого | ||
```js | ||
client.connection.on('change', () => { | ||
console.error('Произошла ошибка соединения'); | ||
}) | ||
``` | ||
## Работа с событиями | ||
Все компоненты приложения (auth, token, connection) унаследованы от класса | ||
[EventEmitter](https://nodejs.org/api/events.html). То есть они все поддерживают | ||
методы подписки на события (on, off, removeAllListeners) и отписки от них, принятые в EventEmitter. | ||
## Ошибки | ||
- NO_JSON_RESPONSE. Пустой ответ | ||
- INVALID_JSON_RESPONSE. Некорректный JSON вет | ||
- API_RESPONSE_ERROR. Ошибка в ответе по API | ||
- NO_TOKEN_AND_CODE. В настройках отсуствует код и не установлен токен | ||
- CONNECTION_ERROR. Неудачное соединение | ||
- NO_ENVIRONMENT_OPTIONS. Отсутствуют настройки | ||
- PATH_IS_EMPTY. Попытка установить client.environment.set без переданного первого пути | ||
- INVALID_PATH. Неверный | ||
- NO_AUTH_OPTIONS. Отсутствуют настройки config.auth | ||
## Сохранение авторизации между сессиями | ||
Может быть полезным сохранять авторизацию между запусками приложения. Для этого есть событие `change` | ||
компонента client.token, в которое приходит новый токен при каждом сохранении. | ||
Этот токен можно сохранять куда вам удобно (БД, файлы и тд). При инициализации соединения можно заранее установить токен для восстановления авторизации: | ||
`crm.connection.setToken( currentToken )` | ||
`crm.token.setValue(currentToken)` | ||
Ниже пример реализации через сохранение в файл token.json который лежит рядом со скриптом | ||
```javascript | ||
crm.on( 'connection:newToken', response => { | ||
fs.writeFileSync( './token.json', JSON.stringify( response.data )); | ||
```js | ||
client.connection.on('change', () => { | ||
const token = client.token.getValue(); | ||
fs.writeFileSync('./token.json', JSON.stringify(token)); | ||
}); | ||
try { | ||
const currentToken = require( './token.json' ); | ||
crm.connection.setToken( currentToken ); | ||
const currentToken = require('./token.json'); | ||
client.token.setValue(currentToken); | ||
} catch (e) { | ||
// Token file not found | ||
// Файл не найден | ||
} | ||
``` | ||
## Переход с версии 2.x.x | ||
### Методы | ||
- client.connect -> client.connection.connect | ||
- client.connection.getAuthUrl() -> client.auth.getUrl() | ||
- client.connection.setState(state) -> client.environment.set('auth.state', state) | ||
- client.connection.getState() -> client.environment.get('auth.state') | ||
- client.connection.getToken() -> client.token.getValue() | ||
- client.connection.setToken(token) -> client.token.setValue(token) | ||
- client.connection.refreshToken() -> client.token.refresh() | ||
#### client.connection.setCode(code) | ||
Замена: client.auth.setCode(code) | ||
Вызов этого метода в версии 2.x.x приводит к обновлению токена по только что заданному коду. | ||
В текущей версии это происходит при последующем запросе к API. Старая версия эквивалентна: | ||
```js | ||
client.auth.setCode(code); | ||
await client.connection.connect(); | ||
``` | ||
### События | ||
- client.on('connection:beforeConnect') -> client.connection.on('beforeConnect') | ||
- client.on('connection:beforeFetchToken') -> client.token.on('beforeFetch') | ||
- client.on('connection:beforeRefreshToken') -> client.token.on('beforeRefresh') | ||
- client.on('connection:checkToken') -> client.token.on('expirationCheck') | ||
- client.on('connection:authError') -> client.connection.on('connectionError') | ||
- client.on('connection:connected') -> client.connection.on('connected') | ||
- client.on('connection:error') -> client.connection.on('connectionError') | ||
- client.on('connection:newToken') -> client.token.on('change') | ||
## Доска почёта | ||
@@ -287,1 +450,6 @@ | ||
Отдельная благодарность @dmitrytemlead за возможность протестировать библиотеку в стороннем проекте | ||
## Сообщество | ||
По всем вопросам работы библиотеки, заходите в [чат проекта в Telegram](https://t.me/+QKoG6INanhIyYTAy). | ||
Сделаем вместе пространство уютным :) |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
444
3
128298
18
88
2250
+ Addedreflect-metadata@^0.1.13
+ Addedtypescript@^4.6.4
+ Addedreflect-metadata@0.1.14(transitive)
+ Addedtypescript@4.9.5(transitive)
- Removedpromise-queue@^2.2.5
- Removedxml2js@^0.4.19
- Removedpromise-queue@2.2.5(transitive)
- Removedsax@1.4.1(transitive)
- Removedxml2js@0.4.23(transitive)
- Removedxmlbuilder@11.0.1(transitive)
Updatedqs@^6.10.3