@pachca/cli 2026.10.0 → 2026.10.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/CHANGELOG.md +10 -0
- package/README.md +7 -5
- package/dist/base-command.js +12 -0
- package/dist/client.js +2 -1
- package/dist/commands/bots/create.js +1 -1
- package/dist/commands/bots/list-company.js +1 -1
- package/dist/commands/bots/list-events.js +1 -1
- package/dist/commands/bots/list-tokens.js +1 -1
- package/dist/commands/bots/list.js +2 -2
- package/dist/commands/bots/remove-avatar.js +42 -0
- package/dist/commands/bots/remove-event.js +1 -1
- package/dist/commands/bots/update-avatar.js +51 -0
- package/dist/commands/bots/update.js +4 -4
- package/dist/commands/chats/create.js +1 -0
- package/dist/commands/chats/download-export.js +1 -1
- package/dist/commands/chats/get.js +1 -1
- package/dist/commands/chats/list-company.js +1 -1
- package/dist/commands/chats/list.js +1 -1
- package/dist/commands/chats/mark-unread.js +1 -1
- package/dist/commands/chats/request-export.js +4 -2
- package/dist/commands/drafts/list.js +1 -1
- package/dist/commands/files/direct-url.js +8 -4
- package/dist/commands/group-tags/get.js +1 -1
- package/dist/commands/group-tags/list-users.js +2 -2
- package/dist/commands/group-tags/list.js +3 -3
- package/dist/commands/members/add.js +2 -2
- package/dist/commands/members/list.js +2 -2
- package/dist/commands/members/remove-group-tag.js +1 -1
- package/dist/commands/members/remove.js +1 -1
- package/dist/commands/members/update.js +1 -1
- package/dist/commands/messages/create.js +9 -10
- package/dist/commands/messages/get.js +1 -1
- package/dist/commands/messages/list.js +1 -1
- package/dist/commands/messages/update.js +1 -1
- package/dist/commands/profile/update-status.js +3 -32
- package/dist/commands/reactions/list.js +1 -1
- package/dist/commands/read-member/list-readers.js +1 -1
- package/dist/commands/search/list-chats.js +2 -2
- package/dist/commands/search/list-messages.js +6 -6
- package/dist/commands/search/list-users.js +4 -4
- package/dist/commands/security/list.js +1 -1
- package/dist/commands/tasks/get.js +1 -1
- package/dist/commands/tasks/list.js +5 -5
- package/dist/commands/threads/get.js +1 -1
- package/dist/commands/threads/list.js +2 -2
- package/dist/commands/upload.js +5 -2
- package/dist/commands/users/get.js +1 -1
- package/dist/commands/users/list.js +1 -1
- package/dist/commands/users/update-status.js +3 -32
- package/dist/commands/users/update.js +2 -2
- package/dist/commands/views/open.js +2 -2
- package/dist/data/alternatives.json +7 -5
- package/dist/data/changelog.json +41 -0
- package/dist/data/endpoints.json +1 -1
- package/dist/data/workflows.json +6 -6
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.10.1 (20 октября 2026)
|
|
4
|
+
|
|
5
|
+
- **Изменено** (chats request-export): Команда выводит номер выгрузки `id`: с ним `pachca chats download-export` забирает архив, когда тот соберётся
|
|
6
|
+
- **Добавлено** (chats create): Команда предупреждает в stderr об идентификаторах из `--member-ids`, которых не удалось добавить в чат
|
|
7
|
+
- **Добавлено** (bots update-avatar, bots remove-avatar): Новые команды — аватар бота: загрузка файла флагом `--file` и удаление
|
|
8
|
+
- **Добавлено** (bots get): В `webhook` приходят адрес входящего вебхука `url`, секрет подписи `secret_token` и тело последнего запроса `last_request_body`, если у токена есть скоуп `bots:write` и вы можете управлять токенами бота
|
|
9
|
+
- **Изменено** (messages create): Сообщение уходит без `--content`, если к нему приложены файлы
|
|
10
|
+
- **Изменено** (profile update-status, users update-status): `--emoji` и `--title` нужны, только когда статуса ещё нет — продлить статус можно одним `--expires-at`
|
|
11
|
+
- **Изменено** (upload, files direct-url): `pachca upload` передаёт в форме загрузки `acl` и `bucket`, только если они пришли, а у `pachca files direct-url` флаг `--acl` необязателен и есть флаг `--bucket`: в части пространств метод `Получение подписи, ключа и других параметров` отдаёт `bucket` вместо `acl`
|
|
12
|
+
|
|
3
13
|
## 2026.10.0 (13 октября 2026)
|
|
4
14
|
|
|
5
15
|
- **Добавлено** (bots list-tokens, bots create-token, bots update-token, bots reissue-token, bots delete-token): Новые команды — токены бота: у бота может быть несколько токенов, у каждого своё имя и права. Значение токена показывается один раз, при выпуске и перевыпуске.
|
package/README.md
CHANGED
|
@@ -85,6 +85,8 @@ pachca guide # список всех сценариев
|
|
|
85
85
|
| `pachca bots get` | Информация о боте |
|
|
86
86
|
| `pachca bots update` | Редактирование бота |
|
|
87
87
|
| `pachca bots delete` | Удаление бота |
|
|
88
|
+
| `pachca bots update-avatar` | Загрузка аватара бота |
|
|
89
|
+
| `pachca bots remove-avatar` | Удаление аватара бота |
|
|
88
90
|
| `pachca bots recreate-token` | Ротация токена бота |
|
|
89
91
|
| `pachca bots rotate-client-secret` | Ротация секрета клиента |
|
|
90
92
|
| `pachca bots list-scopes` | Каталог прав бота |
|
|
@@ -95,7 +97,7 @@ pachca guide # список всех сценариев
|
|
|
95
97
|
| `pachca bots reissue-token` | Перевыпуск токена бота |
|
|
96
98
|
| `pachca bots list-company` | Список ботов пространства |
|
|
97
99
|
| `pachca bots list-events` | История событий |
|
|
98
|
-
| `pachca bots remove-event` | Удаление события |
|
|
100
|
+
| `pachca bots remove-event` | Удаление события истории |
|
|
99
101
|
|
|
100
102
|
### chats
|
|
101
103
|
|
|
@@ -119,12 +121,12 @@ pachca guide # список всех сценариев
|
|
|
119
121
|
| Команда | Описание |
|
|
120
122
|
|---------|---------|
|
|
121
123
|
| `pachca members add-group-tags` | Добавление тегов |
|
|
122
|
-
| `pachca members remove-group-tag` | Исключение тега |
|
|
124
|
+
| `pachca members remove-group-tag` | Исключение тега из чата |
|
|
123
125
|
| `pachca members leave` | Выход из чата |
|
|
124
126
|
| `pachca members list` | Список участников чата |
|
|
125
|
-
| `pachca members add` | Добавление
|
|
126
|
-
| `pachca members remove` | Исключение
|
|
127
|
-
| `pachca members update` | Редактирование роли |
|
|
127
|
+
| `pachca members add` | Добавление участников |
|
|
128
|
+
| `pachca members remove` | Исключение участника |
|
|
129
|
+
| `pachca members update` | Редактирование роли участника |
|
|
128
130
|
|
|
129
131
|
### custom-properties
|
|
130
132
|
|
package/dist/base-command.js
CHANGED
|
@@ -209,6 +209,18 @@ export class BaseCommand extends Command {
|
|
|
209
209
|
}
|
|
210
210
|
outputData(data, opts);
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Warn about a non-empty list from the response `meta` (e.g. `not_found_member_ids`).
|
|
214
|
+
*
|
|
215
|
+
* stdout keeps printing only `data`, so `-o json` output keeps its shape. The list
|
|
216
|
+
* goes to stderr in every output mode, like the other `⚠` notices.
|
|
217
|
+
*/
|
|
218
|
+
warnMetaList(meta, field, message, hint) {
|
|
219
|
+
const value = meta && typeof meta === 'object' ? meta[field] : undefined;
|
|
220
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
221
|
+
return;
|
|
222
|
+
process.stderr.write(`⚠ ${message}: ${value.join(', ')}.\n ${hint}\n`);
|
|
223
|
+
}
|
|
212
224
|
/**
|
|
213
225
|
* Output a success message to stderr.
|
|
214
226
|
*/
|
package/dist/client.js
CHANGED
|
@@ -33,8 +33,9 @@ function buildUrl(apiPath, query) {
|
|
|
33
33
|
for (const [key, value] of Object.entries(query)) {
|
|
34
34
|
if (value !== undefined) {
|
|
35
35
|
if (Array.isArray(value)) {
|
|
36
|
+
// The key already carries the form the spec declares, `name[]` for a list.
|
|
36
37
|
for (const v of value) {
|
|
37
|
-
url.searchParams.append(
|
|
38
|
+
url.searchParams.append(key, String(v));
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
@@ -41,7 +41,7 @@ export default class BotsCreate extends BaseCommand {
|
|
|
41
41
|
description: "Шаблон форматирования входящего вебхука",
|
|
42
42
|
}),
|
|
43
43
|
'template-engine': Flags.string({
|
|
44
|
-
description: "Шаблонизатор для обработки шаблона входящего
|
|
44
|
+
description: "Шаблонизатор для обработки шаблона входящего вебхука. Без этого поля бот получает `liquid`, а пустой бот (`empty: true`) — `mustache`.",
|
|
45
45
|
}),
|
|
46
46
|
'challenge-key': Flags.string({
|
|
47
47
|
description: "Название поля проверки для верификации входящего вебхука",
|
|
@@ -52,7 +52,7 @@ export default class BotsListCompany extends BaseCommand {
|
|
|
52
52
|
const paginate = meta?.paginate;
|
|
53
53
|
nextCursor = paginate?.next_page;
|
|
54
54
|
pages++;
|
|
55
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
55
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
56
56
|
const hasNext = paginate?.has_next;
|
|
57
57
|
if (typeof hasNext === 'boolean') {
|
|
58
58
|
if (!hasNext)
|
|
@@ -47,7 +47,7 @@ export default class BotsListEvents extends BaseCommand {
|
|
|
47
47
|
const paginate = meta?.paginate;
|
|
48
48
|
nextCursor = paginate?.next_page;
|
|
49
49
|
pages++;
|
|
50
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
50
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
51
51
|
const hasNext = paginate?.has_next;
|
|
52
52
|
if (typeof hasNext === 'boolean') {
|
|
53
53
|
if (!hasNext)
|
|
@@ -49,7 +49,7 @@ export default class BotsListTokens extends BaseCommand {
|
|
|
49
49
|
const paginate = meta?.paginate;
|
|
50
50
|
nextCursor = paginate?.next_page;
|
|
51
51
|
pages++;
|
|
52
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
52
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
53
53
|
const hasNext = paginate?.has_next;
|
|
54
54
|
if (typeof hasNext === 'boolean') {
|
|
55
55
|
if (!hasNext)
|
|
@@ -4,7 +4,7 @@ import { BaseCommand } from '../../base-command.js';
|
|
|
4
4
|
export default class BotsList extends BaseCommand {
|
|
5
5
|
static description = "Список ботов";
|
|
6
6
|
static examples = [
|
|
7
|
-
"Найти и удалить бота — Пользовательским токеном (скоуп `bots:read`) получи список ботов, доступных тебе для редактирования: созданных тобой и тех, чьи настройки открывают тебе доступ. Фильтруй по имени параметром `query`, следующую страницу бери из `meta.paginate.next_page`:\n $ pachca bots list"
|
|
7
|
+
"Найти и удалить бота — Пользовательским токеном (скоуп `bots:read`) получи список ботов, доступных тебе для редактирования: созданных тобой и тех, чьи настройки открывают тебе доступ. Фильтруй по имени параметром `query`. Пока `meta.paginate.has_next` равен `true`, следующую страницу бери из `meta.paginate.next_page`:\n $ pachca bots list"
|
|
8
8
|
];
|
|
9
9
|
static scope = "bots:read";
|
|
10
10
|
static apiMethod = "GET";
|
|
@@ -51,7 +51,7 @@ export default class BotsList extends BaseCommand {
|
|
|
51
51
|
const paginate = meta?.paginate;
|
|
52
52
|
nextCursor = paginate?.next_page;
|
|
53
53
|
pages++;
|
|
54
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
54
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
55
55
|
const hasNext = paginate?.has_next;
|
|
56
56
|
if (typeof hasNext === 'boolean') {
|
|
57
57
|
if (!hasNext)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
import * as clack from '@clack/prompts';
|
|
5
|
+
export default class BotsRemoveAvatar extends BaseCommand {
|
|
6
|
+
static description = "Удаление аватара бота";
|
|
7
|
+
static scope = "bots:write";
|
|
8
|
+
static apiMethod = "DELETE";
|
|
9
|
+
static apiPath = "/bots/{id}/avatar";
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.integer({
|
|
12
|
+
description: "Идентификатор бота (pachca bots list)",
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
...BaseCommand.baseFlags,
|
|
18
|
+
force: Flags.boolean({
|
|
19
|
+
description: 'Пропустить подтверждение',
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
const { args, flags } = await this.parse(BotsRemoveAvatar);
|
|
25
|
+
this.parsedFlags = flags;
|
|
26
|
+
if (!flags.force) {
|
|
27
|
+
if (!this.isInteractive()) {
|
|
28
|
+
this.validationError([{ message: 'Деструктивная операция требует флага --force', flag: 'force' }], { type: 'PACHCA_DESTRUCTIVE_OP_ERROR', hint: "pachca bots remove-avatar <id> --force" });
|
|
29
|
+
}
|
|
30
|
+
const confirm = await clack.confirm({ message: 'Вы уверены?' });
|
|
31
|
+
if (clack.isCancel(confirm) || !confirm) {
|
|
32
|
+
process.stderr.write('Отменено.\n');
|
|
33
|
+
this.exit(0);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const { data } = await this.apiRequest({
|
|
37
|
+
method: 'DELETE',
|
|
38
|
+
path: `/bots/${args.id}/avatar`,
|
|
39
|
+
});
|
|
40
|
+
this.success('Удалено');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
export default class BotsRemoveEvent extends BaseCommand {
|
|
6
|
-
static description = "Удаление события";
|
|
6
|
+
static description = "Удаление события истории";
|
|
7
7
|
static examples = [
|
|
8
8
|
"Обработка событий через историю (polling) — Удали обработанное событие:\n $ pachca bots remove-event"
|
|
9
9
|
];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
export default class BotsUpdateAvatar extends BaseCommand {
|
|
7
|
+
static description = "Загрузка аватара бота";
|
|
8
|
+
static scope = "bots:write";
|
|
9
|
+
static apiMethod = "PUT";
|
|
10
|
+
static apiPath = "/bots/{id}/avatar";
|
|
11
|
+
static defaultColumns = ["image_url"];
|
|
12
|
+
static args = {
|
|
13
|
+
id: Args.integer({
|
|
14
|
+
description: "Идентификатор бота (pachca bots list)",
|
|
15
|
+
required: true,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
...BaseCommand.baseFlags,
|
|
20
|
+
file: Flags.string({
|
|
21
|
+
description: "Файл изображения для аватара",
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
async run() {
|
|
25
|
+
const { args, flags } = await this.parse(BotsUpdateAvatar);
|
|
26
|
+
this.parsedFlags = flags;
|
|
27
|
+
let formData;
|
|
28
|
+
if (flags.file) {
|
|
29
|
+
formData = new FormData();
|
|
30
|
+
if (flags.file === '-') {
|
|
31
|
+
const chunks = [];
|
|
32
|
+
for await (const chunk of process.stdin)
|
|
33
|
+
chunks.push(chunk);
|
|
34
|
+
const blob = new Blob([Buffer.concat(chunks)]);
|
|
35
|
+
formData.append('image', blob, 'stdin');
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const blob = new Blob([fs.readFileSync(flags.file)]);
|
|
39
|
+
formData.append('image', blob, path.basename(flags.file));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const { data } = await this.apiRequest({
|
|
43
|
+
method: 'PUT',
|
|
44
|
+
path: `/bots/${args.id}/avatar`,
|
|
45
|
+
formData,
|
|
46
|
+
});
|
|
47
|
+
const responseBody = (data ?? {});
|
|
48
|
+
const result = responseBody.data ?? responseBody;
|
|
49
|
+
this.output(result);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -30,7 +30,7 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
30
30
|
description: "URL исходящего вебхука",
|
|
31
31
|
}),
|
|
32
32
|
'events': Flags.string({
|
|
33
|
-
description: "События, на которые подписан
|
|
33
|
+
description: "События, на которые подписан бот. Список заменяется целиком.",
|
|
34
34
|
}),
|
|
35
35
|
'trigger-on': Flags.string({
|
|
36
36
|
description: "Условие срабатывания исходящего вебхука",
|
|
@@ -66,7 +66,7 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
66
66
|
description: "Кто может добавлять бота в чаты",
|
|
67
67
|
}),
|
|
68
68
|
'can-edit': Flags.string({
|
|
69
|
-
description: "Роли, которым, помимо создателя, разрешено редактировать настройки бота. Создатель может редактировать всегда. Пустой массив — редактировать может только создатель.",
|
|
69
|
+
description: "Роли, которым, помимо создателя, разрешено редактировать настройки бота. Создатель может редактировать всегда. Пустой массив — редактировать может только создатель. Список заменяется целиком.",
|
|
70
70
|
}),
|
|
71
71
|
'single-chat': Flags.boolean({
|
|
72
72
|
description: "Ограничивает бота одной беседой или каналом: `true` — бота можно добавить только в один такой чат, `false` — в несколько. Личные чаты и треды в ограничение не входят.",
|
|
@@ -76,10 +76,10 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
76
76
|
description: "Источник входящего вебхука. Если у бота входящего вебхука не было, он включается.",
|
|
77
77
|
}),
|
|
78
78
|
'unfurl-domains': Flags.string({
|
|
79
|
-
description: "Домены, ссылки на которые бот разворачивает, не больше 5. Работают вместе с событием `message_link_shared`.",
|
|
79
|
+
description: "Домены, ссылки на которые бот разворачивает, не больше 5. Работают вместе с событием `message_link_shared`. Список заменяется целиком.",
|
|
80
80
|
}),
|
|
81
81
|
'oauth-client': Flags.string({
|
|
82
|
-
description: "Настройки авторизации от имени сотрудника. Если авторизация выключена, объект её включает, а `null` выключает: выданные сотрудниками авторизации отзываются, страница в витрине
|
|
82
|
+
description: "Настройки авторизации от имени сотрудника. Если авторизация выключена, объект её включает, а `null` выключает: выданные сотрудниками авторизации отзываются, страница в витрине удаляется, собственные токены бота продолжают работать.",
|
|
83
83
|
}),
|
|
84
84
|
'promo': Flags.string({
|
|
85
85
|
description: "Страница бота в витрине. Доступна, только когда у бота включена авторизация.",
|
|
@@ -91,5 +91,6 @@ export default class ChatsCreate extends BaseCommand {
|
|
|
91
91
|
const responseBody = (data ?? {});
|
|
92
92
|
const result = responseBody.data ?? responseBody;
|
|
93
93
|
this.output(result);
|
|
94
|
+
this.warnMetaList(responseBody.meta, "not_found_member_ids", "Не удалось добавить в чат", "Таких сотрудников нет в пространстве, либо они приостановлены или удалены.");
|
|
94
95
|
}
|
|
95
96
|
}
|
|
@@ -15,7 +15,7 @@ export default class ChatsDownloadExport extends BaseCommand {
|
|
|
15
15
|
static apiPath = "/chats/exports/{id}";
|
|
16
16
|
static args = {
|
|
17
17
|
id: Args.integer({
|
|
18
|
-
description: "Идентификатор
|
|
18
|
+
description: "Идентификатор экспорта: `export_id` из вебхука о готовом архиве или число из ссылки вида `/full_exports/{id}` в уведомлении в Пачке (pachca chats list)",
|
|
19
19
|
required: true,
|
|
20
20
|
}),
|
|
21
21
|
};
|
|
@@ -9,7 +9,7 @@ export default class ChatsGet extends BaseCommand {
|
|
|
9
9
|
static defaultColumns = ["id", "name", "created_at", "owner_id", "channel"];
|
|
10
10
|
static args = {
|
|
11
11
|
id: Args.integer({
|
|
12
|
-
description: "Идентификатор
|
|
12
|
+
description: "Идентификатор чата: в ссылке веб-приложения это число из пути `/chats/{id}` (pachca chats list)",
|
|
13
13
|
required: true,
|
|
14
14
|
}),
|
|
15
15
|
};
|
|
@@ -53,7 +53,7 @@ export default class ChatsListCompany extends BaseCommand {
|
|
|
53
53
|
const paginate = meta?.paginate;
|
|
54
54
|
nextCursor = paginate?.next_page;
|
|
55
55
|
pages++;
|
|
56
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
56
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
57
57
|
const hasNext = paginate?.has_next;
|
|
58
58
|
if (typeof hasNext === 'boolean') {
|
|
59
59
|
if (!hasNext)
|
|
@@ -86,7 +86,7 @@ export default class ChatsList extends BaseCommand {
|
|
|
86
86
|
const paginate = meta?.paginate;
|
|
87
87
|
nextCursor = paginate?.next_page;
|
|
88
88
|
pages++;
|
|
89
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
89
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
90
90
|
const hasNext = paginate?.has_next;
|
|
91
91
|
if (typeof hasNext === 'boolean') {
|
|
92
92
|
if (!hasNext)
|
|
@@ -8,7 +8,7 @@ export default class ChatsMarkUnread extends BaseCommand {
|
|
|
8
8
|
static apiPath = "/chats/{id}/unread";
|
|
9
9
|
static args = {
|
|
10
10
|
id: Args.integer({
|
|
11
|
-
description: "Идентификатор чата или треда (pachca chats list)",
|
|
11
|
+
description: "Идентификатор чата (беседы, канала, личного чата или чата треда) (pachca chats list)",
|
|
12
12
|
required: true,
|
|
13
13
|
}),
|
|
14
14
|
};
|
|
@@ -5,13 +5,14 @@ import * as clack from '@clack/prompts';
|
|
|
5
5
|
export default class ChatsRequestExport extends BaseCommand {
|
|
6
6
|
static description = "Экспорт сообщений";
|
|
7
7
|
static examples = [
|
|
8
|
-
"Экспорт истории чата — Запроси
|
|
8
|
+
"Экспорт истории чата — Запроси экспорт и возьми номер выгрузки из `data.id`:\n $ pachca chats request-export"
|
|
9
9
|
];
|
|
10
10
|
static hiddenAliases = ["common:request-export"];
|
|
11
11
|
static scope = "chat_exports:write";
|
|
12
12
|
static plan = "corporation";
|
|
13
13
|
static apiMethod = "POST";
|
|
14
14
|
static apiPath = "/chats/exports";
|
|
15
|
+
static defaultColumns = ["id"];
|
|
15
16
|
static requiredFlags = ["start-at", "end-at"];
|
|
16
17
|
static args = {};
|
|
17
18
|
static flags = {
|
|
@@ -23,7 +24,7 @@ export default class ChatsRequestExport extends BaseCommand {
|
|
|
23
24
|
description: "Дата окончания для экспорта в формате YYYY-MM-DD, включительно. Если прислать дату со временем, время молча отбрасывается.",
|
|
24
25
|
}),
|
|
25
26
|
'webhook-url': Flags.string({
|
|
26
|
-
description: "Адрес, на который придёт вебхук с номером готовой
|
|
27
|
+
description: "Адрес, на который придёт вебхук с номером готовой выгрузки, когда архив будет собран. Номер приходит в поле `export_id`, а всё тело вебхука описано в разделе [Экспорт](https://dev.pachca.com/guides/export).",
|
|
27
28
|
}),
|
|
28
29
|
'chat-ids': Flags.string({
|
|
29
30
|
description: "Массив идентификаторов чатов. Указывается, если нужно получить сообщения только некоторых чатов.",
|
|
@@ -79,6 +80,7 @@ export default class ChatsRequestExport extends BaseCommand {
|
|
|
79
80
|
method: 'POST',
|
|
80
81
|
path: '/chats/exports',
|
|
81
82
|
body,
|
|
83
|
+
headers: { "Prefer": "return=representation" },
|
|
82
84
|
});
|
|
83
85
|
const responseBody = (data ?? {});
|
|
84
86
|
const result = responseBody.data ?? responseBody;
|
|
@@ -59,7 +59,7 @@ export default class DraftsList extends BaseCommand {
|
|
|
59
59
|
const paginate = meta?.paginate;
|
|
60
60
|
nextCursor = paginate?.next_page;
|
|
61
61
|
pages++;
|
|
62
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
62
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
63
63
|
const hasNext = paginate?.has_next;
|
|
64
64
|
if (typeof hasNext === 'boolean') {
|
|
65
65
|
if (!hasNext)
|
|
@@ -9,7 +9,7 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
9
9
|
static hiddenAliases = ["common:direct-url"];
|
|
10
10
|
static apiMethod = "POST";
|
|
11
11
|
static apiPath = "/direct_url";
|
|
12
|
-
static requiredFlags = ["content-disposition", "
|
|
12
|
+
static requiredFlags = ["content-disposition", "policy", "x-amz-credential", "x-amz-algorithm", "x-amz-date", "x-amz-signature", "key"];
|
|
13
13
|
static args = {};
|
|
14
14
|
static flags = {
|
|
15
15
|
...BaseCommand.baseFlags,
|
|
@@ -21,7 +21,7 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
21
21
|
description: "Параметр Content-Disposition, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
|
|
22
22
|
}),
|
|
23
23
|
'acl': Flags.string({
|
|
24
|
-
description: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
|
|
24
|
+
description: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads). Передаётся, если пришёл в ответе.",
|
|
25
25
|
}),
|
|
26
26
|
'policy': Flags.string({
|
|
27
27
|
description: "Параметр policy, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
|
|
@@ -41,6 +41,9 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
41
41
|
'key': Flags.string({
|
|
42
42
|
description: "Параметр key, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)",
|
|
43
43
|
}),
|
|
44
|
+
'bucket': Flags.string({
|
|
45
|
+
description: "Параметр bucket, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads). Передаётся, если пришёл в ответе.",
|
|
46
|
+
}),
|
|
44
47
|
file: Flags.string({
|
|
45
48
|
description: "Файл для загрузки",
|
|
46
49
|
}),
|
|
@@ -50,7 +53,6 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
50
53
|
this.parsedFlags = flags;
|
|
51
54
|
const missingRequired = [
|
|
52
55
|
{ flag: 'content-disposition', label: "Параметр Content-Disposition, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
|
|
53
|
-
{ flag: 'acl', label: "Параметр acl, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
|
|
54
56
|
{ flag: 'policy', label: "Параметр policy, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
|
|
55
57
|
{ flag: 'x-amz-credential', label: "Параметр x-amz-credential, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
|
|
56
58
|
{ flag: 'x-amz-algorithm', label: "Параметр x-amz-algorithm, полученный в ответе на запрос [Получение подписи, ключа и других параметров](POST /uploads)", type: 'string' },
|
|
@@ -78,7 +80,7 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
else {
|
|
81
|
-
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --content-disposition <string>, --
|
|
83
|
+
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --content-disposition <string>, --policy <string>, --x-amz-credential <string>, --x-amz-algorithm <string>, --x-amz-date <string>, --x-amz-signature <string>, --key <string>. pachca introspect files direct-url" });
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
let formData;
|
|
@@ -100,6 +102,8 @@ export default class FilesDirectUrl extends BaseCommand {
|
|
|
100
102
|
formData.append('x-amz-signature', String(flags['x-amz-signature']));
|
|
101
103
|
if (flags['key'])
|
|
102
104
|
formData.append('key', String(flags['key']));
|
|
105
|
+
if (flags['bucket'])
|
|
106
|
+
formData.append('bucket', String(flags['bucket']));
|
|
103
107
|
if (flags.file === '-') {
|
|
104
108
|
const chunks = [];
|
|
105
109
|
for await (const chunk of process.stdin)
|
|
@@ -9,7 +9,7 @@ export default class GroupTagsGet extends BaseCommand {
|
|
|
9
9
|
static defaultColumns = ["id", "name", "users_count"];
|
|
10
10
|
static args = {
|
|
11
11
|
id: Args.integer({
|
|
12
|
-
description: "Идентификатор
|
|
12
|
+
description: "Идентификатор тега: в ссылке веб-приложения это число из параметра `tag_id`",
|
|
13
13
|
required: true,
|
|
14
14
|
}),
|
|
15
15
|
};
|
|
@@ -12,7 +12,7 @@ export default class GroupTagsListUsers extends BaseCommand {
|
|
|
12
12
|
static defaultColumns = ["id", "title", "first_name", "last_name", "email"];
|
|
13
13
|
static args = {
|
|
14
14
|
id: Args.integer({
|
|
15
|
-
description: "Идентификатор
|
|
15
|
+
description: "Идентификатор тега: в ссылке веб-приложения это число из параметра `tag_id`",
|
|
16
16
|
required: true,
|
|
17
17
|
}),
|
|
18
18
|
};
|
|
@@ -52,7 +52,7 @@ export default class GroupTagsListUsers extends BaseCommand {
|
|
|
52
52
|
const paginate = meta?.paginate;
|
|
53
53
|
nextCursor = paginate?.next_page;
|
|
54
54
|
pages++;
|
|
55
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
55
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
56
56
|
const hasNext = paginate?.has_next;
|
|
57
57
|
if (typeof hasNext === 'boolean') {
|
|
58
58
|
if (!hasNext)
|
|
@@ -38,7 +38,7 @@ export default class GroupTagsList extends BaseCommand {
|
|
|
38
38
|
const seenCursors = new Set();
|
|
39
39
|
while (pages < 500) {
|
|
40
40
|
const query = {
|
|
41
|
-
names: flags['names']?.split(','),
|
|
41
|
+
'names[]': flags['names']?.split(','),
|
|
42
42
|
limit: flags.limit,
|
|
43
43
|
cursor: nextCursor,
|
|
44
44
|
};
|
|
@@ -51,7 +51,7 @@ export default class GroupTagsList extends BaseCommand {
|
|
|
51
51
|
const paginate = meta?.paginate;
|
|
52
52
|
nextCursor = paginate?.next_page;
|
|
53
53
|
pages++;
|
|
54
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
54
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
55
55
|
const hasNext = paginate?.has_next;
|
|
56
56
|
if (typeof hasNext === 'boolean') {
|
|
57
57
|
if (!hasNext)
|
|
@@ -85,7 +85,7 @@ export default class GroupTagsList extends BaseCommand {
|
|
|
85
85
|
method: 'GET',
|
|
86
86
|
path: '/group_tags',
|
|
87
87
|
query: {
|
|
88
|
-
names: flags['names']?.split(','),
|
|
88
|
+
'names[]': flags['names']?.split(','),
|
|
89
89
|
limit: flags.limit,
|
|
90
90
|
cursor: flags.cursor,
|
|
91
91
|
},
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
export default class MembersAdd extends BaseCommand {
|
|
6
|
-
static description = "Добавление
|
|
6
|
+
static description = "Добавление участников";
|
|
7
7
|
static examples = [
|
|
8
8
|
"Подписаться на тред сообщения — Добавь бота в участники чата треда:\n $ pachca members add",
|
|
9
9
|
"Создать канал и пригласить участников — Или добавь участников позже:\n $ pachca members add",
|
|
@@ -25,7 +25,7 @@ export default class MembersAdd extends BaseCommand {
|
|
|
25
25
|
description: "Массив идентификаторов пользователей, которые станут участниками",
|
|
26
26
|
}),
|
|
27
27
|
'silent': Flags.boolean({
|
|
28
|
-
description: "
|
|
28
|
+
description: "При `true` в чат не приходит системное сообщение о добавлении, а добавленные сотрудники не получают письмо с приглашением. Сообщение бывает только в закрытой беседе, письмо — в беседах и каналах у тех, кто не отключил такие письма. В треде параметр ничего не меняет.",
|
|
29
29
|
allowNo: true,
|
|
30
30
|
}),
|
|
31
31
|
};
|
|
@@ -20,7 +20,7 @@ export default class MembersList extends BaseCommand {
|
|
|
20
20
|
static flags = {
|
|
21
21
|
...BaseCommand.baseFlags,
|
|
22
22
|
'role': Flags.string({
|
|
23
|
-
description: "Роль в
|
|
23
|
+
description: "Роль в чате. В канале пишут создатель, админы и редакторы, а участник там — подписчик.",
|
|
24
24
|
options: ["all", "owner", "admin", "editor", "member"],
|
|
25
25
|
default: "all",
|
|
26
26
|
}),
|
|
@@ -59,7 +59,7 @@ export default class MembersList extends BaseCommand {
|
|
|
59
59
|
const paginate = meta?.paginate;
|
|
60
60
|
nextCursor = paginate?.next_page;
|
|
61
61
|
pages++;
|
|
62
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
62
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
63
63
|
const hasNext = paginate?.has_next;
|
|
64
64
|
if (typeof hasNext === 'boolean') {
|
|
65
65
|
if (!hasNext)
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
export default class MembersRemoveGroupTag extends BaseCommand {
|
|
6
|
-
static description = "Исключение тега";
|
|
6
|
+
static description = "Исключение тега из чата";
|
|
7
7
|
static scope = "chat_members:write";
|
|
8
8
|
static apiMethod = "DELETE";
|
|
9
9
|
static apiPath = "/chats/{id}/group_tags/{tag_id}";
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
export default class MembersRemove extends BaseCommand {
|
|
6
|
-
static description = "Исключение
|
|
6
|
+
static description = "Исключение участника";
|
|
7
7
|
static examples = [
|
|
8
8
|
"Архивация и управление чатом — Удалить участника:\n $ pachca members remove"
|
|
9
9
|
];
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
4
|
import * as clack from '@clack/prompts';
|
|
5
5
|
export default class MembersUpdate extends BaseCommand {
|
|
6
|
-
static description = "Редактирование роли";
|
|
6
|
+
static description = "Редактирование роли участника";
|
|
7
7
|
static examples = [
|
|
8
8
|
"Архивация и управление чатом — Изменить роль участника:\n $ pachca members update"
|
|
9
9
|
];
|