@andrey4emk/npm-app-back-b24 3.9.0 → 4.0.1
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 +108 -4
- package/bitrix24/b24/facade.ts +14 -1
- package/bitrix24/b24/proxy.ts +51 -9
- package/bitrix24/b24/retry.ts +19 -6
- package/bitrix24/b24/tokens.ts +8 -6
- package/bitrix24/b24/types.ts +27 -0
- package/bitrix24/b24.ts +43 -12
- package/bitrix24/errTaskB24.ts +100 -6
- package/bitrix24/eventB24.ts +71 -35
- package/index.ts +4 -1
- package/package.json +17 -6
- package/sendMessage/chatApp.ts +101 -24
- package/sendMessage/smsgold.ts +11 -2
- package/sendMessage/wappi.ts +41 -15
package/sendMessage/smsgold.ts
CHANGED
|
@@ -27,6 +27,15 @@ interface SmsMessageData {
|
|
|
27
27
|
*/
|
|
28
28
|
const DEFAULT_UPLOAD_FOLDER_ID = 2792881;
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Файл, загруженный на диск Bitrix24 — то, что классу нужно от ответа
|
|
32
|
+
* `disk.folder.uploadfile`. Идентификатор портал отдаёт то строкой, то числом,
|
|
33
|
+
* и класс лишь передаёт его дальше в `disk.file.getExternalLink`
|
|
34
|
+
*/
|
|
35
|
+
interface UploadedFile {
|
|
36
|
+
ID: string | number;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
/** Результат отправки SMS */
|
|
31
40
|
interface SmsResult {
|
|
32
41
|
error: boolean;
|
|
@@ -175,7 +184,7 @@ export class Smsgold {
|
|
|
175
184
|
}
|
|
176
185
|
|
|
177
186
|
/** Загружает файл в папку Битрикс24 через метод disk.folder.uploadfile */
|
|
178
|
-
private async uploadFileInFolderB24(fileBuffer: Buffer, fileName: string): Promise<{ error: boolean; message?: string; data?:
|
|
187
|
+
private async uploadFileInFolderB24(fileBuffer: Buffer, fileName: string): Promise<{ error: boolean; message?: string; data?: UploadedFile }> {
|
|
179
188
|
try {
|
|
180
189
|
const base64File = fileBuffer.toString("base64");
|
|
181
190
|
|
|
@@ -185,7 +194,7 @@ export class Smsgold {
|
|
|
185
194
|
data: { NAME: fileName },
|
|
186
195
|
fileContent: [fileName, base64File],
|
|
187
196
|
});
|
|
188
|
-
const data = getResultData(res, "disk.folder.uploadfile");
|
|
197
|
+
const data = getResultData<UploadedFile>(res, "disk.folder.uploadfile");
|
|
189
198
|
return { error: false, data };
|
|
190
199
|
} catch (error: unknown) {
|
|
191
200
|
const errMsg = error instanceof Error ? error.message : String(error);
|
package/sendMessage/wappi.ts
CHANGED
|
@@ -25,11 +25,31 @@ interface WappiFileMessageData extends WappiMessageData {
|
|
|
25
25
|
fileName: string;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Ответ Wappi в той части, которую разбирает класс.
|
|
30
|
+
*
|
|
31
|
+
* Описан по фактически читаемым полям, а не по всему API. Поля `check` и `haveContact`
|
|
32
|
+
* в ответе Wappi отсутствуют — их дописывает сам класс в объект ответа, поэтому
|
|
33
|
+
* в интерфейсе они обязаны быть, иначе присваивание не пройдёт тайпчек
|
|
34
|
+
*/
|
|
35
|
+
interface WappiResponse {
|
|
36
|
+
status?: string;
|
|
37
|
+
detail?: string;
|
|
38
|
+
on_max?: boolean;
|
|
39
|
+
on_whatsapp?: boolean;
|
|
40
|
+
contact?: unknown;
|
|
41
|
+
/** Дописывается классом: номер пригоден для отправки */
|
|
42
|
+
check?: boolean;
|
|
43
|
+
/** Дописывается классом: контакт найден или создан */
|
|
44
|
+
haveContact?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
28
47
|
/** Стандартный результат операции */
|
|
29
48
|
interface WappiResult {
|
|
30
49
|
error: boolean;
|
|
31
50
|
message: string;
|
|
32
|
-
|
|
51
|
+
/** Ответ Wappi как есть — форму задаёт сервис, потребитель приводит сам */
|
|
52
|
+
data: unknown;
|
|
33
53
|
/**
|
|
34
54
|
* Ответа не дождались. Отличает «проверка сказала нет» от «проверки не было»:
|
|
35
55
|
* без этого признака вызывающий код принимает таймаут за отрицательный ответ.
|
|
@@ -93,7 +113,7 @@ export class Wappi {
|
|
|
93
113
|
url = `https://wappi.pro/maxapi/sync/message/send?${sendOpenLine}profile_id=${profile_id}`;
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
let data:
|
|
116
|
+
let data: WappiResponse;
|
|
97
117
|
try {
|
|
98
118
|
const res = await fetchWithTimeout(
|
|
99
119
|
url!,
|
|
@@ -110,7 +130,7 @@ export class Wappi {
|
|
|
110
130
|
},
|
|
111
131
|
FETCH_TIMEOUTS.send
|
|
112
132
|
);
|
|
113
|
-
data = await res.json();
|
|
133
|
+
data = (await res.json()) as WappiResponse;
|
|
114
134
|
} catch (error: unknown) {
|
|
115
135
|
// Метод исторически без try/catch — перехватываем только таймаут, который сами
|
|
116
136
|
// и вводим, чтобы не появился новый путь исключений там, где его сегодня нет.
|
|
@@ -202,7 +222,7 @@ export class Wappi {
|
|
|
202
222
|
url = `https://wappi.pro/maxapi/async/message/file/url/send?${sendOpenLine}profile_id=${profile_id}`;
|
|
203
223
|
}
|
|
204
224
|
|
|
205
|
-
let data:
|
|
225
|
+
let data: WappiResponse;
|
|
206
226
|
try {
|
|
207
227
|
// В теле уходит base64 файла — бюджет transfer, а не send
|
|
208
228
|
const res = await fetchWithTimeout(
|
|
@@ -223,7 +243,7 @@ export class Wappi {
|
|
|
223
243
|
},
|
|
224
244
|
FETCH_TIMEOUTS.transfer
|
|
225
245
|
);
|
|
226
|
-
data = await res.json();
|
|
246
|
+
data = (await res.json()) as WappiResponse;
|
|
227
247
|
} catch (error: unknown) {
|
|
228
248
|
// Перехватываем только таймаут, остальные ошибки ведут себя как раньше
|
|
229
249
|
if (!isTimeoutError(error)) throw error;
|
|
@@ -265,9 +285,14 @@ export class Wappi {
|
|
|
265
285
|
const contactCheck = await this.getContactTelegramWappi(phone);
|
|
266
286
|
|
|
267
287
|
// 2 Если существует, то номер в телеге есть, можем отправлять сообщение
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
288
|
+
// Приведение, а не проверка: `data` объявлен unknown только в публичном типе,
|
|
289
|
+
// внутри класса это всегда разобранный ответ Wappi. На ошибке там null,
|
|
290
|
+
// но до чтения поля не доходит — первым проверяется `!contactCheck.error`,
|
|
291
|
+
// порядок вычисления тот же, что и до 4.0.0
|
|
292
|
+
const contactData = contactCheck.data as WappiResponse;
|
|
293
|
+
if (!contactCheck.error && contactData.haveContact) {
|
|
294
|
+
contactData.check = true;
|
|
295
|
+
return { error: false, message: `Номер ${phone} проверен для мессенджера ${messangerType}`, data: contactData };
|
|
271
296
|
}
|
|
272
297
|
|
|
273
298
|
// Ответа не дождались — это не «контакта нет». Создавать контакт вслепую нельзя:
|
|
@@ -280,14 +305,15 @@ export class Wappi {
|
|
|
280
305
|
|
|
281
306
|
// 3 Если не существует, то номера в телеге нет, пробуем создать
|
|
282
307
|
const addContactResult = await this.addContactTelegramWappi(phone);
|
|
308
|
+
const addedData = addContactResult.data as WappiResponse;
|
|
283
309
|
|
|
284
310
|
if (!addContactResult.error) {
|
|
285
311
|
// Если получается создать, отправляем информацию
|
|
286
|
-
|
|
287
|
-
return { error: false, message: `Номер ${phone} успешно добавлен и проверен для мессенджера ${messangerType}`, data:
|
|
312
|
+
addedData.check = true;
|
|
313
|
+
return { error: false, message: `Номер ${phone} успешно добавлен и проверен для мессенджера ${messangerType}`, data: addedData };
|
|
288
314
|
}
|
|
289
315
|
// Если не получается, то отправляем информацию об ошибке
|
|
290
|
-
return { error: true, message: `Не удалось проверить и добавить номер ${phone} в Telegram: ${addContactResult.message}`, data:
|
|
316
|
+
return { error: true, message: `Не удалось проверить и добавить номер ${phone} в Telegram: ${addContactResult.message}`, data: addedData };
|
|
291
317
|
}
|
|
292
318
|
if (messangerType === "max") {
|
|
293
319
|
token = this.maxAuth.token;
|
|
@@ -295,7 +321,7 @@ export class Wappi {
|
|
|
295
321
|
url = `https://wappi.pro/maxapi/sync/contact/check?profile_id=${profile_id}&phone=${phone}`;
|
|
296
322
|
}
|
|
297
323
|
|
|
298
|
-
let data:
|
|
324
|
+
let data: WappiResponse;
|
|
299
325
|
try {
|
|
300
326
|
const res = await fetchWithTimeout(
|
|
301
327
|
url!,
|
|
@@ -308,7 +334,7 @@ export class Wappi {
|
|
|
308
334
|
},
|
|
309
335
|
FETCH_TIMEOUTS.api
|
|
310
336
|
);
|
|
311
|
-
data = await res.json();
|
|
337
|
+
data = (await res.json()) as WappiResponse;
|
|
312
338
|
} catch (error: unknown) {
|
|
313
339
|
// Перехватываем только таймаут, остальные ошибки ведут себя как раньше
|
|
314
340
|
if (!isTimeoutError(error)) throw error;
|
|
@@ -353,7 +379,7 @@ export class Wappi {
|
|
|
353
379
|
FETCH_TIMEOUTS.api
|
|
354
380
|
);
|
|
355
381
|
|
|
356
|
-
const data
|
|
382
|
+
const data = (await res.json()) as WappiResponse;
|
|
357
383
|
|
|
358
384
|
if (data.status !== "done") {
|
|
359
385
|
return { error: true, message: `Ошибка получения контакта ${phone} из Telegram`, data };
|
|
@@ -405,7 +431,7 @@ export class Wappi {
|
|
|
405
431
|
FETCH_TIMEOUTS.send
|
|
406
432
|
);
|
|
407
433
|
|
|
408
|
-
const data
|
|
434
|
+
const data = (await res.json()) as WappiResponse;
|
|
409
435
|
if (data.status !== "done") {
|
|
410
436
|
return { error: true, message: `Ошибка создания контакта ${phone} в Telegram`, data };
|
|
411
437
|
}
|