@pachca/cli 2026.9.0 → 2026.10.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/CHANGELOG.md +32 -0
- package/README.md +23 -2
- package/dist/base-command.js +35 -0
- package/dist/client.js +23 -8
- package/dist/commands/auth/login.js +4 -4
- package/dist/commands/bots/create-token.js +84 -0
- package/dist/commands/bots/create.js +32 -5
- package/dist/commands/bots/delete-token.js +46 -0
- package/dist/commands/bots/delete.js +1 -1
- package/dist/commands/bots/get.js +1 -1
- package/dist/commands/bots/list-scopes.js +32 -0
- package/dist/commands/bots/list-tokens.js +94 -0
- package/dist/commands/bots/list.js +1 -1
- package/dist/commands/bots/recreate-token-self.js +1 -1
- package/dist/commands/bots/recreate-token.js +2 -2
- package/dist/commands/bots/reissue-token.js +37 -0
- package/dist/commands/bots/rotate-client-secret.js +30 -0
- package/dist/commands/bots/update-token.js +60 -0
- package/dist/commands/bots/update.js +35 -6
- package/dist/commands/chats/list.js +2 -2
- package/dist/commands/chats/mark-unread.js +44 -0
- package/dist/commands/chats/remove-avatar.js +45 -0
- package/dist/commands/chats/request-export.js +7 -8
- package/dist/commands/chats/update-avatar.js +54 -0
- package/dist/commands/drafts/create.js +98 -0
- package/dist/commands/drafts/delete.js +45 -0
- package/dist/commands/drafts/get.js +30 -0
- package/dist/commands/drafts/list.js +107 -0
- package/dist/commands/drafts/update.js +66 -0
- package/dist/commands/files/get.js +43 -0
- package/dist/commands/group-tags/list.js +1 -1
- package/dist/commands/members/leave.js +1 -1
- package/dist/commands/messages/create.js +5 -5
- package/dist/commands/messages/update.js +1 -1
- package/dist/commands/profile/update-status.js +1 -1
- package/dist/commands/reactions/add.js +2 -2
- package/dist/commands/reactions/remove.js +2 -2
- package/dist/commands/search/list-chats.js +1 -0
- package/dist/commands/security/list.js +3 -3
- package/dist/commands/tasks/create.js +2 -2
- package/dist/commands/tasks/list.js +1 -1
- package/dist/commands/tasks/update.js +3 -3
- package/dist/commands/threads/list.js +2 -2
- package/dist/commands/users/create.js +1 -1
- package/dist/commands/users/update-status.js +1 -1
- package/dist/commands/users/update.js +1 -1
- package/dist/data/alternatives.json +18 -2
- package/dist/data/changelog.json +140 -0
- package/dist/data/endpoints.json +1 -1
- package/dist/data/workflows.json +76 -5
- package/dist/oauth.js +28 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class BotsReissueToken extends BaseCommand {
|
|
5
|
+
static description = "Перевыпуск токена бота";
|
|
6
|
+
static examples = [
|
|
7
|
+
"Ротация токена бота — Отдельный токен бота перевыпускай по его `id` из `pachca bots list-tokens`: значение меняется, имя и права остаются:\n $ pachca bots reissue-token"
|
|
8
|
+
];
|
|
9
|
+
static scope = "bots:write";
|
|
10
|
+
static apiMethod = "POST";
|
|
11
|
+
static apiPath = "/bots/{id}/tokens/{token_id}/reissue";
|
|
12
|
+
static defaultColumns = ["id", "name", "created_at", "token", "user_id"];
|
|
13
|
+
static args = {
|
|
14
|
+
id: Args.integer({
|
|
15
|
+
description: "Идентификатор бота (pachca bots list)",
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
token_id: Args.integer({
|
|
19
|
+
description: "Идентификатор токена",
|
|
20
|
+
required: true,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
static flags = {
|
|
24
|
+
...BaseCommand.baseFlags,
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { args, flags } = await this.parse(BotsReissueToken);
|
|
28
|
+
this.parsedFlags = flags;
|
|
29
|
+
const { data } = await this.apiRequest({
|
|
30
|
+
method: 'POST',
|
|
31
|
+
path: `/bots/${args.id}/tokens/${args.token_id}/reissue`,
|
|
32
|
+
});
|
|
33
|
+
const responseBody = (data ?? {});
|
|
34
|
+
const result = responseBody.data ?? responseBody;
|
|
35
|
+
this.output(result);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class BotsRotateClientSecret extends BaseCommand {
|
|
5
|
+
static description = "Ротация секрета клиента";
|
|
6
|
+
static scope = "bots:write";
|
|
7
|
+
static apiMethod = "POST";
|
|
8
|
+
static apiPath = "/bots/{id}/rotate_client_secret";
|
|
9
|
+
static defaultColumns = ["id", "name", "created_at", "nickname", "avatar_url"];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.integer({
|
|
12
|
+
description: "Идентификатор бота (pachca bots list)",
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
...BaseCommand.baseFlags,
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(BotsRotateClientSecret);
|
|
21
|
+
this.parsedFlags = flags;
|
|
22
|
+
const { data } = await this.apiRequest({
|
|
23
|
+
method: 'POST',
|
|
24
|
+
path: `/bots/${args.id}/rotate_client_secret`,
|
|
25
|
+
});
|
|
26
|
+
const responseBody = (data ?? {});
|
|
27
|
+
const result = responseBody.data ?? responseBody;
|
|
28
|
+
this.output(result);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class BotsUpdateToken extends BaseCommand {
|
|
5
|
+
static description = "Изменение токена бота";
|
|
6
|
+
static scope = "bots:write";
|
|
7
|
+
static apiMethod = "PUT";
|
|
8
|
+
static apiPath = "/bots/{id}/tokens/{token_id}";
|
|
9
|
+
static defaultColumns = ["id", "name", "created_at", "token", "user_id"];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.integer({
|
|
12
|
+
description: "Идентификатор бота (pachca bots list)",
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
token_id: Args.integer({
|
|
16
|
+
description: "Идентификатор токена",
|
|
17
|
+
required: true,
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
...BaseCommand.baseFlags,
|
|
22
|
+
'name': Flags.string({
|
|
23
|
+
description: "Новое имя токена (макс. 255 символов)",
|
|
24
|
+
}),
|
|
25
|
+
'scopes': Flags.string({
|
|
26
|
+
description: "Новые права токена. Список заменяется целиком и действует сразу, перевыпускать токен не нужно.",
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
async run() {
|
|
30
|
+
const { args, flags } = await this.parse(BotsUpdateToken);
|
|
31
|
+
this.parsedFlags = flags;
|
|
32
|
+
const validationErrors = [];
|
|
33
|
+
if (flags['name'] && String(flags['name']).length > 255) {
|
|
34
|
+
validationErrors.push({ message: `--name: максимум 255 символов (передано: ${String(flags['name']).length})`, flag: 'name' });
|
|
35
|
+
}
|
|
36
|
+
if (validationErrors.length > 0) {
|
|
37
|
+
this.validationError(validationErrors);
|
|
38
|
+
}
|
|
39
|
+
const body = {
|
|
40
|
+
name: flags['name'],
|
|
41
|
+
scopes: flags['scopes'] ? this.parseJSON(flags['scopes'], 'scopes') : undefined,
|
|
42
|
+
};
|
|
43
|
+
// Clean undefined fields
|
|
44
|
+
for (const [k, v] of Object.entries(body)) {
|
|
45
|
+
if (v === undefined)
|
|
46
|
+
delete body[k];
|
|
47
|
+
}
|
|
48
|
+
if (Object.keys(body).length === 0) {
|
|
49
|
+
this.validationError([{ message: 'Не указаны поля для обновления' }], { type: 'PACHCA_USAGE_ERROR' });
|
|
50
|
+
}
|
|
51
|
+
const { data } = await this.apiRequest({
|
|
52
|
+
method: 'PUT',
|
|
53
|
+
path: `/bots/${args.id}/tokens/${args.token_id}`,
|
|
54
|
+
body,
|
|
55
|
+
});
|
|
56
|
+
const responseBody = (data ?? {});
|
|
57
|
+
const result = responseBody.data ?? responseBody;
|
|
58
|
+
this.output(result);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -4,12 +4,14 @@ import { BaseCommand } from '../../base-command.js';
|
|
|
4
4
|
export default class BotsUpdate extends BaseCommand {
|
|
5
5
|
static description = "Редактирование бота";
|
|
6
6
|
static examples = [
|
|
7
|
-
"Обновить Webhook URL бота — Пользовательским токеном (с правом редактировать бота) — обнови URL по `id` бота. Пустая строка отключает вебхук:\n $ pachca bots update"
|
|
7
|
+
"Обновить Webhook URL бота — Пользовательским токеном (с правом редактировать бота) — обнови URL по `id` бота. Пустая строка отключает вебхук:\n $ pachca bots update",
|
|
8
|
+
"Включить боту авторизацию от имени сотрудника — Пользовательским токеном (создатель бота или администратор, если бот открыт администраторам) включи авторизацию: где хранится секрет, адреса возврата и права, которые бот попросит у сотрудника. Права бери из `pachca bots list-scopes`:\n $ pachca bots update",
|
|
9
|
+
"Включить боту авторизацию от имени сотрудника — Чтобы бот появился в витрине, добавь описание и опубликуй страницу:\n $ pachca bots update"
|
|
8
10
|
];
|
|
9
11
|
static scope = "bots:write";
|
|
10
12
|
static apiMethod = "PUT";
|
|
11
13
|
static apiPath = "/bots/{id}";
|
|
12
|
-
static defaultColumns = ["id", "
|
|
14
|
+
static defaultColumns = ["id", "name", "created_at", "nickname", "avatar_url"];
|
|
13
15
|
static args = {
|
|
14
16
|
id: Args.integer({
|
|
15
17
|
description: "Идентификатор бота (pachca bots list)",
|
|
@@ -53,7 +55,7 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
53
55
|
allowNo: true,
|
|
54
56
|
}),
|
|
55
57
|
'ignore-self-messages': Flags.boolean({
|
|
56
|
-
description: "
|
|
58
|
+
description: "Не присылать боту события о его собственных сообщениях и реакциях",
|
|
57
59
|
allowNo: true,
|
|
58
60
|
}),
|
|
59
61
|
'events-history-enabled': Flags.boolean({
|
|
@@ -66,6 +68,22 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
66
68
|
'can-edit': Flags.string({
|
|
67
69
|
description: "Роли, которым, помимо создателя, разрешено редактировать настройки бота. Создатель может редактировать всегда. Пустой массив — редактировать может только создатель.",
|
|
68
70
|
}),
|
|
71
|
+
'single-chat': Flags.boolean({
|
|
72
|
+
description: "Ограничивает бота одной беседой или каналом: `true` — бота можно добавить только в один такой чат, `false` — в несколько. Личные чаты и треды в ограничение не входят.",
|
|
73
|
+
allowNo: true,
|
|
74
|
+
}),
|
|
75
|
+
'kind': Flags.string({
|
|
76
|
+
description: "Источник входящего вебхука. Если у бота входящего вебхука не было, он включается.",
|
|
77
|
+
}),
|
|
78
|
+
'unfurl-domains': Flags.string({
|
|
79
|
+
description: "Домены, ссылки на которые бот разворачивает, не больше 5. Работают вместе с событием `message_link_shared`.",
|
|
80
|
+
}),
|
|
81
|
+
'oauth-client': Flags.string({
|
|
82
|
+
description: "Настройки авторизации от имени сотрудника. Если авторизация выключена, объект её включает, а `null` выключает: выданные сотрудниками авторизации отзываются, страница в витрине удаляется.",
|
|
83
|
+
}),
|
|
84
|
+
'promo': Flags.string({
|
|
85
|
+
description: "Страница бота в витрине. Доступна, только когда у бота включена авторизация.",
|
|
86
|
+
}),
|
|
69
87
|
};
|
|
70
88
|
async run() {
|
|
71
89
|
const { args, flags } = await this.parse(BotsUpdate);
|
|
@@ -80,7 +98,8 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
80
98
|
if (validationErrors.length > 0) {
|
|
81
99
|
this.validationError(validationErrors);
|
|
82
100
|
}
|
|
83
|
-
const body = {
|
|
101
|
+
const body = {
|
|
102
|
+
webhook: {
|
|
84
103
|
name: flags['name'],
|
|
85
104
|
nickname: flags['nickname'],
|
|
86
105
|
outgoing_url: flags['outgoing-url'],
|
|
@@ -96,14 +115,24 @@ export default class BotsUpdate extends BaseCommand {
|
|
|
96
115
|
events_history_enabled: flags['events-history-enabled'],
|
|
97
116
|
who_can_add: flags['who-can-add'],
|
|
98
117
|
can_edit: flags['can-edit'] ? this.parseJSON(flags['can-edit'], 'can-edit') : undefined,
|
|
99
|
-
|
|
118
|
+
single_chat: flags['single-chat'],
|
|
119
|
+
kind: flags['kind'],
|
|
120
|
+
unfurl_domains: flags['unfurl-domains'] ? this.parseJSON(flags['unfurl-domains'], 'unfurl-domains') : undefined,
|
|
121
|
+
},
|
|
122
|
+
oauth_client: flags['oauth-client'] ? this.parseJSON(flags['oauth-client'], 'oauth-client') : undefined,
|
|
123
|
+
promo: flags['promo'] ? this.parseJSON(flags['promo'], 'promo') : undefined,
|
|
124
|
+
};
|
|
100
125
|
// Clean undefined fields
|
|
101
126
|
const inner = body['webhook'];
|
|
102
127
|
for (const [k, v] of Object.entries(inner)) {
|
|
103
128
|
if (v === undefined)
|
|
104
129
|
delete inner[k];
|
|
105
130
|
}
|
|
106
|
-
|
|
131
|
+
for (const [k, v] of Object.entries(body)) {
|
|
132
|
+
if (k !== 'webhook' && v === undefined)
|
|
133
|
+
delete body[k];
|
|
134
|
+
}
|
|
135
|
+
if (Object.keys(inner).length === 0 && Object.keys(body).length === 1) {
|
|
107
136
|
this.validationError([{ message: 'Не указаны поля для обновления' }], { type: 'PACHCA_USAGE_ERROR' });
|
|
108
137
|
}
|
|
109
138
|
const { data } = await this.apiRequest({
|
|
@@ -36,10 +36,10 @@ export default class ChatsList extends BaseCommand {
|
|
|
36
36
|
allowNo: true,
|
|
37
37
|
}),
|
|
38
38
|
'last-message-at-after': Flags.string({
|
|
39
|
-
description: "Фильтрация по времени создания последнего
|
|
39
|
+
description: "Фильтрация по времени создания последнего сообщения: вернутся чаты, где оно позже указанного. Значение в ISO-8601, смещение вида `+03:00` учитывается, время без смещения считается UTC.",
|
|
40
40
|
}),
|
|
41
41
|
'last-message-at-before': Flags.string({
|
|
42
|
-
description: "Фильтрация по времени создания последнего
|
|
42
|
+
description: "Фильтрация по времени создания последнего сообщения: вернутся чаты, где оно раньше указанного. Значение в ISO-8601, смещение вида `+03:00` учитывается, время без смещения считается UTC.",
|
|
43
43
|
}),
|
|
44
44
|
'personal': Flags.boolean({
|
|
45
45
|
description: "Фильтрация по личным и групповым чатам. Если параметр не указан, возвращаются любые чаты.",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class ChatsMarkUnread extends BaseCommand {
|
|
5
|
+
static description = "Отметка чата непрочитанным";
|
|
6
|
+
static scope = "chats:mark_unread";
|
|
7
|
+
static apiMethod = "PUT";
|
|
8
|
+
static apiPath = "/chats/{id}/unread";
|
|
9
|
+
static args = {
|
|
10
|
+
id: Args.integer({
|
|
11
|
+
description: "Идентификатор чата или треда (pachca chats list)",
|
|
12
|
+
required: true,
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
...BaseCommand.baseFlags,
|
|
17
|
+
'message-id': Flags.integer({
|
|
18
|
+
description: "Идентификатор сообщения, с которого чат становится непрочитанным: оно и все сообщения после него. Если не передать, непрочитанным становится последнее сообщение. (pachca messages list)",
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async run() {
|
|
22
|
+
const { args, flags } = await this.parse(ChatsMarkUnread);
|
|
23
|
+
this.parsedFlags = flags;
|
|
24
|
+
const body = {
|
|
25
|
+
message_id: flags['message-id'],
|
|
26
|
+
};
|
|
27
|
+
// Clean undefined fields
|
|
28
|
+
for (const [k, v] of Object.entries(body)) {
|
|
29
|
+
if (v === undefined)
|
|
30
|
+
delete body[k];
|
|
31
|
+
}
|
|
32
|
+
if (Object.keys(body).length === 0) {
|
|
33
|
+
this.validationError([{ message: 'Не указаны поля для обновления' }], { type: 'PACHCA_USAGE_ERROR' });
|
|
34
|
+
}
|
|
35
|
+
const { data } = await this.apiRequest({
|
|
36
|
+
method: 'PUT',
|
|
37
|
+
path: `/chats/${args.id}/unread`,
|
|
38
|
+
body,
|
|
39
|
+
});
|
|
40
|
+
const responseBody = (data ?? {});
|
|
41
|
+
const result = responseBody.data ?? responseBody;
|
|
42
|
+
this.output(result);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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 ChatsRemoveAvatar extends BaseCommand {
|
|
6
|
+
static description = "Удаление аватара чата";
|
|
7
|
+
static examples = [
|
|
8
|
+
"Поставить или убрать аватар чата — Чтобы убрать аватар, удали его:\n $ pachca chats remove-avatar"
|
|
9
|
+
];
|
|
10
|
+
static scope = "chats:update";
|
|
11
|
+
static apiMethod = "DELETE";
|
|
12
|
+
static apiPath = "/chats/{id}/avatar";
|
|
13
|
+
static args = {
|
|
14
|
+
id: Args.integer({
|
|
15
|
+
description: "Идентификатор чата (pachca chats list)",
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
...BaseCommand.baseFlags,
|
|
21
|
+
force: Flags.boolean({
|
|
22
|
+
description: 'Пропустить подтверждение',
|
|
23
|
+
default: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { args, flags } = await this.parse(ChatsRemoveAvatar);
|
|
28
|
+
this.parsedFlags = flags;
|
|
29
|
+
if (!flags.force) {
|
|
30
|
+
if (!this.isInteractive()) {
|
|
31
|
+
this.validationError([{ message: 'Деструктивная операция требует флага --force', flag: 'force' }], { type: 'PACHCA_DESTRUCTIVE_OP_ERROR', hint: "pachca chats remove-avatar <id> --force" });
|
|
32
|
+
}
|
|
33
|
+
const confirm = await clack.confirm({ message: 'Вы уверены?' });
|
|
34
|
+
if (clack.isCancel(confirm) || !confirm) {
|
|
35
|
+
process.stderr.write('Отменено.\n');
|
|
36
|
+
this.exit(0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const { data } = await this.apiRequest({
|
|
40
|
+
method: 'DELETE',
|
|
41
|
+
path: `/chats/${args.id}/avatar`,
|
|
42
|
+
});
|
|
43
|
+
this.success('Удалено');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -12,18 +12,18 @@ export default class ChatsRequestExport extends BaseCommand {
|
|
|
12
12
|
static plan = "corporation";
|
|
13
13
|
static apiMethod = "POST";
|
|
14
14
|
static apiPath = "/chats/exports";
|
|
15
|
-
static requiredFlags = ["start-at", "end-at"
|
|
15
|
+
static requiredFlags = ["start-at", "end-at"];
|
|
16
16
|
static args = {};
|
|
17
17
|
static flags = {
|
|
18
18
|
...BaseCommand.baseFlags,
|
|
19
19
|
'start-at': Flags.string({
|
|
20
|
-
description: "Дата начала для экспорта
|
|
20
|
+
description: "Дата начала для экспорта в формате YYYY-MM-DD. Если прислать дату со временем, время молча отбрасывается — экспорт всегда идёт по календарным дням.",
|
|
21
21
|
}),
|
|
22
22
|
'end-at': Flags.string({
|
|
23
|
-
description: "Дата окончания для экспорта
|
|
23
|
+
description: "Дата окончания для экспорта в формате YYYY-MM-DD, включительно. Если прислать дату со временем, время молча отбрасывается.",
|
|
24
24
|
}),
|
|
25
25
|
'webhook-url': Flags.string({
|
|
26
|
-
description: "Адрес, на который
|
|
26
|
+
description: "Адрес, на который придёт вебхук с номером готовой выгрузки. Без него узнать номер неоткуда: заказавший получит письмо и уведомление, а вызывающая программа — ничего.",
|
|
27
27
|
}),
|
|
28
28
|
'chat-ids': Flags.string({
|
|
29
29
|
description: "Массив идентификаторов чатов. Указывается, если нужно получить сообщения только некоторых чатов.",
|
|
@@ -37,9 +37,8 @@ export default class ChatsRequestExport extends BaseCommand {
|
|
|
37
37
|
const { args, flags } = await this.parse(ChatsRequestExport);
|
|
38
38
|
this.parsedFlags = flags;
|
|
39
39
|
const missingRequired = [
|
|
40
|
-
{ flag: 'start-at', label: "Дата начала для экспорта
|
|
41
|
-
{ flag: 'end-at', label: "Дата окончания для экспорта
|
|
42
|
-
{ flag: 'webhook-url', label: "Адрес, на который будет отправлен вебхук по завершению экспорта", type: 'string' },
|
|
40
|
+
{ flag: 'start-at', label: "Дата начала для экспорта в формате YYYY-MM-DD. Если прислать дату со временем, время молча отбрасывается — экспорт всегда идёт по календарным дням.", type: 'string' },
|
|
41
|
+
{ flag: 'end-at', label: "Дата окончания для экспорта в формате YYYY-MM-DD, включительно. Если прислать дату со временем, время молча отбрасывается.", type: 'string' },
|
|
43
42
|
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
44
43
|
if (missingRequired.length > 0) {
|
|
45
44
|
if (this.isInteractive()) {
|
|
@@ -61,7 +60,7 @@ export default class ChatsRequestExport extends BaseCommand {
|
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
else {
|
|
64
|
-
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --start-at <string>, --end-at <string
|
|
63
|
+
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --start-at <string>, --end-at <string>. pachca introspect chats request-export" });
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
const body = {
|
|
@@ -0,0 +1,54 @@
|
|
|
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 ChatsUpdateAvatar extends BaseCommand {
|
|
7
|
+
static description = "Загрузка аватара чата";
|
|
8
|
+
static examples = [
|
|
9
|
+
"Поставить или убрать аватар чата — Загрузи аватар беседы или канала:\n $ pachca chats update-avatar"
|
|
10
|
+
];
|
|
11
|
+
static scope = "chats:update";
|
|
12
|
+
static apiMethod = "PUT";
|
|
13
|
+
static apiPath = "/chats/{id}/avatar";
|
|
14
|
+
static defaultColumns = ["image_url"];
|
|
15
|
+
static args = {
|
|
16
|
+
id: Args.integer({
|
|
17
|
+
description: "Идентификатор чата (pachca chats list)",
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
...BaseCommand.baseFlags,
|
|
23
|
+
file: Flags.string({
|
|
24
|
+
description: "Файл изображения для аватара",
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { args, flags } = await this.parse(ChatsUpdateAvatar);
|
|
29
|
+
this.parsedFlags = flags;
|
|
30
|
+
let formData;
|
|
31
|
+
if (flags.file) {
|
|
32
|
+
formData = new FormData();
|
|
33
|
+
if (flags.file === '-') {
|
|
34
|
+
const chunks = [];
|
|
35
|
+
for await (const chunk of process.stdin)
|
|
36
|
+
chunks.push(chunk);
|
|
37
|
+
const blob = new Blob([Buffer.concat(chunks)]);
|
|
38
|
+
formData.append('image', blob, 'stdin');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const blob = new Blob([fs.readFileSync(flags.file)]);
|
|
42
|
+
formData.append('image', blob, path.basename(flags.file));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const { data } = await this.apiRequest({
|
|
46
|
+
method: 'PUT',
|
|
47
|
+
path: `/chats/${args.id}/avatar`,
|
|
48
|
+
formData,
|
|
49
|
+
});
|
|
50
|
+
const responseBody = (data ?? {});
|
|
51
|
+
const result = responseBody.data ?? responseBody;
|
|
52
|
+
this.output(result);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
import * as clack from '@clack/prompts';
|
|
5
|
+
export default class DraftsCreate extends BaseCommand {
|
|
6
|
+
static description = "Новый черновик";
|
|
7
|
+
static examples = [
|
|
8
|
+
"Отправить сообщение позже или по расписанию — Создай отложенное сообщение: `schedule.start_date` — когда отправить, `schedule.repetition.interval` — как повторять (`once`, если один раз):\n $ pachca drafts create"
|
|
9
|
+
];
|
|
10
|
+
static scope = "drafts:write";
|
|
11
|
+
static apiMethod = "POST";
|
|
12
|
+
static apiPath = "/drafts";
|
|
13
|
+
static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
|
|
14
|
+
static requiredFlags = ["entity-type", "entity-id"];
|
|
15
|
+
static args = {};
|
|
16
|
+
static flags = {
|
|
17
|
+
...BaseCommand.baseFlags,
|
|
18
|
+
'entity-type': Flags.string({
|
|
19
|
+
description: "Куда пишется черновик: в беседу или канал, в тред либо в личную переписку с сотрудником",
|
|
20
|
+
}),
|
|
21
|
+
'entity-id': Flags.integer({
|
|
22
|
+
description: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо сотрудника (pachca chats list | pachca users list)",
|
|
23
|
+
}),
|
|
24
|
+
'content': Flags.string({
|
|
25
|
+
description: "Текст черновика. Можно не передавать, если есть вложения, но пустым черновик быть не может. До 40 000 байт в UTF-8, а у отложенного сообщения в пространстве с продвинутым шифрованием — до 27 000.",
|
|
26
|
+
}),
|
|
27
|
+
'parent-message-id': Flags.integer({
|
|
28
|
+
description: "Идентификатор сообщения, ответом на которое уйдёт черновик. Сообщение должно быть в том же чате.",
|
|
29
|
+
}),
|
|
30
|
+
'files': Flags.string({
|
|
31
|
+
description: "Прикрепляемые файлы, не больше десяти",
|
|
32
|
+
}),
|
|
33
|
+
'schedule': Flags.string({
|
|
34
|
+
description: "Расписание отправки. С ним создаётся отложенное сообщение, без него — обычный черновик.",
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
async run() {
|
|
38
|
+
const { args, flags } = await this.parse(DraftsCreate);
|
|
39
|
+
this.parsedFlags = flags;
|
|
40
|
+
// Read from stdin if --content not provided and stdin is not TTY
|
|
41
|
+
if (!flags['content'] && !process.stdin.isTTY) {
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for await (const chunk of process.stdin) {
|
|
44
|
+
chunks.push(chunk);
|
|
45
|
+
}
|
|
46
|
+
flags['content'] = Buffer.concat(chunks).toString('utf-8').trimEnd();
|
|
47
|
+
}
|
|
48
|
+
const missingRequired = [
|
|
49
|
+
{ flag: 'entity-type', label: "Куда пишется черновик: в беседу или канал, в тред либо в личную переписку с сотрудником", type: 'string' },
|
|
50
|
+
{ flag: 'entity-id', label: "Идентификатор того, что названо в `entity_type`: беседы или канала, треда либо сотрудника", type: 'integer' },
|
|
51
|
+
].filter((f) => flags[f.flag] === undefined || flags[f.flag] === null);
|
|
52
|
+
if (missingRequired.length > 0) {
|
|
53
|
+
if (this.isInteractive()) {
|
|
54
|
+
for (const field of missingRequired) {
|
|
55
|
+
const value = await clack.text({ message: field.label, validate: (v) => v.length === 0 ? 'Обязательное поле' : undefined });
|
|
56
|
+
if (clack.isCancel(value)) {
|
|
57
|
+
process.stderr.write('Отменено.\n');
|
|
58
|
+
this.exit(0);
|
|
59
|
+
}
|
|
60
|
+
if (field.type === 'integer') {
|
|
61
|
+
flags[field.flag] = Number.parseInt(value, 10);
|
|
62
|
+
}
|
|
63
|
+
else if (field.type === 'boolean') {
|
|
64
|
+
flags[field.flag] = value === 'true';
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
flags[field.flag] = value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.validationError(missingRequired.map((f) => ({ message: `Обязательный флаг --${f.flag} не передан`, flag: f.flag })), { hint: "Обязательные: --entity-type <string>, --entity-id <integer>. pachca introspect drafts create" });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const body = { draft: {
|
|
76
|
+
entity_type: flags['entity-type'],
|
|
77
|
+
entity_id: flags['entity-id'],
|
|
78
|
+
content: flags['content'],
|
|
79
|
+
parent_message_id: flags['parent-message-id'],
|
|
80
|
+
files: flags['files'] ? this.parseJSON(flags['files'], 'files') : undefined,
|
|
81
|
+
schedule: flags['schedule'] ? this.parseJSON(flags['schedule'], 'schedule') : undefined,
|
|
82
|
+
} };
|
|
83
|
+
// Clean undefined fields
|
|
84
|
+
const inner = body['draft'];
|
|
85
|
+
for (const [k, v] of Object.entries(inner)) {
|
|
86
|
+
if (v === undefined)
|
|
87
|
+
delete inner[k];
|
|
88
|
+
}
|
|
89
|
+
const { data } = await this.apiRequest({
|
|
90
|
+
method: 'POST',
|
|
91
|
+
path: '/drafts',
|
|
92
|
+
body,
|
|
93
|
+
});
|
|
94
|
+
const responseBody = (data ?? {});
|
|
95
|
+
const result = responseBody.data ?? responseBody;
|
|
96
|
+
this.output(result);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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 DraftsDelete extends BaseCommand {
|
|
6
|
+
static description = "Удаление черновика";
|
|
7
|
+
static examples = [
|
|
8
|
+
"Отправить сообщение позже или по расписанию — Чтобы отменить отправку — удали отложенное сообщение:\n $ pachca drafts delete"
|
|
9
|
+
];
|
|
10
|
+
static scope = "drafts:write";
|
|
11
|
+
static apiMethod = "DELETE";
|
|
12
|
+
static apiPath = "/drafts/{id}";
|
|
13
|
+
static args = {
|
|
14
|
+
id: Args.integer({
|
|
15
|
+
description: "Идентификатор черновика",
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
...BaseCommand.baseFlags,
|
|
21
|
+
force: Flags.boolean({
|
|
22
|
+
description: 'Пропустить подтверждение',
|
|
23
|
+
default: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { args, flags } = await this.parse(DraftsDelete);
|
|
28
|
+
this.parsedFlags = flags;
|
|
29
|
+
if (!flags.force) {
|
|
30
|
+
if (!this.isInteractive()) {
|
|
31
|
+
this.validationError([{ message: 'Деструктивная операция требует флага --force', flag: 'force' }], { type: 'PACHCA_DESTRUCTIVE_OP_ERROR', hint: "pachca drafts delete <id> --force" });
|
|
32
|
+
}
|
|
33
|
+
const confirm = await clack.confirm({ message: 'Вы уверены?' });
|
|
34
|
+
if (clack.isCancel(confirm) || !confirm) {
|
|
35
|
+
process.stderr.write('Отменено.\n');
|
|
36
|
+
this.exit(0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const { data } = await this.apiRequest({
|
|
40
|
+
method: 'DELETE',
|
|
41
|
+
path: `/drafts/${args.id}`,
|
|
42
|
+
});
|
|
43
|
+
this.success('Удалено');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Auto-generated from openapi.yaml — DO NOT EDIT
|
|
2
|
+
import { Args } from '@oclif/core';
|
|
3
|
+
import { BaseCommand } from '../../base-command.js';
|
|
4
|
+
export default class DraftsGet extends BaseCommand {
|
|
5
|
+
static description = "Информация о черновике";
|
|
6
|
+
static scope = "drafts:read";
|
|
7
|
+
static apiMethod = "GET";
|
|
8
|
+
static apiPath = "/drafts/{id}";
|
|
9
|
+
static defaultColumns = ["id", "content", "created_at", "entity_type", "entity_id"];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.integer({
|
|
12
|
+
description: "Идентификатор черновика",
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
...BaseCommand.baseFlags,
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(DraftsGet);
|
|
21
|
+
this.parsedFlags = flags;
|
|
22
|
+
const { data } = await this.apiRequest({
|
|
23
|
+
method: 'GET',
|
|
24
|
+
path: `/drafts/${args.id}`,
|
|
25
|
+
});
|
|
26
|
+
const responseBody = (data ?? {});
|
|
27
|
+
const result = responseBody.data ?? responseBody;
|
|
28
|
+
this.output(result);
|
|
29
|
+
}
|
|
30
|
+
}
|