plazbot-cli 0.2.26 → 0.3.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/CLAUDE.md +34 -5
- package/README.md +21 -0
- package/dist/cli.js +32 -20
- package/dist/commands/agent/ai-config.js +98 -50
- package/dist/commands/agent/chat.js +80 -74
- package/dist/commands/agent/copy.js +23 -21
- package/dist/commands/agent/create.js +42 -72
- package/dist/commands/agent/delete.js +29 -30
- package/dist/commands/agent/enable-widget.js +30 -26
- package/dist/commands/agent/export.js +90 -77
- package/dist/commands/agent/files.js +68 -60
- package/dist/commands/agent/get.js +101 -87
- package/dist/commands/agent/index.js +53 -39
- package/dist/commands/agent/list.js +26 -24
- package/dist/commands/agent/monitor.js +91 -86
- package/dist/commands/agent/on-message.js +40 -37
- package/dist/commands/agent/set.js +62 -59
- package/dist/commands/agent/templates.js +109 -108
- package/dist/commands/agent/tools.js +64 -65
- package/dist/commands/agent/update.js +28 -27
- package/dist/commands/agent/validate.js +127 -0
- package/dist/commands/agent/wizard.js +152 -159
- package/dist/commands/auth/index.js +7 -10
- package/dist/commands/auth/login.js +50 -37
- package/dist/commands/auth/logout.js +16 -14
- package/dist/commands/auth/status.js +19 -16
- package/dist/commands/portal/add-agent.js +26 -24
- package/dist/commands/portal/add-link.js +21 -17
- package/dist/commands/portal/clear-links.js +17 -15
- package/dist/commands/portal/create.js +25 -21
- package/dist/commands/portal/delete.js +31 -30
- package/dist/commands/portal/get.js +33 -31
- package/dist/commands/portal/index.js +30 -22
- package/dist/commands/portal/list.js +34 -30
- package/dist/commands/portal/update.js +41 -33
- package/dist/commands/whatsapp/broadcast.js +40 -37
- package/dist/commands/whatsapp/channels.js +40 -34
- package/dist/commands/whatsapp/chat.js +33 -32
- package/dist/commands/whatsapp/connect.js +53 -52
- package/dist/commands/whatsapp/delete-webhook.js +19 -17
- package/dist/commands/whatsapp/index.js +35 -25
- package/dist/commands/whatsapp/register-webhook.js +21 -19
- package/dist/commands/whatsapp/send-template.js +39 -31
- package/dist/commands/whatsapp/send.js +27 -23
- package/dist/commands/whatsapp/widget.js +35 -31
- package/dist/commands/workers/deploy.js +49 -44
- package/dist/commands/workers/index.js +28 -18
- package/dist/commands/workers/list.js +43 -35
- package/dist/commands/workers/logs.js +38 -32
- package/dist/commands/workers/remove.js +38 -37
- package/dist/commands/workers/secret.js +63 -58
- package/dist/commands/workers/test.js +44 -36
- package/dist/schemas/agent.config.schema.json +569 -0
- package/dist/studio/api/sseClient.js +97 -0
- package/dist/studio/api/studioApi.js +25 -0
- package/dist/studio/api/types.js +16 -0
- package/dist/studio/components/AgentPanel.js +35 -0
- package/dist/studio/components/App.js +214 -0
- package/dist/studio/components/ChatLog.js +59 -0
- package/dist/studio/components/Footer.js +11 -0
- package/dist/studio/components/Header.js +8 -0
- package/dist/studio/components/Input.js +15 -0
- package/dist/studio/components/Message.js +56 -0
- package/dist/studio/components/Suggestions.js +11 -0
- package/dist/studio/components/ToolCall.js +33 -0
- package/dist/studio/components/WhatsappConnectCard.js +57 -0
- package/dist/studio/index.js +42 -0
- package/dist/studio/render/json.js +16 -0
- package/dist/studio/render/markdown.js +32 -0
- package/dist/studio/render/steps.js +58 -0
- package/dist/studio/runOneShot.js +96 -0
- package/dist/studio/runRepl.js +52 -0
- package/dist/studio/slash/handlers.js +199 -0
- package/dist/studio/slash/parser.js +46 -0
- package/dist/studio/slash/registry.js +16 -0
- package/dist/studio/state/store.js +181 -0
- package/dist/studio/whatsapp/api.js +63 -0
- package/dist/studio/whatsapp/polling.js +77 -0
- package/dist/studio/whatsapp/types.js +31 -0
- package/dist/types/agent.js +1 -2
- package/dist/types/auth.js +1 -2
- package/dist/types/common.js +1 -2
- package/dist/types/message.js +1 -2
- package/dist/types/portal.js +1 -2
- package/dist/types/workers.js +1 -2
- package/dist/utils/agent-errors.js +46 -0
- package/dist/utils/api.js +8 -9
- package/dist/utils/banner.js +33 -34
- package/dist/utils/credentials.js +12 -20
- package/dist/utils/help.js +44 -0
- package/dist/utils/logger.js +13 -19
- package/dist/utils/ui.js +35 -49
- package/package.json +21 -10
- package/src/cli.ts +24 -8
- package/src/commands/agent/ai-config.ts +89 -34
- package/src/commands/agent/chat.ts +49 -37
- package/src/commands/agent/copy.ts +19 -13
- package/src/commands/agent/create.ts +32 -22
- package/src/commands/agent/delete.ts +24 -18
- package/src/commands/agent/enable-widget.ts +31 -23
- package/src/commands/agent/export.ts +72 -51
- package/src/commands/agent/files.ts +51 -39
- package/src/commands/agent/get.ts +86 -66
- package/src/commands/agent/index.ts +36 -18
- package/src/commands/agent/list.ts +22 -16
- package/src/commands/agent/monitor.ts +67 -56
- package/src/commands/agent/on-message.ts +36 -27
- package/src/commands/agent/set.ts +47 -37
- package/src/commands/agent/templates.ts +90 -82
- package/src/commands/agent/tools.ts +53 -47
- package/src/commands/agent/update.ts +28 -20
- package/src/commands/agent/validate.ts +135 -0
- package/src/commands/agent/wizard.ts +114 -114
- package/src/commands/auth/index.ts +3 -3
- package/src/commands/auth/login.ts +44 -29
- package/src/commands/auth/logout.ts +16 -10
- package/src/commands/auth/status.ts +14 -8
- package/src/commands/portal/add-agent.ts +23 -17
- package/src/commands/portal/add-link.ts +17 -9
- package/src/commands/portal/clear-links.ts +13 -7
- package/src/commands/portal/create.ts +20 -12
- package/src/commands/portal/delete.ts +28 -20
- package/src/commands/portal/get.ts +25 -19
- package/src/commands/portal/index.ts +22 -10
- package/src/commands/portal/list.ts +27 -19
- package/src/commands/portal/update.ts +38 -26
- package/src/commands/whatsapp/broadcast.ts +28 -18
- package/src/commands/whatsapp/channels.ts +31 -20
- package/src/commands/whatsapp/chat.ts +20 -12
- package/src/commands/whatsapp/connect.ts +39 -31
- package/src/commands/whatsapp/delete-webhook.ts +15 -9
- package/src/commands/whatsapp/index.ts +24 -10
- package/src/commands/whatsapp/register-webhook.ts +16 -10
- package/src/commands/whatsapp/send-template.ts +33 -21
- package/src/commands/whatsapp/send.ts +23 -15
- package/src/commands/whatsapp/widget.ts +25 -17
- package/src/commands/workers/deploy.ts +34 -22
- package/src/commands/workers/index.ts +21 -7
- package/src/commands/workers/list.ts +31 -19
- package/src/commands/workers/logs.ts +30 -20
- package/src/commands/workers/remove.ts +30 -22
- package/src/commands/workers/secret.ts +46 -34
- package/src/commands/workers/test.ts +34 -22
- package/src/schemas/agent.config.schema.json +569 -0
- package/src/studio/api/sseClient.ts +91 -0
- package/src/studio/api/studioApi.ts +27 -0
- package/src/studio/api/types.ts +96 -0
- package/src/studio/components/App.tsx +266 -0
- package/src/studio/components/ChatLog.tsx +95 -0
- package/src/studio/components/Footer.tsx +38 -0
- package/src/studio/components/Header.tsx +39 -0
- package/src/studio/components/Input.tsx +32 -0
- package/src/studio/components/Message.tsx +87 -0
- package/src/studio/components/Suggestions.tsx +26 -0
- package/src/studio/components/ToolCall.tsx +58 -0
- package/src/studio/components/WhatsappConnectCard.tsx +139 -0
- package/src/studio/index.ts +58 -0
- package/src/studio/render/markdown.ts +32 -0
- package/src/studio/render/steps.ts +57 -0
- package/src/studio/runOneShot.ts +114 -0
- package/src/studio/runRepl.tsx +76 -0
- package/src/studio/slash/handlers.ts +226 -0
- package/src/studio/slash/parser.ts +41 -0
- package/src/studio/slash/registry.ts +54 -0
- package/src/studio/state/store.ts +273 -0
- package/src/studio/whatsapp/api.ts +96 -0
- package/src/studio/whatsapp/polling.ts +93 -0
- package/src/studio/whatsapp/types.ts +80 -0
- package/src/types/agent.ts +1 -1
- package/src/types/auth.ts +4 -3
- package/src/types/portal.ts +1 -1
- package/src/types/workers.ts +1 -1
- package/src/utils/agent-errors.ts +67 -0
- package/src/utils/api.ts +6 -0
- package/src/utils/banner.ts +14 -9
- package/src/utils/credentials.ts +6 -5
- package/src/utils/help.ts +51 -0
- package/tsconfig.json +9 -6
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.
|
|
10
|
-
.argument('<portalId>', 'ID del portal')
|
|
11
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Portal } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
export const getCommand = new Command('get')
|
|
7
|
+
.description('Show detailed information for a portal')
|
|
8
|
+
.argument('<portalId>', 'Portal ID')
|
|
9
|
+
.option('--dev', 'Use development environment', false)
|
|
12
10
|
.action(async (portalId, options) => {
|
|
13
11
|
try {
|
|
14
12
|
// Obtener credenciales guardadas
|
|
15
|
-
const credentials = await
|
|
16
|
-
const portal = new
|
|
13
|
+
const credentials = await getStoredCredentials();
|
|
14
|
+
const portal = new Portal({
|
|
17
15
|
workspaceId: credentials.workspace,
|
|
18
16
|
apiKey: credentials.apiKey,
|
|
19
17
|
zone: credentials.zone,
|
|
@@ -21,44 +19,48 @@ exports.getCommand = new commander_1.Command('get')
|
|
|
21
19
|
});
|
|
22
20
|
const response = await portal.getPortal(portalId);
|
|
23
21
|
const portalDetails = response.portal;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
logger.title('Portal details');
|
|
23
|
+
logger.label('ID', portalDetails.id);
|
|
24
|
+
logger.label('Name', portalDetails.name);
|
|
25
|
+
logger.label('URL', portalDetails.url);
|
|
26
|
+
logger.label('Access', portalDetails.access);
|
|
27
|
+
logger.label('Status', portalDetails.disabled ? 'Disabled' : 'Enabled');
|
|
30
28
|
if (portalDetails.title) {
|
|
31
|
-
|
|
29
|
+
logger.label('Title', portalDetails.title);
|
|
32
30
|
}
|
|
33
31
|
if (portalDetails.subtitle) {
|
|
34
|
-
|
|
32
|
+
logger.label('Subtitle', portalDetails.subtitle);
|
|
35
33
|
}
|
|
36
34
|
if (portalDetails.logo) {
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
logger.title('Assets');
|
|
36
|
+
logger.label('Logo', portalDetails.logo);
|
|
39
37
|
if (portalDetails.logodark) {
|
|
40
|
-
|
|
38
|
+
logger.label('Logo (dark mode)', portalDetails.logodark);
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
if (portalDetails.links && portalDetails.links.length > 0) {
|
|
44
|
-
|
|
42
|
+
logger.title('Links');
|
|
45
43
|
portalDetails.links.forEach((link) => {
|
|
46
|
-
|
|
44
|
+
logger.label(link.value, link.url);
|
|
47
45
|
});
|
|
48
46
|
}
|
|
49
47
|
if (portalDetails.agents && portalDetails.agents.length > 0) {
|
|
50
|
-
|
|
48
|
+
logger.title('Associated agents');
|
|
51
49
|
portalDetails.agents.forEach((agent) => {
|
|
52
|
-
|
|
50
|
+
logger.label(agent.name, agent.id);
|
|
53
51
|
});
|
|
54
52
|
}
|
|
55
53
|
if (options.dev) {
|
|
56
|
-
|
|
54
|
+
logger.warning('\nEnvironment: development');
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
catch (error) {
|
|
60
|
-
const message = error instanceof Error ? error.message : '
|
|
61
|
-
|
|
58
|
+
const message = error instanceof Error ? error.message : 'Unknown error while fetching portal details';
|
|
59
|
+
logger.error(message);
|
|
62
60
|
process.exit(1);
|
|
63
61
|
}
|
|
64
62
|
});
|
|
63
|
+
addExamples(getCommand, [
|
|
64
|
+
{ description: 'Show details for a specific portal',
|
|
65
|
+
command: 'plazbot portal get prt_AbcDef123' },
|
|
66
|
+
]);
|
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.
|
|
15
|
-
.addCommand(
|
|
16
|
-
.addCommand(
|
|
17
|
-
.addCommand(
|
|
18
|
-
.addCommand(
|
|
19
|
-
.addCommand(
|
|
20
|
-
.addCommand(
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addExamples } from '../../utils/help.js';
|
|
3
|
+
import { getCommand } from './get.js';
|
|
4
|
+
import { deleteCommand } from './delete.js';
|
|
5
|
+
import { createCommand } from './create.js';
|
|
6
|
+
import { updateCommand } from './update.js';
|
|
7
|
+
import { addAgentCommand } from './add-agent.js';
|
|
8
|
+
import { listCommand } from './list.js';
|
|
9
|
+
import { addLinkCommand } from './add-link.js';
|
|
10
|
+
import { clearLinksCommand } from './clear-links.js';
|
|
11
|
+
export const portalCommands = new Command('portal')
|
|
12
|
+
.description('Commands related to portals')
|
|
13
|
+
.addCommand(listCommand)
|
|
14
|
+
.addCommand(getCommand)
|
|
15
|
+
.addCommand(deleteCommand)
|
|
16
|
+
.addCommand(createCommand)
|
|
17
|
+
.addCommand(updateCommand)
|
|
18
|
+
.addCommand(addAgentCommand)
|
|
19
|
+
.addCommand(addLinkCommand)
|
|
20
|
+
.addCommand(clearLinksCommand);
|
|
21
|
+
addExamples(portalCommands, [
|
|
22
|
+
{ description: 'List the portal of the active workspace',
|
|
23
|
+
command: 'plazbot portal list' },
|
|
24
|
+
{ description: 'Create a portal',
|
|
25
|
+
command: 'plazbot portal create -n "Help Center" -t "Welcome"' },
|
|
26
|
+
{ description: 'Attach an agent to a portal',
|
|
27
|
+
command: 'plazbot portal add-agent-portal -p prt_AbcDef123 -a agt_AbcDef123' },
|
|
28
|
+
{ description: 'Add a link to a portal',
|
|
29
|
+
command: 'plazbot portal add-link prt_AbcDef123 -t "Docs" -u https://docs.example.com' },
|
|
30
|
+
]);
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.description('Muestra el portal asociado al workspace')
|
|
10
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Portal } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
export const listCommand = new Command('list')
|
|
7
|
+
.description('Show the portal associated with the workspace')
|
|
8
|
+
.option('--dev', 'Use development environment', false)
|
|
11
9
|
.action(async (options) => {
|
|
12
10
|
try {
|
|
13
11
|
// Obtener credenciales guardadas
|
|
14
|
-
const credentials = await
|
|
15
|
-
const portal = new
|
|
12
|
+
const credentials = await getStoredCredentials();
|
|
13
|
+
const portal = new Portal({
|
|
16
14
|
workspaceId: credentials.workspace,
|
|
17
15
|
apiKey: credentials.apiKey,
|
|
18
16
|
zone: credentials.zone,
|
|
@@ -20,45 +18,51 @@ exports.listCommand = new commander_1.Command('list')
|
|
|
20
18
|
});
|
|
21
19
|
const response = await portal.getExistsPortal();
|
|
22
20
|
const portalDetails = response.portal;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
logger.title('Portal found');
|
|
22
|
+
logger.label('ID', portalDetails.id);
|
|
23
|
+
logger.label('Name', portalDetails.name);
|
|
24
|
+
logger.label('URL', portalDetails.url);
|
|
25
|
+
logger.label('Access', portalDetails.access || 'N/A');
|
|
26
|
+
logger.label('Status', portalDetails.disabled ? 'Disabled' : 'Enabled');
|
|
29
27
|
if (portalDetails.title) {
|
|
30
|
-
|
|
28
|
+
logger.label('Title', portalDetails.title);
|
|
31
29
|
}
|
|
32
30
|
if (portalDetails.subtitle) {
|
|
33
|
-
|
|
31
|
+
logger.label('Subtitle', portalDetails.subtitle);
|
|
34
32
|
}
|
|
35
33
|
if (portalDetails.logo) {
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
logger.title('Assets');
|
|
35
|
+
logger.label('Logo', portalDetails.logo);
|
|
38
36
|
if (portalDetails.logodark) {
|
|
39
|
-
|
|
37
|
+
logger.label('Logo (dark mode)', portalDetails.logodark);
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
const portalAny = portalDetails;
|
|
43
41
|
if (portalAny.links && portalAny.links.length > 0) {
|
|
44
|
-
|
|
42
|
+
logger.title('Links');
|
|
45
43
|
portalAny.links.forEach((link) => {
|
|
46
|
-
|
|
44
|
+
logger.label(link.value, link.url);
|
|
47
45
|
});
|
|
48
46
|
}
|
|
49
47
|
if (portalAny.agents && portalAny.agents.length > 0) {
|
|
50
|
-
|
|
48
|
+
logger.title('Associated agents');
|
|
51
49
|
portalAny.agents.forEach((agent) => {
|
|
52
|
-
|
|
50
|
+
logger.label(agent.name, agent.id);
|
|
53
51
|
});
|
|
54
52
|
}
|
|
55
53
|
if (options.dev) {
|
|
56
|
-
|
|
54
|
+
logger.warning('\nEnvironment: development');
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
catch (error) {
|
|
60
|
-
const message = error instanceof Error ? error.message : '
|
|
61
|
-
|
|
58
|
+
const message = error instanceof Error ? error.message : 'Unknown error while listing the portal';
|
|
59
|
+
logger.error(message);
|
|
62
60
|
process.exit(1);
|
|
63
61
|
}
|
|
64
62
|
});
|
|
63
|
+
addExamples(listCommand, [
|
|
64
|
+
{ description: 'Show the portal of the active workspace',
|
|
65
|
+
command: 'plazbot portal list' },
|
|
66
|
+
{ description: 'Use the development backend',
|
|
67
|
+
command: 'plazbot portal list --dev' },
|
|
68
|
+
]);
|
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.
|
|
10
|
-
.
|
|
11
|
-
.option('-
|
|
12
|
-
.option('-
|
|
13
|
-
.option('-
|
|
14
|
-
.option('-
|
|
15
|
-
.option('
|
|
16
|
-
.option('-
|
|
17
|
-
.option('--
|
|
18
|
-
.option('--brand-off <value>', 'Estado de marca deshabilitada (true o false)')
|
|
19
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Portal } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
export const updateCommand = new Command('update')
|
|
7
|
+
.description('Update an existing portal')
|
|
8
|
+
.argument('<portalId>', 'ID of the portal to update')
|
|
9
|
+
.option('-n, --name <name>', 'New portal name')
|
|
10
|
+
.option('-t, --title <title>', 'New portal title')
|
|
11
|
+
.option('-s, --subtitle <subtitle>', 'New portal subtitle')
|
|
12
|
+
.option('-l, --logo <url>', 'New logo URL')
|
|
13
|
+
.option('-d, --logo-dark <url>', 'New dark-mode logo URL')
|
|
14
|
+
.option('-a, --access <type>', 'Access type (direct or form)')
|
|
15
|
+
.option('--disabled <value>', 'Disabled state (true or false)')
|
|
16
|
+
.option('--brand-off <value>', 'Brand-off state (true or false)')
|
|
17
|
+
.option('--dev', 'Use development environment', false)
|
|
20
18
|
.action(async (portalId, options) => {
|
|
21
19
|
try {
|
|
22
20
|
// Obtener credenciales guardadas
|
|
23
|
-
const credentials = await
|
|
24
|
-
const portal = new
|
|
21
|
+
const credentials = await getStoredCredentials();
|
|
22
|
+
const portal = new Portal({
|
|
25
23
|
workspaceId: credentials.workspace,
|
|
26
24
|
apiKey: credentials.apiKey,
|
|
27
25
|
zone: credentials.zone,
|
|
@@ -29,8 +27,8 @@ exports.updateCommand = new commander_1.Command('update')
|
|
|
29
27
|
});
|
|
30
28
|
// Obtener detalles actuales del portal
|
|
31
29
|
const currentPortal = await portal.getPortal(portalId);
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
logger.title('Current portal');
|
|
31
|
+
logger.json(currentPortal.portal);
|
|
34
32
|
// Construir objeto de actualización solo con los campos proporcionados
|
|
35
33
|
const updateData = { id: portalId };
|
|
36
34
|
if (options.name)
|
|
@@ -45,34 +43,44 @@ exports.updateCommand = new commander_1.Command('update')
|
|
|
45
43
|
updateData.logodark = options.logoDark;
|
|
46
44
|
if (options.access) {
|
|
47
45
|
if (options.access !== 'direct' && options.access !== 'form') {
|
|
48
|
-
throw new Error('
|
|
46
|
+
throw new Error('Access type must be "direct" or "form"');
|
|
49
47
|
}
|
|
50
48
|
updateData.access = options.access;
|
|
51
49
|
}
|
|
52
50
|
if (options.disabled) {
|
|
53
51
|
if (options.disabled !== 'true' && options.disabled !== 'false') {
|
|
54
|
-
throw new Error('
|
|
52
|
+
throw new Error('The disabled value must be "true" or "false"');
|
|
55
53
|
}
|
|
56
54
|
updateData.disabled = options.disabled === 'true';
|
|
57
55
|
}
|
|
58
56
|
if (options.brandOff) {
|
|
59
57
|
if (options.brandOff !== 'true' && options.brandOff !== 'false') {
|
|
60
|
-
throw new Error('
|
|
58
|
+
throw new Error('The brand-off value must be "true" or "false"');
|
|
61
59
|
}
|
|
62
60
|
updateData.brandOff = options.brandOff === 'true';
|
|
63
61
|
}
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
logger.title('Changes to apply');
|
|
63
|
+
logger.json(updateData);
|
|
66
64
|
const result = await portal.updatePortal(updateData);
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
logger.success('Portal updated successfully');
|
|
66
|
+
logger.label('Message', result.message);
|
|
69
67
|
if (options.dev) {
|
|
70
|
-
|
|
68
|
+
logger.warning('\nEnvironment: development');
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
catch (error) {
|
|
74
|
-
const message = error instanceof Error ? error.message : '
|
|
75
|
-
|
|
72
|
+
const message = error instanceof Error ? error.message : 'Unknown error while updating the portal';
|
|
73
|
+
logger.error(message);
|
|
76
74
|
process.exit(1);
|
|
77
75
|
}
|
|
78
76
|
});
|
|
77
|
+
addExamples(updateCommand, [
|
|
78
|
+
{ description: 'Rename a portal',
|
|
79
|
+
command: 'plazbot portal update prt_AbcDef123 -n "Support Center"' },
|
|
80
|
+
{ description: 'Switch access to form mode and update title',
|
|
81
|
+
command: 'plazbot portal update prt_AbcDef123 -a form -t "Sign in to continue"' },
|
|
82
|
+
{ description: 'Disable a portal',
|
|
83
|
+
command: 'plazbot portal update prt_AbcDef123 --disabled true' },
|
|
84
|
+
{ description: 'Hide the Plazbot brand and update the logo',
|
|
85
|
+
command: 'plazbot portal update prt_AbcDef123 --brand-off true -l https://files.example.com/logo.png' },
|
|
86
|
+
]);
|
|
@@ -1,26 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.
|
|
15
|
-
.requiredOption('-t, --template <name>', 'Nombre del template')
|
|
16
|
-
.requiredOption('--phones <file>', 'Archivo CSV con numeros de telefono (uno por linea)')
|
|
17
|
-
.option('--var <vars...>', 'Variables del body (formato: name=valor)')
|
|
18
|
-
.option('--delay <ms>', 'Delay entre mensajes en ms', '1000')
|
|
19
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Message } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import { theme, section, progressBar } from '../../utils/ui.js';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
export const broadcastCommand = new Command('broadcast')
|
|
9
|
+
.description('Bulk send WhatsApp template messages')
|
|
10
|
+
.requiredOption('-t, --template <name>', 'Template name')
|
|
11
|
+
.requiredOption('--phones <file>', 'CSV file with phone numbers (one per line)')
|
|
12
|
+
.option('--var <vars...>', 'Body variables (format: name=value)')
|
|
13
|
+
.option('--delay <ms>', 'Delay between messages in ms', '1000')
|
|
14
|
+
.option('--dev', 'Use development environment', false)
|
|
20
15
|
.action(async (options) => {
|
|
21
16
|
try {
|
|
22
|
-
const credentials = await
|
|
23
|
-
const messageClient = new
|
|
17
|
+
const credentials = await getStoredCredentials();
|
|
18
|
+
const messageClient = new Message({
|
|
24
19
|
workspaceId: credentials.workspace,
|
|
25
20
|
apiKey: credentials.apiKey,
|
|
26
21
|
zone: credentials.zone,
|
|
@@ -29,25 +24,25 @@ exports.broadcastCommand = new commander_1.Command('broadcast')
|
|
|
29
24
|
// Leer archivo de telefonos
|
|
30
25
|
let phones;
|
|
31
26
|
try {
|
|
32
|
-
const content = await
|
|
27
|
+
const content = await fs.readFile(options.phones, 'utf-8');
|
|
33
28
|
phones = content.split('\n')
|
|
34
29
|
.map(line => line.trim())
|
|
35
30
|
.filter(line => line && !line.startsWith('#'));
|
|
36
31
|
}
|
|
37
32
|
catch {
|
|
38
|
-
throw new Error(`
|
|
33
|
+
throw new Error(`Could not read file: ${options.phones}`);
|
|
39
34
|
}
|
|
40
35
|
if (phones.length === 0) {
|
|
41
|
-
throw new Error('
|
|
36
|
+
throw new Error('The file does not contain phone numbers');
|
|
42
37
|
}
|
|
43
38
|
// Parsear variables
|
|
44
39
|
const variablesBody = parseVariables(options.var);
|
|
45
|
-
console.log(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
console.log(section('WhatsApp Broadcast'));
|
|
41
|
+
logger.label('Template', options.template);
|
|
42
|
+
logger.label('Recipients', String(phones.length));
|
|
43
|
+
logger.label('Delay', `${options.delay}ms`);
|
|
49
44
|
if (variablesBody.length > 0) {
|
|
50
|
-
|
|
45
|
+
logger.label('Variables', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
|
|
51
46
|
}
|
|
52
47
|
console.log();
|
|
53
48
|
const delay = parseInt(options.delay) || 1000;
|
|
@@ -67,26 +62,34 @@ exports.broadcastCommand = new commander_1.Command('broadcast')
|
|
|
67
62
|
}
|
|
68
63
|
catch {
|
|
69
64
|
failed++;
|
|
70
|
-
console.log(
|
|
65
|
+
console.log(theme.error(` ✖ Failed: ${phone}`));
|
|
71
66
|
}
|
|
72
67
|
// Progress
|
|
73
|
-
console.log(` ${
|
|
68
|
+
console.log(` ${progressBar(i + 1, phones.length)}`);
|
|
74
69
|
// Rate limiting
|
|
75
70
|
if (i < phones.length - 1) {
|
|
76
71
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
|
-
console.log(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
console.log(section('Result'));
|
|
75
|
+
logger.label('Sent', theme.success(String(sent)));
|
|
76
|
+
logger.label('Failed', failed > 0 ? theme.error(String(failed)) : '0');
|
|
77
|
+
logger.label('Total', String(phones.length));
|
|
83
78
|
}
|
|
84
79
|
catch (error) {
|
|
85
|
-
const message = error?.message || '
|
|
86
|
-
|
|
80
|
+
const message = error?.message || 'Unknown error';
|
|
81
|
+
logger.error(message);
|
|
87
82
|
process.exit(1);
|
|
88
83
|
}
|
|
89
84
|
});
|
|
85
|
+
addExamples(broadcastCommand, [
|
|
86
|
+
{ description: 'Broadcast a template to a phone list (default 1s delay)',
|
|
87
|
+
command: 'plazbot whatsapp broadcast -t welcome --phones ./phones.csv' },
|
|
88
|
+
{ description: 'Broadcast with body variables',
|
|
89
|
+
command: 'plazbot whatsapp broadcast -t promo --phones ./contacts.csv --var amount=20 code=PROMO20' },
|
|
90
|
+
{ description: 'Slow broadcast (3s delay) to avoid rate limits',
|
|
91
|
+
command: 'plazbot whatsapp broadcast -t reminder --phones ./list.csv --delay 3000' },
|
|
92
|
+
]);
|
|
90
93
|
function parseVariables(vars) {
|
|
91
94
|
if (!vars)
|
|
92
95
|
return [];
|
|
@@ -1,32 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
.description('Listar agentes con canales de WhatsApp asignados')
|
|
11
|
-
.option('--dev', 'Usar ambiente de desarrollo', false)
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Agent } from 'plazbot';
|
|
3
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import { createSpinner, createTable, theme, section, statusBadge } from '../../utils/ui.js';
|
|
7
|
+
export const channelsCommand = new Command('channels')
|
|
8
|
+
.description('List agents with assigned WhatsApp channels')
|
|
9
|
+
.option('--dev', 'Use development environment', false)
|
|
12
10
|
.action(async (options) => {
|
|
13
11
|
try {
|
|
14
|
-
const credentials = await
|
|
15
|
-
const agent = new
|
|
12
|
+
const credentials = await getStoredCredentials();
|
|
13
|
+
const agent = new Agent({
|
|
16
14
|
workspaceId: credentials.workspace,
|
|
17
15
|
apiKey: credentials.apiKey,
|
|
18
16
|
zone: credentials.zone,
|
|
19
17
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
20
18
|
});
|
|
21
|
-
const spinner =
|
|
19
|
+
const spinner = createSpinner('Loading channels...');
|
|
22
20
|
spinner.start();
|
|
23
21
|
const agents = await agent.getAgents();
|
|
24
22
|
spinner.stop();
|
|
25
|
-
console.log(
|
|
23
|
+
console.log(section('WhatsApp Channels'));
|
|
26
24
|
const whatsappAgents = (agents || []).filter((a) => a.channels && a.channels.some((c) => c.channel === 'whatsapp'));
|
|
27
25
|
if (whatsappAgents.length === 0) {
|
|
28
|
-
console.log(
|
|
29
|
-
console.log(
|
|
26
|
+
console.log(theme.muted('\n No agents with WhatsApp configured'));
|
|
27
|
+
console.log(theme.muted(' Use the wizard: plazbot agent create\n'));
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
32
30
|
const rows = whatsappAgents.map((a) => {
|
|
@@ -35,32 +33,36 @@ exports.channelsCommand = new commander_1.Command('channels')
|
|
|
35
33
|
a.id || a._id,
|
|
36
34
|
a.name,
|
|
37
35
|
waChannel?.key || 'N/A',
|
|
38
|
-
|
|
36
|
+
statusBadge(a.enable !== false),
|
|
39
37
|
];
|
|
40
38
|
});
|
|
41
|
-
console.log(
|
|
39
|
+
console.log(createTable(['Agent ID', 'Name', 'WhatsApp Number', 'Status'], rows));
|
|
42
40
|
}
|
|
43
41
|
catch (error) {
|
|
44
|
-
const message = error instanceof Error ? error.message : '
|
|
45
|
-
|
|
42
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
43
|
+
logger.error(message);
|
|
46
44
|
process.exit(1);
|
|
47
45
|
}
|
|
48
46
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
addExamples(channelsCommand, [
|
|
48
|
+
{ description: 'List agents that have a WhatsApp number assigned',
|
|
49
|
+
command: 'plazbot whatsapp channels' },
|
|
50
|
+
]);
|
|
51
|
+
export const assignCommand = new Command('assign')
|
|
52
|
+
.description('Assign an agent to a WhatsApp number')
|
|
53
|
+
.argument('<phone>', 'WhatsApp number')
|
|
54
|
+
.argument('<agentId>', 'Agent ID')
|
|
55
|
+
.option('--dev', 'Use development environment', false)
|
|
54
56
|
.action(async (phone, agentId, options) => {
|
|
55
57
|
try {
|
|
56
|
-
const credentials = await
|
|
57
|
-
const agent = new
|
|
58
|
+
const credentials = await getStoredCredentials();
|
|
59
|
+
const agent = new Agent({
|
|
58
60
|
workspaceId: credentials.workspace,
|
|
59
61
|
apiKey: credentials.apiKey,
|
|
60
62
|
zone: credentials.zone,
|
|
61
63
|
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
62
64
|
});
|
|
63
|
-
const spinner =
|
|
65
|
+
const spinner = createSpinner('Loading agent...');
|
|
64
66
|
spinner.start();
|
|
65
67
|
const agentData = await agent.getAgentById({ id: agentId });
|
|
66
68
|
spinner.stop();
|
|
@@ -68,19 +70,23 @@ exports.assignCommand = new commander_1.Command('assign')
|
|
|
68
70
|
// Verificar si ya tiene este canal
|
|
69
71
|
const existing = channels.findIndex((c) => c.channel === 'whatsapp' && c.key === phone);
|
|
70
72
|
if (existing >= 0) {
|
|
71
|
-
|
|
73
|
+
logger.warning('This number is already assigned to this agent');
|
|
72
74
|
return;
|
|
73
75
|
}
|
|
74
76
|
// Agregar canal
|
|
75
77
|
channels.push({ channel: 'whatsapp', key: phone, multianswer: false });
|
|
76
|
-
const updateSpinner =
|
|
78
|
+
const updateSpinner = createSpinner('Assigning...');
|
|
77
79
|
updateSpinner.start();
|
|
78
80
|
await agent.updateAgent(agentId, { channels });
|
|
79
|
-
updateSpinner.succeed(`
|
|
81
|
+
updateSpinner.succeed(`Agent "${agentData.name}" assigned to WhatsApp ${phone}`);
|
|
80
82
|
}
|
|
81
83
|
catch (error) {
|
|
82
|
-
const message = error instanceof Error ? error.message : '
|
|
83
|
-
|
|
84
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
85
|
+
logger.error(message);
|
|
84
86
|
process.exit(1);
|
|
85
87
|
}
|
|
86
88
|
});
|
|
89
|
+
addExamples(assignCommand, [
|
|
90
|
+
{ description: 'Assign a WhatsApp number to an agent',
|
|
91
|
+
command: 'plazbot whatsapp assign 51912345678 agt_AbcDef123' },
|
|
92
|
+
]);
|