@andrey4emk/npm-app-back-b24 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -40
- package/b24.js +4 -5
- package/eventGet.js +122 -0
- package/index.js +3 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -5,83 +5,123 @@
|
|
|
5
5
|
## Установка
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @andrey4emk/npm-
|
|
8
|
+
npm install @andrey4emk/npm-app-back-b24
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Использование
|
|
12
12
|
|
|
13
13
|
```js
|
|
14
|
-
import { create, refresh, save } from "@andrey4emk/npm-
|
|
14
|
+
import { create, refresh, save, errTask, Event } from "@andrey4emk/npm-app-back-b24";
|
|
15
15
|
import { AuthB24Model } from "./models/AuthB24.js"; // пример модели
|
|
16
16
|
|
|
17
|
+
// OAuth функции
|
|
17
18
|
const b24Client = await create(AuthB24Model);
|
|
18
19
|
const refreshResult = await refresh(AuthB24Model);
|
|
19
20
|
|
|
20
21
|
app.post("/b24/auth", (req, res) => save(req, res, AuthB24Model));
|
|
22
|
+
|
|
23
|
+
// Создание служебной задачи при ошибке
|
|
24
|
+
await errTask(b24Client, {
|
|
25
|
+
title: "Ошибка синхронизации",
|
|
26
|
+
description: "Детали ошибки здесь",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Работа с событиями
|
|
30
|
+
const eventHandler = new Event(b24Client);
|
|
31
|
+
const events = await eventHandler.get("ONCRMDYNAMICITEMUPDATE_149");
|
|
21
32
|
```
|
|
22
33
|
|
|
23
34
|
## API
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
36
|
+
### OAuth функции
|
|
37
|
+
|
|
38
|
+
- **`create(AuthB24Model)`** — создаёт клиента `B24OAuth` с использованием сохранённых в БД токенов.
|
|
39
|
+
|
|
40
|
+
- Возвращает: промис с экземпляром `B24OAuth`, готовым к вызовам REST API.
|
|
41
|
+
|
|
42
|
+
- **`refresh(AuthB24Model)`** — продлевает токены через Bitrix24 и обновляет запись в БД.
|
|
43
|
+
|
|
44
|
+
- Возвращает: промис с объектом `{ error: boolean, message: string }`.
|
|
28
45
|
|
|
29
|
-
-
|
|
46
|
+
- **`save(req, res, AuthB24Model)`** — HTTP-обработчик для сохранения набора токенов из `req.body`.
|
|
47
|
+
- Возвращает: HTTP-ответ с JSON `{ status, message }` (код `201` при успехе, `400`/`500` при ошибках).
|
|
30
48
|
|
|
31
|
-
###
|
|
49
|
+
### Утилиты
|
|
32
50
|
|
|
33
|
-
-
|
|
34
|
-
- [`create`](b24.js) — промис с экземпляром `B24OAuth`, готовым к вызовам REST API.
|
|
35
|
-
- [`refresh`](b24.js) — промис с объектом `{ error: boolean, message: string }`, описывающим статус продления.
|
|
36
|
-
- [`save`](b24.js) — HTTP-ответ, отправляющий JSON `{ status, message }` с кодом `201` при успехе или `400/500` при ошибках.
|
|
37
|
-
- [`error`](b24.js) — промис с объектом `{ error: boolean, message: string, result? }`.
|
|
38
|
-
- В случае успеха возвращает `{ error: false, message: 'Задача создана в Битрикс24.', result }`, где `result` — ответ API `tasks.task.add`.
|
|
39
|
-
- Если задач уже больше или равно `maxTasks`, возвращает `{ error: false, message: 'Превышено максимальное количество задач...' }` и не создаёт новую задачу.
|
|
40
|
-
- В случае ошибки возвращает `{ error: true, message: 'Не удалось создать задачу в Битрикс24: <текст ошибки>' }`.
|
|
51
|
+
- **`errTask(b24, dataTask)`** — создаёт служебную задачу в Bitrix24 при ошибках/событиях.
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
- Сначала проверяет, сколько задач с таким `TITLE` уже создано (через `tasks.task.list`).
|
|
54
|
+
- Если их меньше чем `maxTasks`, создаёт новую задачу (`tasks.task.add`).
|
|
55
|
+
- Возвращает: промис с объектом `{ error: boolean, message: string, result? }`.
|
|
56
|
+
- При успехе: `{ error: false, message: 'Задача создана в Битрикс24.', result }` (где `result` — ответ API).
|
|
57
|
+
- Если превышен лимит: `{ error: false, message: 'Превышено максимальное количество задач...' }`.
|
|
58
|
+
- При ошибке: `{ error: true, message: 'Не удалось создать задачу в Битрикс24: <текст ошибки>' }`.
|
|
43
59
|
|
|
44
|
-
|
|
60
|
+
**Параметры `dataTask`:**
|
|
45
61
|
|
|
46
|
-
- `title` (string) — заголовок
|
|
62
|
+
- `title` (string, **обязательно**) — заголовок задачи.
|
|
47
63
|
- `description` (string) — описание (опционально).
|
|
48
64
|
- `createdBy` (number) — ID создателя (по умолчанию `138`).
|
|
49
65
|
- `responsibleId` (number) — ID ответственного (по умолчанию `1`).
|
|
50
|
-
- `deadline` (ISO string) —
|
|
51
|
-
- `groupId` (number|null) —
|
|
66
|
+
- `deadline` (ISO string) — дедлайн; если не задан, используется `DateTime.now().plus({ days: 1 })`.
|
|
67
|
+
- `groupId` (number|null) — группа (опционально).
|
|
52
68
|
- `accomplices` (array) — массив соисполнителей.
|
|
53
69
|
- `maxTasks` (number) — максимум существующих задач с таким названием (по умолчанию `100`).
|
|
54
70
|
- `entityTypeAbbr` (string) — код CRM сущности для `UF_CRM_TASK`.
|
|
55
71
|
|
|
56
|
-
|
|
72
|
+
### События
|
|
57
73
|
|
|
58
|
-
|
|
74
|
+
- **`Event`** — класс для работы с офлайн-событиями Bitrix24.
|
|
59
75
|
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
```js
|
|
77
|
+
const eventHandler = new Event(b24);
|
|
62
78
|
|
|
63
|
-
|
|
79
|
+
// Получить события
|
|
80
|
+
const { events } = await eventHandler.get("ONCRMDYNAMICITEMUPDATE_149");
|
|
81
|
+
// events: { processId, entitysId, arrMessageIdAndEntityId }
|
|
64
82
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `APP_B24_CLIENT_ID_DEV`, `APP_B24_CLIENT_SECRET_DEV`
|
|
68
|
-
- `APP_ENV` (`DEV` или иное значение)
|
|
83
|
+
// Очистить события
|
|
84
|
+
await eventHandler.clear(processId, messageId);
|
|
69
85
|
|
|
70
|
-
|
|
86
|
+
// Удалить messageId из массива
|
|
87
|
+
const updated = await eventHandler.deleteMessageId(entityId, arrMessageIdAndEntityId);
|
|
88
|
+
```
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
**Методы:**
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
- `get(eventName)` — получить события по названию. Возвращает `{ error, events }`.
|
|
93
|
+
- `clear(processId, messageId)` — очистить события. Возвращает `{ error }`.
|
|
94
|
+
- `deleteMessageId(entityId, arrMessageIdAndEntityId)` — удалить запись события из массива. Возвращает обновлённый массив.
|
|
75
95
|
|
|
76
|
-
|
|
77
|
-
- `APP_B24_CLIENT_ID`, `APP_B24_CLIENT_SECRET` — клиентские креденшелы для рабочего (production) приложения.
|
|
78
|
-
- `APP_B24_CLIENT_ID_DEV`, `APP_B24_CLIENT_SECRET_DEV` — креденшелы для DEV окружения, используются при `APP_ENV == 'DEV'`.
|
|
79
|
-
- `APP_ENV` — определяет, какие креденшелы использовать (например, `DEV`).
|
|
80
|
-
- `APP_NAME` — читабельное имя приложения, добавляется в описание задач, создаваемых функцией `error`.
|
|
96
|
+
## Переменные окружения
|
|
81
97
|
|
|
82
|
-
|
|
98
|
+
| Переменная | Назначение |
|
|
99
|
+
| --------------------------- | ------------------------------------------------------------- |
|
|
100
|
+
| `APP_B24_DOMEN` | Домен Bitrix24, для которого хранится запись авторизации в БД |
|
|
101
|
+
| `APP_B24_CLIENT_ID` | Client ID для production |
|
|
102
|
+
| `APP_B24_CLIENT_SECRET` | Client Secret для production |
|
|
103
|
+
| `APP_B24_CLIENT_ID_DEV` | Client ID для DEV окружения |
|
|
104
|
+
| `APP_B24_CLIENT_SECRET_DEV` | Client Secret для DEV окружения |
|
|
105
|
+
| `APP_ENV` | Определяет окружение (`DEV` или production) |
|
|
106
|
+
| `APP_NAME` | Название приложения (используется в описании задач) |
|
|
107
|
+
|
|
108
|
+
Пример `.env`:
|
|
109
|
+
|
|
110
|
+
```env
|
|
111
|
+
APP_B24_DOMEN=mycompany.bitrix24.ru
|
|
112
|
+
APP_ENV=DEV
|
|
113
|
+
APP_B24_CLIENT_ID_DEV=xxx
|
|
114
|
+
APP_B24_CLIENT_SECRET_DEV=yyy
|
|
115
|
+
APP_B24_CLIENT_ID=aaa
|
|
116
|
+
APP_B24_CLIENT_SECRET=bbb
|
|
117
|
+
APP_NAME=MyApp
|
|
118
|
+
```
|
|
83
119
|
|
|
84
120
|
## Скрипты
|
|
85
121
|
|
|
86
|
-
- `npm run test` — заглушка
|
|
87
|
-
- `npm run pack:dry` — предпросмотр содержимого
|
|
122
|
+
- `npm run test` — запуск тестов (заглушка).
|
|
123
|
+
- `npm run pack:dry` — предпросмотр содержимого пакета перед публикацией.
|
|
124
|
+
|
|
125
|
+
## Лицензия
|
|
126
|
+
|
|
127
|
+
MIT © 2025 andrey4emk
|
package/b24.js
CHANGED
|
@@ -5,7 +5,6 @@ import dotEnv from "dotenv";
|
|
|
5
5
|
dotEnv.config();
|
|
6
6
|
|
|
7
7
|
// Environment variables (copied here to make code easier to test/mocking)
|
|
8
|
-
// Сохраняем имена переменных точь-в-точь, но без process.env
|
|
9
8
|
const APP_B24_DOMEN = process.env.APP_B24_DOMEN;
|
|
10
9
|
const APP_ENV = process.env.APP_ENV;
|
|
11
10
|
const APP_B24_CLIENT_ID_DEV = process.env.APP_B24_CLIENT_ID_DEV;
|
|
@@ -94,9 +93,9 @@ export async function save(req, res, AuthB24Model) {
|
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
export async function
|
|
96
|
+
export async function errTask(b24, dataTask) {
|
|
98
97
|
try {
|
|
99
|
-
let appName =
|
|
98
|
+
let appName = APP_NAME || "Задай название приложения в .env";
|
|
100
99
|
let title = dataTask.title;
|
|
101
100
|
let description = dataTask.description || "";
|
|
102
101
|
let createdBy = dataTask.createdBy || 138;
|
|
@@ -107,7 +106,7 @@ export async function error({ dataTask, $b24 }) {
|
|
|
107
106
|
let maxTasks = dataTask.maxTasks || 100;
|
|
108
107
|
let entityTypeAbbr = dataTask.entityTypeAbbr || "";
|
|
109
108
|
// Проверяем сколько создано таких задач. Если их уже больше 10, то не создаем новую
|
|
110
|
-
let resTasks = await
|
|
109
|
+
let resTasks = await b24.callMethod("tasks.task.list", {
|
|
111
110
|
filter: {
|
|
112
111
|
TITLE: title,
|
|
113
112
|
"<STATUS": 4,
|
|
@@ -120,7 +119,7 @@ export async function error({ dataTask, $b24 }) {
|
|
|
120
119
|
return { error: false, message: `Превышено максимальное количество задач с таким названием (${maxTasks}). Новая задача не создана.` };
|
|
121
120
|
} else {
|
|
122
121
|
// Создаем задачу в б24 на проверить. Если не смогли получить события
|
|
123
|
-
let resCreateTask = await
|
|
122
|
+
let resCreateTask = await b24.callMethod("tasks.task.add", {
|
|
124
123
|
fields: {
|
|
125
124
|
TITLE: title,
|
|
126
125
|
DESCRIPTION: `${appName} \n\n ${description}`,
|
package/eventGet.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Как использовать:
|
|
3
|
+
import { Event } from "@andrey4emk/npm-app-back-b24";
|
|
4
|
+
const event = new Event($b24); // $b24 — ваш экземпляр SDK
|
|
5
|
+
await event.get('ONCRMDYNAMICITEMUPDATE_149');
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class Event {
|
|
9
|
+
constructor(b24) {
|
|
10
|
+
if (!b24 || typeof b24.callMethod !== "function") {
|
|
11
|
+
throw new Error("Event: передали херовый b24 или не передали вообще");
|
|
12
|
+
}
|
|
13
|
+
this.b24 = b24;
|
|
14
|
+
}
|
|
15
|
+
async get(eventName) {
|
|
16
|
+
//Переменные
|
|
17
|
+
let events = {
|
|
18
|
+
processId: null,
|
|
19
|
+
entitysId: [],
|
|
20
|
+
arrMessageIdAndEntityId: [],
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Запрашиваем офлайн события сделок через API Bitrix24
|
|
25
|
+
let arrOfflineEvents = await this.b24.callMethod("event.offline.get", {
|
|
26
|
+
clear: 0,
|
|
27
|
+
filter: { EVENT_NAME: eventName },
|
|
28
|
+
// auth_connector: "change_entity_app",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Очищаем сразу события, у которых EVENT_ADDITIONAL: { user_id: '138' }, их не обрабатываем
|
|
32
|
+
let arrEventsToClear = arrOfflineEvents.result.events.filter((event) => event.EVENT_ADDITIONAL.user_id === "138");
|
|
33
|
+
if (arrEventsToClear.length > 0) {
|
|
34
|
+
let arrMessageIdToClear = arrEventsToClear.map((event) => event.MESSAGE_ID);
|
|
35
|
+
let resEventClear = await this.b24.callMethod("event.offline.clear", {
|
|
36
|
+
process_id: arrOfflineEvents.result.process_id,
|
|
37
|
+
message_id: arrMessageIdToClear,
|
|
38
|
+
});
|
|
39
|
+
// Удаляем эти события из основного массива arrOfflineEvents.result.events
|
|
40
|
+
arrOfflineEvents.result.events = arrOfflineEvents.result.events.filter((event) => event.EVENT_ADDITIONAL.user_id !== "138");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (arrOfflineEvents.result.events.length > 0) {
|
|
44
|
+
events.processId = arrOfflineEvents.result.process_id;
|
|
45
|
+
events.entitysId = arrOfflineEvents.result.events.map((event) => event.EVENT_DATA.FIELDS.ID);
|
|
46
|
+
events.arrMessageIdAndEntityId = arrOfflineEvents.result.events.map((event) => ({
|
|
47
|
+
messageId: event.MESSAGE_ID,
|
|
48
|
+
entityId: event.EVENT_DATA.FIELDS.ID,
|
|
49
|
+
}));
|
|
50
|
+
} else {
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Возвращаем очищенный результат
|
|
54
|
+
return { error: false, events: events };
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return { error: true, status: "error", message: `Не удалось получить события. ${error}` };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async clear(processId, messageId) {
|
|
61
|
+
try {
|
|
62
|
+
// Очищаем офлайн события сделок через API Bitrix24
|
|
63
|
+
let resEventClear = await this.b24.callMethod("event.offline.clear", {
|
|
64
|
+
process_id: processId,
|
|
65
|
+
message_id: messageId,
|
|
66
|
+
});
|
|
67
|
+
return { error: false };
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return { error: true, status: "error", message: `Не удалось очистить события. ${error}` };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async deleteMessageId(entityId, arrMessageIdAndEntityId) {
|
|
73
|
+
try {
|
|
74
|
+
// Находим в массиве arrMessageIdAndEntityId объект с нужным entityId и удаляем целиком этот объект из массива
|
|
75
|
+
let index = arrMessageIdAndEntityId.findIndex((item) => item.entityId === entityId);
|
|
76
|
+
if (index !== -1) {
|
|
77
|
+
arrMessageIdAndEntityId.splice(index, 1);
|
|
78
|
+
}
|
|
79
|
+
return arrMessageIdAndEntityId;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return { error: true, status: "error", message: `Не удалось удалить messageId. ${error}` };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const event = new Event();
|
|
87
|
+
|
|
88
|
+
// Как выглядит оффлайн событие
|
|
89
|
+
|
|
90
|
+
// {
|
|
91
|
+
// result: {
|
|
92
|
+
// process_id: '9bjf3j8mhfw40xisspvurxfnd0yvja97',
|
|
93
|
+
// events: [
|
|
94
|
+
// {
|
|
95
|
+
// ID: '81307763',
|
|
96
|
+
// TIMESTAMP_X: '2025-09-13T10:54:04+03:00',
|
|
97
|
+
// EVENT_NAME: 'ONCRMDYNAMICITEMUPDATE_149',
|
|
98
|
+
// EVENT_DATA: { FIELDS: { ID: 959, ENTITY_TYPE_ID: 149 } },
|
|
99
|
+
// EVENT_ADDITIONAL: { user_id: '1' },
|
|
100
|
+
// MESSAGE_ID: '892acbbb5d7a6aad30f5c670a65bcabc'
|
|
101
|
+
// },
|
|
102
|
+
// {
|
|
103
|
+
// ID: '81307739',
|
|
104
|
+
// TIMESTAMP_X: '2025-09-13T10:54:16+03:00',
|
|
105
|
+
// EVENT_NAME: 'ONCRMDYNAMICITEMUPDATE_149',
|
|
106
|
+
// EVENT_DATA: { FIELDS: { ID: 957, ENTITY_TYPE_ID: 149 } },
|
|
107
|
+
// EVENT_ADDITIONAL: { user_id: '138' },
|
|
108
|
+
// MESSAGE_ID: '7cf5d29bee90cc37382a9fff07fc2a43'
|
|
109
|
+
// }
|
|
110
|
+
// ]
|
|
111
|
+
// },
|
|
112
|
+
// time: {
|
|
113
|
+
// start: 1757750082.536543,
|
|
114
|
+
// finish: 1757750082.626707,
|
|
115
|
+
// duration: 0.0901641845703125,
|
|
116
|
+
// processing: 0.0034630298614501953,
|
|
117
|
+
// date_start: '2025-09-13T10:54:42+03:00',
|
|
118
|
+
// date_finish: '2025-09-13T10:54:42+03:00',
|
|
119
|
+
// operating_reset_at: 1757750682,
|
|
120
|
+
// operating: 0
|
|
121
|
+
// }
|
|
122
|
+
// }
|
package/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrey4emk/npm-app-back-b24",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Bitrix24 OAuth helpers for Node.js projects",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "echo \"No tests\" && exit 0",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/andrey4emk/npm_appBackB24#readme",
|
|
22
22
|
"files": [
|
|
23
|
-
"
|
|
23
|
+
"index.js",
|
|
24
|
+
"b24.js",
|
|
25
|
+
"eventGet.js"
|
|
24
26
|
],
|
|
25
27
|
"dependencies": {
|
|
26
28
|
"@bitrix24/b24jssdk": "^0.5.1",
|