@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
|
@@ -13,7 +13,7 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
13
13
|
static apiMethod = "POST";
|
|
14
14
|
static apiPath = "/messages";
|
|
15
15
|
static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
|
|
16
|
-
static requiredFlags = ["entity-id"
|
|
16
|
+
static requiredFlags = ["entity-id"];
|
|
17
17
|
static args = {};
|
|
18
18
|
static flags = {
|
|
19
19
|
...BaseCommand.baseFlags,
|
|
@@ -21,28 +21,28 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
21
21
|
description: "Тип сущности. Регистр значения не учитывается. Значение вне списка возвращает `400` с кодом `invalid`.",
|
|
22
22
|
}),
|
|
23
23
|
'entity-id': Flags.integer({
|
|
24
|
-
description: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо
|
|
24
|
+
description: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо пользователя. У треда их два: `id` треда указывают с `entity_type: \"thread\"`, а его `chat_id` — с `discussion`, как у любого чата. (pachca chats list | pachca users list)",
|
|
25
25
|
}),
|
|
26
26
|
'content': Flags.string({
|
|
27
|
-
description: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт.",
|
|
27
|
+
description: "Текст сообщения. Обязателен, если к сообщению не приложены файлы. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). `@all` упоминает всех участников чата, `@here` — тех, кто сейчас в сети, а `@` с названием тега без пробелов — сотрудников этого тега. Имя без `@` и упоминание внутри строчного кода или блока кода упоминанием не считаются. У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт. Сообщение уходит под именем владельца токена, у бота — с бейджем «Бот».",
|
|
28
28
|
}),
|
|
29
29
|
'files': Flags.string({
|
|
30
30
|
description: "Прикрепляемые файлы",
|
|
31
31
|
}),
|
|
32
32
|
'buttons': Flags.string({
|
|
33
|
-
description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке.",
|
|
33
|
+
description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке. Кнопки показываются под текстом и работают только у сообщений, отправленных токеном бота: нажатие на кнопку с `data` приходит событием `button_click` тому самому боту, а вместе с ним `trigger_id` — на открытие формы по нему есть 3 секунды, метод [Открытие представления](POST /views/open). Кнопка с `url` просто ведёт по ссылке и события не создаёт. Подробности — в разделе [Кнопки](https://dev.pachca.com/guides/buttons).",
|
|
34
34
|
}),
|
|
35
35
|
'parent-message-id': Flags.integer({
|
|
36
|
-
description: "Идентификатор сообщения, на которое вы отвечаете с цитатой. Ответить можно на сообщение в любом чате, в том числе в треде: ответ отправляют в тот же чат или тред, где лежит это сообщение, иначе запрос вернёт ошибку `422`. Чтобы написать в тред под сообщением, укажите `entity_type: \"thread\"` и
|
|
36
|
+
description: "Идентификатор сообщения, на которое вы отвечаете с цитатой. Ответить можно на сообщение в любом чате, в том числе в треде: ответ отправляют в тот же чат или тред, где лежит это сообщение, иначе запрос вернёт ошибку `422`. Чтобы написать в тред под сообщением, укажите `entity_type: \"thread\"` и `id` треда в `entity_id`.",
|
|
37
37
|
}),
|
|
38
38
|
'display-avatar-url': Flags.string({
|
|
39
39
|
description: "Ссылка на специальную аватарку отправителя для этого сообщения. Использование этого поля возможно только с access_token бота. (макс. 255 символов)",
|
|
40
40
|
}),
|
|
41
41
|
'display-name': Flags.string({
|
|
42
|
-
description: "Полное специальное имя отправителя для этого сообщения.
|
|
42
|
+
description: "Полное специальное имя отправителя для этого сообщения. Вместе с `display_avatar_url` бот подписывает сообщение чужим именем и аватаром, и только это сообщение. Бейдж «Бот» остаётся, а в профиле отправителя видно настоящего бота. Так показывают автора из другой системы, когда переносят в Пачку чужую переписку. С личным токеном поле недоступно, ответ `403`. Подробности — в разделе [Боты](https://dev.pachca.com/guides/bots/overview). (макс. 255 символов)",
|
|
43
43
|
}),
|
|
44
44
|
'skip-invite-mentions': Flags.boolean({
|
|
45
|
-
description: "Пропуск добавления
|
|
45
|
+
description: "Пропуск добавления упомянутых сотрудников в тред. В треде упоминание работает ещё и как приглашение: упомянутого сотрудника, которого в треде нет, Пачка туда добавляет, и он получает доступ к треду и родительскому сообщению. В беседе и канале упоминание никого не добавляет, и этот параметр там ничего не меняет.",
|
|
46
46
|
allowNo: true,
|
|
47
47
|
}),
|
|
48
48
|
'link-preview': Flags.boolean({
|
|
@@ -62,8 +62,7 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
62
62
|
flags['content'] = Buffer.concat(chunks).toString('utf-8').trimEnd();
|
|
63
63
|
}
|
|
64
64
|
const missingRequired = [
|
|
65
|
-
{ flag: 'entity-id', label: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо
|
|
66
|
-
{ flag: 'content', label: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт.", type: 'string' },
|
|
65
|
+
{ flag: 'entity-id', label: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо пользователя. У треда их два: `id` треда указывают с `entity_type: \"thread\"`, а его `chat_id` — с `discussion`, как у любого чата.", type: 'integer' },
|
|
67
66
|
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
68
67
|
if (missingRequired.length > 0) {
|
|
69
68
|
if (this.isInteractive()) {
|
|
@@ -85,7 +84,7 @@ export default class MessagesCreate extends BaseCommand {
|
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
else {
|
|
88
|
-
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-id <integer
|
|
87
|
+
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-id <integer>. pachca introspect messages create" });
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
const validationErrors = [];
|
|
@@ -14,7 +14,7 @@ export default class MessagesGet extends BaseCommand {
|
|
|
14
14
|
static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
|
|
15
15
|
static args = {
|
|
16
16
|
id: Args.integer({
|
|
17
|
-
description: "Идентификатор
|
|
17
|
+
description: "Идентификатор сообщения. Ссылка веб-приложения указывает на сообщение параметром `sidebar_message`, а без него — параметром `message`. Число из `thread_message_id` — сообщение, под которым висит тред. (pachca messages list)",
|
|
18
18
|
required: true,
|
|
19
19
|
}),
|
|
20
20
|
};
|
|
@@ -100,7 +100,7 @@ export default class MessagesList extends BaseCommand {
|
|
|
100
100
|
const paginate = meta?.paginate;
|
|
101
101
|
nextCursor = paginate?.next_page;
|
|
102
102
|
pages++;
|
|
103
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
103
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
104
104
|
const hasNext = paginate?.has_next;
|
|
105
105
|
if (typeof hasNext === 'boolean') {
|
|
106
106
|
if (!hasNext)
|
|
@@ -24,7 +24,7 @@ export default class MessagesUpdate extends BaseCommand {
|
|
|
24
24
|
description: "Текст сообщения. Поддерживает упоминания: `@nickname` или `<@user_id>` (будет автоматически преобразовано в `@nickname`). У мульти-гостя `<@user_id>` недоступного ему сотрудника остаётся в тексте как есть. До 40 000 байт в UTF-8, для кириллицы это около 20 000 символов. В пространстве с продвинутым шифрованием — до 27 000 байт.",
|
|
25
25
|
}),
|
|
26
26
|
'files': Flags.string({
|
|
27
|
-
description: "Прикрепляемые
|
|
27
|
+
description: "Прикрепляемые файлы. Переданный набор заменяет прежний: чтобы оставить уже приложенный файл, передайте его снова с тем же `key`.",
|
|
28
28
|
}),
|
|
29
29
|
'buttons': Flags.string({
|
|
30
30
|
description: "Массив строк, каждая из которых представлена массивом кнопок. Максимум 100 кнопок у сообщения, до 8 кнопок в строке. Для удаления кнопок пришлите пустой массив.",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
|
-
import * as clack from '@clack/prompts';
|
|
5
4
|
export default class ProfileUpdateStatus extends BaseCommand {
|
|
6
5
|
static description = "Новый свой статус";
|
|
7
6
|
static examples = [
|
|
@@ -11,18 +10,17 @@ export default class ProfileUpdateStatus extends BaseCommand {
|
|
|
11
10
|
static apiMethod = "PUT";
|
|
12
11
|
static apiPath = "/profile/status";
|
|
13
12
|
static defaultColumns = ["title", "emoji", "expires_at", "is_away"];
|
|
14
|
-
static requiredFlags = ["emoji", "title"];
|
|
15
13
|
static args = {};
|
|
16
14
|
static flags = {
|
|
17
15
|
...BaseCommand.baseFlags,
|
|
18
16
|
'emoji': Flags.string({
|
|
19
|
-
description: "Emoji символ статуса",
|
|
17
|
+
description: "Emoji символ статуса. Обязателен, если статуса ещё нет.",
|
|
20
18
|
}),
|
|
21
19
|
'title': Flags.string({
|
|
22
|
-
description: "Текст статуса (макс. 50 символов)",
|
|
20
|
+
description: "Текст статуса. Обязателен, если статуса ещё нет. (макс. 50 символов)",
|
|
23
21
|
}),
|
|
24
22
|
'expires-at': Flags.string({
|
|
25
|
-
description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.
|
|
23
|
+
description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.",
|
|
26
24
|
}),
|
|
27
25
|
'is-away': Flags.boolean({
|
|
28
26
|
description: "Режим «Нет на месте»",
|
|
@@ -35,33 +33,6 @@ export default class ProfileUpdateStatus extends BaseCommand {
|
|
|
35
33
|
async run() {
|
|
36
34
|
const { args, flags } = await this.parse(ProfileUpdateStatus);
|
|
37
35
|
this.parsedFlags = flags;
|
|
38
|
-
const missingRequired = [
|
|
39
|
-
{ flag: 'emoji', label: "Emoji символ статуса", type: 'string' },
|
|
40
|
-
{ flag: 'title', label: "Текст статуса", type: 'string' },
|
|
41
|
-
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
42
|
-
if (missingRequired.length > 0) {
|
|
43
|
-
if (this.isInteractive()) {
|
|
44
|
-
for (const field of missingRequired) {
|
|
45
|
-
const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
|
|
46
|
-
if (clack.isCancel(value)) {
|
|
47
|
-
process.stderr.write('Отменено.\n');
|
|
48
|
-
this.exit(0);
|
|
49
|
-
}
|
|
50
|
-
if (field.type === 'integer') {
|
|
51
|
-
flags[field.flag] = Number.parseInt(value, 10);
|
|
52
|
-
}
|
|
53
|
-
else if (field.type === 'boolean') {
|
|
54
|
-
flags[field.flag] = value === 'true';
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
flags[field.flag] = value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --emoji <string>, --title <string>. pachca introspect profile update-status" });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
36
|
const validationErrors = [];
|
|
66
37
|
if (flags['title'] && String(flags['title']).length > 50) {
|
|
67
38
|
validationErrors.push({ message: `--title: максимум 50 символов (передано: ${String(flags['title']).length})`, flag: 'title' });
|
|
@@ -49,7 +49,7 @@ export default class ReactionsList 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)
|
|
@@ -51,7 +51,7 @@ export default class ReadMemberListReaders 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)
|
|
@@ -16,7 +16,7 @@ export default class SearchListChats extends BaseCommand {
|
|
|
16
16
|
static flags = {
|
|
17
17
|
...BaseCommand.baseFlags,
|
|
18
18
|
'query': Flags.string({
|
|
19
|
-
description: "Текст поискового
|
|
19
|
+
description: "Текст поискового запроса. Запрос длиннее 500 знаков обрезается.",
|
|
20
20
|
}),
|
|
21
21
|
'order': Flags.string({
|
|
22
22
|
description: "Направление сортировки",
|
|
@@ -81,7 +81,7 @@ export default class SearchListChats extends BaseCommand {
|
|
|
81
81
|
const paginate = meta?.paginate;
|
|
82
82
|
nextCursor = paginate?.next_page;
|
|
83
83
|
pages++;
|
|
84
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
84
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
85
85
|
const hasNext = paginate?.has_next;
|
|
86
86
|
if (typeof hasNext === 'boolean') {
|
|
87
87
|
if (!hasNext)
|
|
@@ -14,7 +14,7 @@ export default class SearchListMessages extends BaseCommand {
|
|
|
14
14
|
static flags = {
|
|
15
15
|
...BaseCommand.baseFlags,
|
|
16
16
|
'query': Flags.string({
|
|
17
|
-
description: "Текст поискового
|
|
17
|
+
description: "Текст поискового запроса. Без него сообщения отбираются только фильтрами. Запрос длиннее 500 знаков обрезается.",
|
|
18
18
|
}),
|
|
19
19
|
'order': Flags.string({
|
|
20
20
|
description: "Направление сортировки",
|
|
@@ -68,8 +68,8 @@ export default class SearchListMessages extends BaseCommand {
|
|
|
68
68
|
sort: flags['sort'],
|
|
69
69
|
'created_from': flags['created-from'],
|
|
70
70
|
'created_to': flags['created-to'],
|
|
71
|
-
'chat_ids': flags['chat-ids']?.split(','),
|
|
72
|
-
'user_ids': flags['user-ids']?.split(','),
|
|
71
|
+
'chat_ids[]': flags['chat-ids']?.split(','),
|
|
72
|
+
'user_ids[]': flags['user-ids']?.split(','),
|
|
73
73
|
active: flags['active'],
|
|
74
74
|
limit: flags.limit,
|
|
75
75
|
cursor: nextCursor,
|
|
@@ -83,7 +83,7 @@ export default class SearchListMessages extends BaseCommand {
|
|
|
83
83
|
const paginate = meta?.paginate;
|
|
84
84
|
nextCursor = paginate?.next_page;
|
|
85
85
|
pages++;
|
|
86
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
86
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
87
87
|
const hasNext = paginate?.has_next;
|
|
88
88
|
if (typeof hasNext === 'boolean') {
|
|
89
89
|
if (!hasNext)
|
|
@@ -122,8 +122,8 @@ export default class SearchListMessages extends BaseCommand {
|
|
|
122
122
|
sort: flags['sort'],
|
|
123
123
|
'created_from': flags['created-from'],
|
|
124
124
|
'created_to': flags['created-to'],
|
|
125
|
-
'chat_ids': flags['chat-ids']?.split(','),
|
|
126
|
-
'user_ids': flags['user-ids']?.split(','),
|
|
125
|
+
'chat_ids[]': flags['chat-ids']?.split(','),
|
|
126
|
+
'user_ids[]': flags['user-ids']?.split(','),
|
|
127
127
|
active: flags['active'],
|
|
128
128
|
limit: flags.limit,
|
|
129
129
|
cursor: flags.cursor,
|
|
@@ -16,7 +16,7 @@ export default class SearchListUsers extends BaseCommand {
|
|
|
16
16
|
static flags = {
|
|
17
17
|
...BaseCommand.baseFlags,
|
|
18
18
|
'query': Flags.string({
|
|
19
|
-
description: "Текст поискового
|
|
19
|
+
description: "Текст поискового запроса. Запрос длиннее 500 знаков обрезается.",
|
|
20
20
|
}),
|
|
21
21
|
'sort': Flags.string({
|
|
22
22
|
description: "Сортировка результатов",
|
|
@@ -62,7 +62,7 @@ export default class SearchListUsers extends BaseCommand {
|
|
|
62
62
|
order: flags['order'],
|
|
63
63
|
'created_from': flags['created-from'],
|
|
64
64
|
'created_to': flags['created-to'],
|
|
65
|
-
'company_roles': flags['company-roles']?.split(','),
|
|
65
|
+
'company_roles[]': flags['company-roles']?.split(','),
|
|
66
66
|
limit: flags.limit,
|
|
67
67
|
cursor: nextCursor,
|
|
68
68
|
};
|
|
@@ -75,7 +75,7 @@ export default class SearchListUsers extends BaseCommand {
|
|
|
75
75
|
const paginate = meta?.paginate;
|
|
76
76
|
nextCursor = paginate?.next_page;
|
|
77
77
|
pages++;
|
|
78
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
78
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
79
79
|
const hasNext = paginate?.has_next;
|
|
80
80
|
if (typeof hasNext === 'boolean') {
|
|
81
81
|
if (!hasNext)
|
|
@@ -114,7 +114,7 @@ export default class SearchListUsers extends BaseCommand {
|
|
|
114
114
|
order: flags['order'],
|
|
115
115
|
'created_from': flags['created-from'],
|
|
116
116
|
'created_to': flags['created-to'],
|
|
117
|
-
'company_roles': flags['company-roles']?.split(','),
|
|
117
|
+
'company_roles[]': flags['company-roles']?.split(','),
|
|
118
118
|
limit: flags.limit,
|
|
119
119
|
cursor: flags.cursor,
|
|
120
120
|
},
|
|
@@ -79,7 +79,7 @@ export default class SecurityList extends BaseCommand {
|
|
|
79
79
|
const paginate = meta?.paginate;
|
|
80
80
|
nextCursor = paginate?.next_page;
|
|
81
81
|
pages++;
|
|
82
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
82
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
83
83
|
const hasNext = paginate?.has_next;
|
|
84
84
|
if (typeof hasNext === 'boolean') {
|
|
85
85
|
if (!hasNext)
|
|
@@ -12,7 +12,7 @@ export default class TasksGet extends BaseCommand {
|
|
|
12
12
|
static defaultColumns = ["id", "content", "created_at", "kind", "due_at"];
|
|
13
13
|
static args = {
|
|
14
14
|
id: Args.integer({
|
|
15
|
-
description: "Идентификатор
|
|
15
|
+
description: "Идентификатор напоминания: в ссылке веб-приложения это число из пути `/tasks/{id}` или из параметра `task_id` (pachca tasks list)",
|
|
16
16
|
required: true,
|
|
17
17
|
}),
|
|
18
18
|
};
|
|
@@ -51,8 +51,8 @@ export default class TasksList extends BaseCommand {
|
|
|
51
51
|
while (pages < 500) {
|
|
52
52
|
const query = {
|
|
53
53
|
status: flags['status'],
|
|
54
|
-
'chat_ids': flags['chat-ids']?.split(','),
|
|
55
|
-
'performer_ids': flags['performer-ids']?.split(','),
|
|
54
|
+
'chat_ids[]': flags['chat-ids']?.split(','),
|
|
55
|
+
'performer_ids[]': flags['performer-ids']?.split(','),
|
|
56
56
|
'author_id': flags['author-id'],
|
|
57
57
|
limit: flags.limit,
|
|
58
58
|
cursor: nextCursor,
|
|
@@ -66,7 +66,7 @@ export default class TasksList extends BaseCommand {
|
|
|
66
66
|
const paginate = meta?.paginate;
|
|
67
67
|
nextCursor = paginate?.next_page;
|
|
68
68
|
pages++;
|
|
69
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
69
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
70
70
|
const hasNext = paginate?.has_next;
|
|
71
71
|
if (typeof hasNext === 'boolean') {
|
|
72
72
|
if (!hasNext)
|
|
@@ -101,8 +101,8 @@ export default class TasksList extends BaseCommand {
|
|
|
101
101
|
path: '/tasks',
|
|
102
102
|
query: {
|
|
103
103
|
status: flags['status'],
|
|
104
|
-
'chat_ids': flags['chat-ids']?.split(','),
|
|
105
|
-
'performer_ids': flags['performer-ids']?.split(','),
|
|
104
|
+
'chat_ids[]': flags['chat-ids']?.split(','),
|
|
105
|
+
'performer_ids[]': flags['performer-ids']?.split(','),
|
|
106
106
|
'author_id': flags['author-id'],
|
|
107
107
|
limit: flags.limit,
|
|
108
108
|
cursor: flags.cursor,
|
|
@@ -9,7 +9,7 @@ export default class ThreadsGet extends BaseCommand {
|
|
|
9
9
|
static defaultColumns = ["id", "chat_id", "message_id", "message_chat_id", "updated_at"];
|
|
10
10
|
static args = {
|
|
11
11
|
id: Args.integer({
|
|
12
|
-
description: "Идентификатор
|
|
12
|
+
description: "Идентификатор треда: в ссылке веб-приложения это число из параметра `thread_id`",
|
|
13
13
|
required: true,
|
|
14
14
|
}),
|
|
15
15
|
};
|
|
@@ -5,7 +5,7 @@ export default class ThreadsList extends BaseCommand {
|
|
|
5
5
|
static description = "Список тредов";
|
|
6
6
|
static examples = [
|
|
7
7
|
"Получить список активных тредов за период — Запроси список тредов с фильтром по времени последнего сообщения и нужным `--limit`:\n $ pachca threads list",
|
|
8
|
-
"Получить список активных тредов за период —
|
|
8
|
+
"Получить список активных тредов за период — Пока `meta.paginate.has_next` равен `true`, бери следующую страницу через `--cursor=<next_page>`:\n $ pachca threads list"
|
|
9
9
|
];
|
|
10
10
|
static scope = "threads:read";
|
|
11
11
|
static apiMethod = "GET";
|
|
@@ -56,7 +56,7 @@ export default class ThreadsList extends BaseCommand {
|
|
|
56
56
|
const paginate = meta?.paginate;
|
|
57
57
|
nextCursor = paginate?.next_page;
|
|
58
58
|
pages++;
|
|
59
|
-
// Условие конца: списочные методы — has_next === false; методы поиска
|
|
59
|
+
// Условие конца: списочные методы и /users?query= — has_next === false; методы поиска (без has_next) — пустой data
|
|
60
60
|
const hasNext = paginate?.has_next;
|
|
61
61
|
if (typeof hasNext === 'boolean') {
|
|
62
62
|
if (!hasNext)
|
package/dist/commands/upload.js
CHANGED
|
@@ -46,16 +46,19 @@ export default class Upload extends BaseCommand {
|
|
|
46
46
|
}
|
|
47
47
|
// Step 3: Replace ${filename} in key
|
|
48
48
|
const key = params.key.replace('${filename}', fileName);
|
|
49
|
-
// Step 4: Build FormData
|
|
49
|
+
// Step 4: Build FormData. A workspace gets `acl` or `bucket`, depending on its storage
|
|
50
50
|
const formData = new FormData();
|
|
51
51
|
formData.append('Content-Disposition', params['Content-Disposition']);
|
|
52
|
-
|
|
52
|
+
if (params.acl !== undefined)
|
|
53
|
+
formData.append('acl', params.acl);
|
|
53
54
|
formData.append('policy', params.policy);
|
|
54
55
|
formData.append('x-amz-credential', params['x-amz-credential']);
|
|
55
56
|
formData.append('x-amz-algorithm', params['x-amz-algorithm']);
|
|
56
57
|
formData.append('x-amz-date', params['x-amz-date']);
|
|
57
58
|
formData.append('x-amz-signature', params['x-amz-signature']);
|
|
58
59
|
formData.append('key', key);
|
|
60
|
+
if (params.bucket !== undefined)
|
|
61
|
+
formData.append('bucket', params.bucket);
|
|
59
62
|
formData.append('file', fileBlob, fileName);
|
|
60
63
|
// Step 5: Upload to external URL (no auth)
|
|
61
64
|
await this.apiRequest({
|
|
@@ -12,7 +12,7 @@ export default class UsersGet 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: "Идентификатор пользователя. В ссылке веб-приложения это число из параметра `user_id`. Параметры `profile_id` и `user-id` называют сотрудника, которому ссылку отправили. (pachca users list)",
|
|
16
16
|
required: true,
|
|
17
17
|
}),
|
|
18
18
|
};
|
|
@@ -53,7 +53,7 @@ export default class UsersList 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)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
3
|
import { BaseCommand } from '../../base-command.js';
|
|
4
|
-
import * as clack from '@clack/prompts';
|
|
5
4
|
export default class UsersUpdateStatus extends BaseCommand {
|
|
6
5
|
static description = "Новый статус сотрудника";
|
|
7
6
|
static examples = [
|
|
@@ -11,7 +10,6 @@ export default class UsersUpdateStatus extends BaseCommand {
|
|
|
11
10
|
static apiMethod = "PUT";
|
|
12
11
|
static apiPath = "/users/{user_id}/status";
|
|
13
12
|
static defaultColumns = ["title", "emoji", "expires_at", "is_away"];
|
|
14
|
-
static requiredFlags = ["emoji", "title"];
|
|
15
13
|
static args = {
|
|
16
14
|
user_id: Args.integer({
|
|
17
15
|
description: "Идентификатор пользователя (pachca users list)",
|
|
@@ -21,13 +19,13 @@ export default class UsersUpdateStatus extends BaseCommand {
|
|
|
21
19
|
static flags = {
|
|
22
20
|
...BaseCommand.baseFlags,
|
|
23
21
|
'emoji': Flags.string({
|
|
24
|
-
description: "Emoji символ статуса",
|
|
22
|
+
description: "Emoji символ статуса. Обязателен, если статуса ещё нет.",
|
|
25
23
|
}),
|
|
26
24
|
'title': Flags.string({
|
|
27
|
-
description: "Текст статуса (макс. 50 символов)",
|
|
25
|
+
description: "Текст статуса. Обязателен, если статуса ещё нет. (макс. 50 символов)",
|
|
28
26
|
}),
|
|
29
27
|
'expires-at': Flags.string({
|
|
30
|
-
description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.
|
|
28
|
+
description: "Срок жизни статуса (ISO-8601). Смещение вида `+03:00` учитывается, время без смещения считается UTC.",
|
|
31
29
|
}),
|
|
32
30
|
'is-away': Flags.boolean({
|
|
33
31
|
description: "Режим «Нет на месте»",
|
|
@@ -40,33 +38,6 @@ export default class UsersUpdateStatus extends BaseCommand {
|
|
|
40
38
|
async run() {
|
|
41
39
|
const { args, flags } = await this.parse(UsersUpdateStatus);
|
|
42
40
|
this.parsedFlags = flags;
|
|
43
|
-
const missingRequired = [
|
|
44
|
-
{ flag: 'emoji', label: "Emoji символ статуса", type: 'string' },
|
|
45
|
-
{ flag: 'title', label: "Текст статуса", type: 'string' },
|
|
46
|
-
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
47
|
-
if (missingRequired.length > 0) {
|
|
48
|
-
if (this.isInteractive()) {
|
|
49
|
-
for (const field of missingRequired) {
|
|
50
|
-
const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
|
|
51
|
-
if (clack.isCancel(value)) {
|
|
52
|
-
process.stderr.write('Отменено.\n');
|
|
53
|
-
this.exit(0);
|
|
54
|
-
}
|
|
55
|
-
if (field.type === 'integer') {
|
|
56
|
-
flags[field.flag] = Number.parseInt(value, 10);
|
|
57
|
-
}
|
|
58
|
-
else if (field.type === 'boolean') {
|
|
59
|
-
flags[field.flag] = value === 'true';
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
flags[field.flag] = value;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --emoji <string>, --title <string>. pachca introspect users update-status" });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
41
|
const validationErrors = [];
|
|
71
42
|
if (flags['title'] && String(flags['title']).length > 50) {
|
|
72
43
|
validationErrors.push({ message: `--title: максимум 50 символов (передано: ${String(flags['title']).length})`, flag: 'title' });
|
|
@@ -32,7 +32,7 @@ export default class UsersUpdate extends BaseCommand {
|
|
|
32
32
|
description: "Телефон (макс. 255 символов)",
|
|
33
33
|
}),
|
|
34
34
|
'nickname': Flags.string({
|
|
35
|
-
description: "Имя
|
|
35
|
+
description: "Имя пользователя. Ник бота должен оканчиваться на `_bot` и быть уникальным в пространстве, иначе метод отвечает `422` с ошибкой на поле `nickname`: `invalid` или `already_exists`. Прежний ник бота проверяется, только когда его меняют. (макс. 255 символов)",
|
|
36
36
|
}),
|
|
37
37
|
'department': Flags.string({
|
|
38
38
|
description: "Департамент (макс. 255 символов)",
|
|
@@ -48,7 +48,7 @@ export default class UsersUpdate extends BaseCommand {
|
|
|
48
48
|
allowNo: true,
|
|
49
49
|
}),
|
|
50
50
|
'list-tags': Flags.string({
|
|
51
|
-
description: "Массив названий тегов, привязываемых к сотруднику. Список заменяет прежний целиком, пустой снимает все теги. Значение, которое не является массивом непустых строк, игнорируется: теги сотрудника не меняются.",
|
|
51
|
+
description: "Массив названий тегов, привязываемых к сотруднику. Список заменяет прежний целиком, пустой снимает все теги. Значение, которое не является массивом непустых строк, игнорируется: теги сотрудника не меняются. В тег можно добавить только бота, которого может добавить в чат любой сотрудник и у которого выключена настройка «Ограничить одним чатом». Если бот этим условиям не отвечает, а в списке есть тег, которого у него ещё нет, метод отвечает `422` на поле `group_tags` и ничего не меняет: с кодом `single_chat_bot_tag_denied`, когда бот ограничен одним чатом, и `restricted_bot_tag_denied`, когда добавлять его в чаты могут не все. Подробнее — в разделе [Бот в тегах](https://dev.pachca.com/guides/bots/settings#bot-v-tegah).",
|
|
52
52
|
}),
|
|
53
53
|
'custom-properties': Flags.string({
|
|
54
54
|
description: "Задаваемые дополнительные поля",
|
|
@@ -26,7 +26,7 @@ export default class ViewsOpen extends BaseCommand {
|
|
|
26
26
|
description: "Текст кнопки отправки формы (макс. 24 символов)",
|
|
27
27
|
}),
|
|
28
28
|
'blocks': Flags.string({
|
|
29
|
-
description: "Массив блоков
|
|
29
|
+
description: "Массив блоков представления. Имена блоков (`name`) не повторяются, в select и radio заранее выбрано не больше одного варианта, а `min_length` поля ввода не больше его `max_length`.",
|
|
30
30
|
}),
|
|
31
31
|
'type': Flags.string({
|
|
32
32
|
description: "Способ открытия представления",
|
|
@@ -47,7 +47,7 @@ export default class ViewsOpen extends BaseCommand {
|
|
|
47
47
|
this.parsedFlags = flags;
|
|
48
48
|
const missingRequired = [
|
|
49
49
|
{ flag: 'title', label: "Заголовок представления", type: 'string' },
|
|
50
|
-
{ flag: 'blocks', label: "Массив блоков
|
|
50
|
+
{ flag: 'blocks', label: "Массив блоков представления. Имена блоков (`name`) не повторяются, в select и radio заранее выбрано не больше одного варианта, а `min_length` поля ввода не больше его `max_length`.", type: 'string' },
|
|
51
51
|
{ flag: 'type', label: "Способ открытия представления", type: 'string' },
|
|
52
52
|
{ flag: 'trigger-id', label: "Уникальный идентификатор события (полученный, например, в исходящем вебхуке о нажатии кнопки)", type: 'string' },
|
|
53
53
|
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
"bots:get": "Информация о боте",
|
|
8
8
|
"bots:update": "Редактирование бота",
|
|
9
9
|
"bots:delete": "Удаление бота",
|
|
10
|
+
"bots:update-avatar": "Загрузка аватара бота",
|
|
11
|
+
"bots:remove-avatar": "Удаление аватара бота",
|
|
10
12
|
"bots:recreate-token": "Ротация токена бота",
|
|
11
13
|
"bots:rotate-client-secret": "Ротация секрета клиента",
|
|
12
14
|
"bots:list-scopes": "Каталог прав бота",
|
|
@@ -25,12 +27,12 @@
|
|
|
25
27
|
"chats:update-avatar": "Загрузка аватара чата",
|
|
26
28
|
"chats:remove-avatar": "Удаление аватара чата",
|
|
27
29
|
"members:add-group-tags": "Добавление тегов",
|
|
28
|
-
"members:remove-group-tag": "Исключение тега",
|
|
30
|
+
"members:remove-group-tag": "Исключение тега из чата",
|
|
29
31
|
"members:leave": "Выход из чата",
|
|
30
32
|
"members:list": "Список участников чата",
|
|
31
|
-
"members:add": "Добавление
|
|
32
|
-
"members:remove": "Исключение
|
|
33
|
-
"members:update": "Редактирование роли",
|
|
33
|
+
"members:add": "Добавление участников",
|
|
34
|
+
"members:remove": "Исключение участника",
|
|
35
|
+
"members:update": "Редактирование роли участника",
|
|
34
36
|
"chats:unarchive": "Разархивация чата",
|
|
35
37
|
"chats:mark-unread": "Отметка чата непрочитанным",
|
|
36
38
|
"bots:list-company": "Список ботов пространства",
|
|
@@ -94,7 +96,7 @@
|
|
|
94
96
|
"views:open": "Открытие представления",
|
|
95
97
|
"views:submit-response": "Ответ на отправку формы",
|
|
96
98
|
"bots:list-events": "История событий",
|
|
97
|
-
"bots:remove-event": "Удаление события",
|
|
99
|
+
"bots:remove-event": "Удаление события истории",
|
|
98
100
|
"skill:pachca-users": "pachca-users",
|
|
99
101
|
"skill:pachca-oauth": "pachca-oauth",
|
|
100
102
|
"skill:pachca-profile": "получить профиль, мой профиль, установить свой статус",
|
package/dist/data/changelog.json
CHANGED
|
@@ -1,4 +1,45 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "2026.10.1",
|
|
4
|
+
"date": "20 октября 2026",
|
|
5
|
+
"changes": [
|
|
6
|
+
{
|
|
7
|
+
"type": "~",
|
|
8
|
+
"command": "chats request-export",
|
|
9
|
+
"description": "Команда выводит номер выгрузки `id`: с ним `pachca chats download-export` забирает архив, когда тот соберётся"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "+",
|
|
13
|
+
"command": "chats create",
|
|
14
|
+
"description": "Команда предупреждает в stderr об идентификаторах из `--member-ids`, которых не удалось добавить в чат"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "+",
|
|
18
|
+
"command": "bots update-avatar, bots remove-avatar",
|
|
19
|
+
"description": "Новые команды — аватар бота: загрузка файла флагом `--file` и удаление"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "+",
|
|
23
|
+
"command": "bots get",
|
|
24
|
+
"description": "В `webhook` приходят адрес входящего вебхука `url`, секрет подписи `secret_token` и тело последнего запроса `last_request_body`, если у токена есть скоуп `bots:write` и вы можете управлять токенами бота"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "~",
|
|
28
|
+
"command": "messages create",
|
|
29
|
+
"description": "Сообщение уходит без `--content`, если к нему приложены файлы"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "~",
|
|
33
|
+
"command": "profile update-status, users update-status",
|
|
34
|
+
"description": "`--emoji` и `--title` нужны, только когда статуса ещё нет — продлить статус можно одним `--expires-at`"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "~",
|
|
38
|
+
"command": "upload, files direct-url",
|
|
39
|
+
"description": "`pachca upload` передаёт в форме загрузки `acl` и `bucket`, только если они пришли, а у `pachca files direct-url` флаг `--acl` необязателен и есть флаг `--bucket`: в части пространств метод `Получение подписи, ключа и других параметров` отдаёт `bucket` вместо `acl`"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
2
43
|
{
|
|
3
44
|
"version": "2026.10.0",
|
|
4
45
|
"date": "13 октября 2026",
|