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.
Files changed (178) hide show
  1. package/CLAUDE.md +34 -5
  2. package/README.md +21 -0
  3. package/dist/cli.js +32 -20
  4. package/dist/commands/agent/ai-config.js +98 -50
  5. package/dist/commands/agent/chat.js +80 -74
  6. package/dist/commands/agent/copy.js +23 -21
  7. package/dist/commands/agent/create.js +42 -72
  8. package/dist/commands/agent/delete.js +29 -30
  9. package/dist/commands/agent/enable-widget.js +30 -26
  10. package/dist/commands/agent/export.js +90 -77
  11. package/dist/commands/agent/files.js +68 -60
  12. package/dist/commands/agent/get.js +101 -87
  13. package/dist/commands/agent/index.js +53 -39
  14. package/dist/commands/agent/list.js +26 -24
  15. package/dist/commands/agent/monitor.js +91 -86
  16. package/dist/commands/agent/on-message.js +40 -37
  17. package/dist/commands/agent/set.js +62 -59
  18. package/dist/commands/agent/templates.js +109 -108
  19. package/dist/commands/agent/tools.js +64 -65
  20. package/dist/commands/agent/update.js +28 -27
  21. package/dist/commands/agent/validate.js +127 -0
  22. package/dist/commands/agent/wizard.js +152 -159
  23. package/dist/commands/auth/index.js +7 -10
  24. package/dist/commands/auth/login.js +50 -37
  25. package/dist/commands/auth/logout.js +16 -14
  26. package/dist/commands/auth/status.js +19 -16
  27. package/dist/commands/portal/add-agent.js +26 -24
  28. package/dist/commands/portal/add-link.js +21 -17
  29. package/dist/commands/portal/clear-links.js +17 -15
  30. package/dist/commands/portal/create.js +25 -21
  31. package/dist/commands/portal/delete.js +31 -30
  32. package/dist/commands/portal/get.js +33 -31
  33. package/dist/commands/portal/index.js +30 -22
  34. package/dist/commands/portal/list.js +34 -30
  35. package/dist/commands/portal/update.js +41 -33
  36. package/dist/commands/whatsapp/broadcast.js +40 -37
  37. package/dist/commands/whatsapp/channels.js +40 -34
  38. package/dist/commands/whatsapp/chat.js +33 -32
  39. package/dist/commands/whatsapp/connect.js +53 -52
  40. package/dist/commands/whatsapp/delete-webhook.js +19 -17
  41. package/dist/commands/whatsapp/index.js +35 -25
  42. package/dist/commands/whatsapp/register-webhook.js +21 -19
  43. package/dist/commands/whatsapp/send-template.js +39 -31
  44. package/dist/commands/whatsapp/send.js +27 -23
  45. package/dist/commands/whatsapp/widget.js +35 -31
  46. package/dist/commands/workers/deploy.js +49 -44
  47. package/dist/commands/workers/index.js +28 -18
  48. package/dist/commands/workers/list.js +43 -35
  49. package/dist/commands/workers/logs.js +38 -32
  50. package/dist/commands/workers/remove.js +38 -37
  51. package/dist/commands/workers/secret.js +63 -58
  52. package/dist/commands/workers/test.js +44 -36
  53. package/dist/schemas/agent.config.schema.json +569 -0
  54. package/dist/studio/api/sseClient.js +97 -0
  55. package/dist/studio/api/studioApi.js +25 -0
  56. package/dist/studio/api/types.js +16 -0
  57. package/dist/studio/components/AgentPanel.js +35 -0
  58. package/dist/studio/components/App.js +214 -0
  59. package/dist/studio/components/ChatLog.js +59 -0
  60. package/dist/studio/components/Footer.js +11 -0
  61. package/dist/studio/components/Header.js +8 -0
  62. package/dist/studio/components/Input.js +15 -0
  63. package/dist/studio/components/Message.js +56 -0
  64. package/dist/studio/components/Suggestions.js +11 -0
  65. package/dist/studio/components/ToolCall.js +33 -0
  66. package/dist/studio/components/WhatsappConnectCard.js +57 -0
  67. package/dist/studio/index.js +42 -0
  68. package/dist/studio/render/json.js +16 -0
  69. package/dist/studio/render/markdown.js +32 -0
  70. package/dist/studio/render/steps.js +58 -0
  71. package/dist/studio/runOneShot.js +96 -0
  72. package/dist/studio/runRepl.js +52 -0
  73. package/dist/studio/slash/handlers.js +199 -0
  74. package/dist/studio/slash/parser.js +46 -0
  75. package/dist/studio/slash/registry.js +16 -0
  76. package/dist/studio/state/store.js +181 -0
  77. package/dist/studio/whatsapp/api.js +63 -0
  78. package/dist/studio/whatsapp/polling.js +77 -0
  79. package/dist/studio/whatsapp/types.js +31 -0
  80. package/dist/types/agent.js +1 -2
  81. package/dist/types/auth.js +1 -2
  82. package/dist/types/common.js +1 -2
  83. package/dist/types/message.js +1 -2
  84. package/dist/types/portal.js +1 -2
  85. package/dist/types/workers.js +1 -2
  86. package/dist/utils/agent-errors.js +46 -0
  87. package/dist/utils/api.js +8 -9
  88. package/dist/utils/banner.js +33 -34
  89. package/dist/utils/credentials.js +12 -20
  90. package/dist/utils/help.js +44 -0
  91. package/dist/utils/logger.js +13 -19
  92. package/dist/utils/ui.js +35 -49
  93. package/package.json +21 -10
  94. package/src/cli.ts +24 -8
  95. package/src/commands/agent/ai-config.ts +89 -34
  96. package/src/commands/agent/chat.ts +49 -37
  97. package/src/commands/agent/copy.ts +19 -13
  98. package/src/commands/agent/create.ts +32 -22
  99. package/src/commands/agent/delete.ts +24 -18
  100. package/src/commands/agent/enable-widget.ts +31 -23
  101. package/src/commands/agent/export.ts +72 -51
  102. package/src/commands/agent/files.ts +51 -39
  103. package/src/commands/agent/get.ts +86 -66
  104. package/src/commands/agent/index.ts +36 -18
  105. package/src/commands/agent/list.ts +22 -16
  106. package/src/commands/agent/monitor.ts +67 -56
  107. package/src/commands/agent/on-message.ts +36 -27
  108. package/src/commands/agent/set.ts +47 -37
  109. package/src/commands/agent/templates.ts +90 -82
  110. package/src/commands/agent/tools.ts +53 -47
  111. package/src/commands/agent/update.ts +28 -20
  112. package/src/commands/agent/validate.ts +135 -0
  113. package/src/commands/agent/wizard.ts +114 -114
  114. package/src/commands/auth/index.ts +3 -3
  115. package/src/commands/auth/login.ts +44 -29
  116. package/src/commands/auth/logout.ts +16 -10
  117. package/src/commands/auth/status.ts +14 -8
  118. package/src/commands/portal/add-agent.ts +23 -17
  119. package/src/commands/portal/add-link.ts +17 -9
  120. package/src/commands/portal/clear-links.ts +13 -7
  121. package/src/commands/portal/create.ts +20 -12
  122. package/src/commands/portal/delete.ts +28 -20
  123. package/src/commands/portal/get.ts +25 -19
  124. package/src/commands/portal/index.ts +22 -10
  125. package/src/commands/portal/list.ts +27 -19
  126. package/src/commands/portal/update.ts +38 -26
  127. package/src/commands/whatsapp/broadcast.ts +28 -18
  128. package/src/commands/whatsapp/channels.ts +31 -20
  129. package/src/commands/whatsapp/chat.ts +20 -12
  130. package/src/commands/whatsapp/connect.ts +39 -31
  131. package/src/commands/whatsapp/delete-webhook.ts +15 -9
  132. package/src/commands/whatsapp/index.ts +24 -10
  133. package/src/commands/whatsapp/register-webhook.ts +16 -10
  134. package/src/commands/whatsapp/send-template.ts +33 -21
  135. package/src/commands/whatsapp/send.ts +23 -15
  136. package/src/commands/whatsapp/widget.ts +25 -17
  137. package/src/commands/workers/deploy.ts +34 -22
  138. package/src/commands/workers/index.ts +21 -7
  139. package/src/commands/workers/list.ts +31 -19
  140. package/src/commands/workers/logs.ts +30 -20
  141. package/src/commands/workers/remove.ts +30 -22
  142. package/src/commands/workers/secret.ts +46 -34
  143. package/src/commands/workers/test.ts +34 -22
  144. package/src/schemas/agent.config.schema.json +569 -0
  145. package/src/studio/api/sseClient.ts +91 -0
  146. package/src/studio/api/studioApi.ts +27 -0
  147. package/src/studio/api/types.ts +96 -0
  148. package/src/studio/components/App.tsx +266 -0
  149. package/src/studio/components/ChatLog.tsx +95 -0
  150. package/src/studio/components/Footer.tsx +38 -0
  151. package/src/studio/components/Header.tsx +39 -0
  152. package/src/studio/components/Input.tsx +32 -0
  153. package/src/studio/components/Message.tsx +87 -0
  154. package/src/studio/components/Suggestions.tsx +26 -0
  155. package/src/studio/components/ToolCall.tsx +58 -0
  156. package/src/studio/components/WhatsappConnectCard.tsx +139 -0
  157. package/src/studio/index.ts +58 -0
  158. package/src/studio/render/markdown.ts +32 -0
  159. package/src/studio/render/steps.ts +57 -0
  160. package/src/studio/runOneShot.ts +114 -0
  161. package/src/studio/runRepl.tsx +76 -0
  162. package/src/studio/slash/handlers.ts +226 -0
  163. package/src/studio/slash/parser.ts +41 -0
  164. package/src/studio/slash/registry.ts +54 -0
  165. package/src/studio/state/store.ts +273 -0
  166. package/src/studio/whatsapp/api.ts +96 -0
  167. package/src/studio/whatsapp/polling.ts +93 -0
  168. package/src/studio/whatsapp/types.ts +80 -0
  169. package/src/types/agent.ts +1 -1
  170. package/src/types/auth.ts +4 -3
  171. package/src/types/portal.ts +1 -1
  172. package/src/types/workers.ts +1 -1
  173. package/src/utils/agent-errors.ts +67 -0
  174. package/src/utils/api.ts +6 -0
  175. package/src/utils/banner.ts +14 -9
  176. package/src/utils/credentials.ts +6 -5
  177. package/src/utils/help.ts +51 -0
  178. package/tsconfig.json +9 -6
@@ -2,9 +2,10 @@ import { Command } from 'commander';
2
2
  import axios from 'axios';
3
3
  import ora from 'ora';
4
4
  import chalk from 'chalk';
5
- import { getStoredCredentials } from '../../utils/credentials';
6
- import { logger } from '../../utils/logger';
7
- import { theme, section } from '../../utils/ui';
5
+ import { getStoredCredentials } from '../../utils/credentials.js';
6
+ import { logger } from '../../utils/logger.js';
7
+ import { addExamples } from '../../utils/help.js';
8
+ import { theme, section } from '../../utils/ui.js';
8
9
 
9
10
  function getBaseUrl(zone: string, dev: boolean): string {
10
11
  if (dev) return 'http://localhost:5090';
@@ -44,9 +45,9 @@ async function activateIntegration(baseUrl: string, workspaceId: string, integra
44
45
  }
45
46
 
46
47
  export const whatsappConnectCommand = new Command('connect')
47
- .description('Conectar un numero de WhatsApp al workspace (sin crear agente)')
48
- .option('--dev', 'Usar ambiente de desarrollo', false)
49
- .option('--business', 'Conectar como WhatsApp Business', false)
48
+ .description('Connect a WhatsApp number to the workspace (without creating an agent)')
49
+ .option('--dev', 'Use development environment', false)
50
+ .option('--business', 'Connect as WhatsApp Business', false)
50
51
  .action(async (options: any) => {
51
52
  try {
52
53
  const credentials = await getStoredCredentials();
@@ -60,20 +61,20 @@ export const whatsappConnectCommand = new Command('connect')
60
61
  const channelType = options.business ? 'whatsapp_business' : 'whatsapp';
61
62
  const channelLabel = options.business ? 'WhatsApp Business' : 'WhatsApp';
62
63
 
63
- console.log(section(`Conectar ${channelLabel}`));
64
+ console.log(section(`Connect ${channelLabel}`));
64
65
  console.log();
65
66
 
66
67
  // Cargar integraciones existentes
67
- const loadSpinner = ora({ text: chalk.gray('Cargando integraciones existentes...'), spinner: 'dots', color: 'green' }).start();
68
+ const loadSpinner = ora({ text: chalk.gray('Loading existing integrations...'), spinner: 'dots', color: 'green' }).start();
68
69
  const allIntegrations = await fetchWorkspaceIntegrations(baseUrl, credentials.workspace, headers);
69
70
  const existing = allIntegrations.filter((ig: any) => ig.type === 'whatsapp');
70
71
  loadSpinner.stop();
71
72
 
72
73
  if (existing.length > 0) {
73
- console.log(theme.muted(` ${existing.length} numero(s) ya conectado(s):`));
74
+ console.log(theme.muted(` ${existing.length} number(s) already connected:`));
74
75
  existing.forEach((ig: any) => {
75
76
  const label = getIntegrationLabel(ig);
76
- const status = ig.isActive ? chalk.hex('#66BB6A')('activo') : chalk.hex('#EF5350')('inactivo');
77
+ const status = ig.isActive ? chalk.hex('#66BB6A')('active') : chalk.hex('#EF5350')('inactive');
77
78
  console.log(` ${theme.muted('•')} ${label} ${status}`);
78
79
  });
79
80
  console.log();
@@ -81,7 +82,7 @@ export const whatsappConnectCommand = new Command('connect')
81
82
 
82
83
  // Obtener o generar link de onboarding (mismo flujo que Plazbot Front)
83
84
  const ONBOARDING_SHORT_DOMAIN = 'https://co.plzb.link';
84
- const spinner = ora({ text: chalk.gray('Obteniendo link de conexion...'), spinner: 'dots', color: 'green' }).start();
85
+ const spinner = ora({ text: chalk.gray('Fetching connection link...'), spinner: 'dots', color: 'green' }).start();
85
86
 
86
87
  let linkData: any = null;
87
88
 
@@ -125,12 +126,12 @@ export const whatsappConnectCommand = new Command('connect')
125
126
  }
126
127
 
127
128
  if (!linkData?.token) {
128
- spinner.fail(chalk.hex('#EF5350')('No se pudo obtener el link de conexion'));
129
+ spinner.fail(chalk.hex('#EF5350')('Could not obtain the connection link'));
129
130
  process.exit(1);
130
131
  }
131
132
 
132
133
  const shortUrl = `${ONBOARDING_SHORT_DOMAIN}/${linkData.token}`;
133
- const expiresAt = linkData.expiresAt ? new Date(linkData.expiresAt).toLocaleDateString('es-ES', { day: 'numeric', month: 'long', year: 'numeric' }) : '';
134
+ const expiresAt = linkData.expiresAt ? new Date(linkData.expiresAt).toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric' }) : '';
134
135
  spinner.stop();
135
136
 
136
137
  // Mostrar link
@@ -139,13 +140,13 @@ export const whatsappConnectCommand = new Command('connect')
139
140
  const border = chalk.hex('#25D366');
140
141
 
141
142
  console.log(border(' ┌' + '─'.repeat(W) + '┐'));
142
- console.log(border(' │') + chalk.bold(pad(' Abre este link en tu navegador:')) + border('│'));
143
+ console.log(border(' │') + chalk.bold(pad(' Open this link in your browser:')) + border('│'));
143
144
  console.log(border(' │') + ' '.repeat(W) + border('│'));
144
145
  console.log(border(' │') + chalk.hex('#22d3ee')(pad(` ${shortUrl}`)) + border('│'));
145
146
  console.log(border(' │') + ' '.repeat(W) + border('│'));
146
- console.log(border(' │') + chalk.gray(pad(' Escanea el codigo QR desde tu WhatsApp')) + border('│'));
147
+ console.log(border(' │') + chalk.gray(pad(' Scan the QR code from your WhatsApp')) + border('│'));
147
148
  if (expiresAt) {
148
- console.log(border(' │') + chalk.gray(pad(` Expira: ${expiresAt}`)) + border('│'));
149
+ console.log(border(' │') + chalk.gray(pad(` Expires: ${expiresAt}`)) + border('│'));
149
150
  }
150
151
  console.log(border(' └' + '─'.repeat(W) + '┘'));
151
152
  console.log();
@@ -154,7 +155,7 @@ export const whatsappConnectCommand = new Command('connect')
154
155
  const prevIds = new Set(allIntegrations.map((i: any) => i.id));
155
156
 
156
157
  // Polling para detectar nueva integracion
157
- const pollSpinner = ora({ text: chalk.gray('Esperando conexion... (Ctrl+C para cancelar)'), spinner: 'dots', color: 'cyan' }).start();
158
+ const pollSpinner = ora({ text: chalk.gray('Waiting for connection... (Ctrl+C to cancel)'), spinner: 'dots', color: 'cyan' }).start();
158
159
  const POLL_INTERVAL = 5000;
159
160
  const MAX_POLLS = 60; // 5 minutos
160
161
  let detected: any = null;
@@ -173,40 +174,47 @@ export const whatsappConnectCommand = new Command('connect')
173
174
  } catch {}
174
175
 
175
176
  const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
176
- pollSpinner.text = chalk.gray(`Esperando conexion... ${elapsed}s (Ctrl+C para cancelar)`);
177
+ pollSpinner.text = chalk.gray(`Waiting for connection... ${elapsed}s (Ctrl+C to cancel)`);
177
178
  }
178
179
 
179
180
  if (detected) {
180
181
  const detectedName = getIntegrationLabel(detected);
181
- pollSpinner.succeed(chalk.hex('#4ade80')(`Conexion detectada: ${detectedName}`));
182
+ pollSpinner.succeed(chalk.hex('#4ade80')(`Connection detected: ${detectedName}`));
182
183
 
183
184
  // Activar la integracion
184
- const actSpinner = ora({ text: chalk.gray('Activando integracion...'), spinner: 'dots', color: 'green' }).start();
185
+ const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
185
186
  const activated = await activateIntegration(baseUrl, credentials.workspace, detected.id, headers);
186
187
  if (activated) {
187
- actSpinner.succeed(chalk.hex('#4ade80')('Integracion activada correctamente'));
188
+ actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully'));
188
189
  } else {
189
- actSpinner.warn(chalk.hex('#FFA726')('No se pudo activar automaticamente. Activala desde la plataforma.'));
190
+ actSpinner.warn(chalk.hex('#FFA726')('Could not activate automatically. Activate it from the platform.'));
190
191
  }
191
192
 
192
193
  console.log();
193
- console.log(theme.success(' WhatsApp conectado exitosamente'));
194
- console.log(theme.muted(` Numero: ${detectedName}`));
194
+ console.log(theme.success(' WhatsApp connected successfully'));
195
+ console.log(theme.muted(` Number: ${detectedName}`));
195
196
  console.log();
196
- console.log(theme.muted(' Ahora puedes:'));
197
- console.log(theme.muted(' plazbot whatsapp send-message Enviar un mensaje'));
198
- console.log(theme.muted(' plazbot whatsapp chat <phone> Chat interactivo'));
199
- console.log(theme.muted(' plazbot whatsapp assign <phone> <agentId> Asignar a un agente'));
197
+ console.log(theme.muted(' You can now:'));
198
+ console.log(theme.muted(' plazbot whatsapp send-message Send a message'));
199
+ console.log(theme.muted(' plazbot whatsapp chat <phone> Interactive chat'));
200
+ console.log(theme.muted(' plazbot whatsapp assign <phone> <agentId> Assign to an agent'));
200
201
  console.log();
201
202
  } else {
202
- pollSpinner.warn(chalk.hex('#FFA726')('Timeout: no se detecto conexion en 5 minutos.'));
203
- console.log(theme.muted(' Puedes volver a intentar con: plazbot whatsapp connect'));
203
+ pollSpinner.warn(chalk.hex('#FFA726')('Timeout: no connection detected within 5 minutes.'));
204
+ console.log(theme.muted(' You can try again with: plazbot whatsapp connect'));
204
205
  console.log();
205
206
  }
206
207
 
207
208
  } catch (error) {
208
- const message = error instanceof Error ? error.message : 'Error desconocido';
209
+ const message = error instanceof Error ? error.message : 'Unknown error';
209
210
  logger.error(message);
210
211
  process.exit(1);
211
212
  }
212
213
  });
214
+
215
+ addExamples(whatsappConnectCommand, [
216
+ { description: 'Generate a QR connection link for WhatsApp',
217
+ command: 'plazbot whatsapp connect' },
218
+ { description: 'Connect a WhatsApp Business number',
219
+ command: 'plazbot whatsapp connect --business' },
220
+ ]);
@@ -1,7 +1,8 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
5
6
 
6
7
  interface DeleteWebhookOptions {
7
8
  dev?: boolean;
@@ -9,9 +10,9 @@ interface DeleteWebhookOptions {
9
10
  }
10
11
 
11
12
  export const deleteWebhookCommand = new Command('delete-webhook')
12
- .description('Elimina el webhook de WhatsApp')
13
- .requiredOption('-n, --number <phone>', 'Número de WhatsApp (con código de país, ej: 51912345678)')
14
- .option('--dev', 'Usar ambiente de desarrollo', false)
13
+ .description('Delete the WhatsApp webhook')
14
+ .requiredOption('-n, --number <phone>', 'WhatsApp number (with country code, e.g.: 51912345678)')
15
+ .option('--dev', 'Use development environment', false)
15
16
  .action(async (options: DeleteWebhookOptions) => {
16
17
  try {
17
18
  const credentials = await getStoredCredentials();
@@ -22,16 +23,21 @@ export const deleteWebhookCommand = new Command('delete-webhook')
22
23
  ...(options.dev && { customUrl: "http://localhost:5090" })
23
24
  });
24
25
 
25
- logger.title('Eliminando webhook de WhatsApp');
26
- logger.label('Numero', options.number);
26
+ logger.title('Deleting WhatsApp webhook');
27
+ logger.label('Number', options.number);
27
28
 
28
29
  await messageClient.deleteWebhook({
29
30
  number: options.number
30
31
  });
31
32
 
32
- logger.success('Webhook eliminado exitosamente');
33
+ logger.success('Webhook deleted successfully');
33
34
  } catch (error: unknown) {
34
35
  logger.error((error as Error).message);
35
36
  process.exit(1);
36
37
  }
37
- });
38
+ });
39
+
40
+ addExamples(deleteWebhookCommand, [
41
+ { description: 'Remove the webhook from a WhatsApp number',
42
+ command: 'plazbot whatsapp delete-webhook -n 51912345678' },
43
+ ]);
@@ -1,16 +1,17 @@
1
1
  import { Command } from 'commander';
2
- import { sendMessageCommand } from './send';
3
- import { sendTemplateCommand } from './send-template';
4
- import { registerWebhookCommand } from './register-webhook';
5
- import { deleteWebhookCommand } from './delete-webhook';
6
- import { broadcastCommand } from './broadcast';
7
- import { whatsappChatCommand } from './chat';
8
- import { whatsappConnectCommand } from './connect';
9
- import { widgetCommand } from './widget';
10
- import { channelsCommand, assignCommand } from './channels';
2
+ import { addExamples } from '../../utils/help.js';
3
+ import { sendMessageCommand } from './send.js';
4
+ import { sendTemplateCommand } from './send-template.js';
5
+ import { registerWebhookCommand } from './register-webhook.js';
6
+ import { deleteWebhookCommand } from './delete-webhook.js';
7
+ import { broadcastCommand } from './broadcast.js';
8
+ import { whatsappChatCommand } from './chat.js';
9
+ import { whatsappConnectCommand } from './connect.js';
10
+ import { widgetCommand } from './widget.js';
11
+ import { channelsCommand, assignCommand } from './channels.js';
11
12
 
12
13
  export const whatsappCommands = new Command('whatsapp')
13
- .description('Comandos de WhatsApp: mensajes, templates, broadcast y mas')
14
+ .description('WhatsApp commands: messages, templates, broadcast and more')
14
15
  .addCommand(whatsappConnectCommand)
15
16
  .addCommand(sendMessageCommand)
16
17
  .addCommand(sendTemplateCommand)
@@ -21,3 +22,16 @@ export const whatsappCommands = new Command('whatsapp')
21
22
  .addCommand(widgetCommand)
22
23
  .addCommand(channelsCommand)
23
24
  .addCommand(assignCommand);
25
+
26
+ addExamples(whatsappCommands, [
27
+ { description: 'Connect a WhatsApp number to the workspace',
28
+ command: 'plazbot whatsapp connect' },
29
+ { description: 'Send a quick message',
30
+ command: 'plazbot whatsapp send-message -t 51912345678 -m "Hello"' },
31
+ { description: 'Send a template with variables',
32
+ command: 'plazbot whatsapp send-template -p 51912345678 -t welcome --var name=Anna' },
33
+ { description: 'Open an interactive chat',
34
+ command: 'plazbot whatsapp chat 51912345678' },
35
+ { description: 'Assign a number to an agent',
36
+ command: 'plazbot whatsapp assign 51912345678 agt_AbcDef123' },
37
+ ]);
@@ -1,7 +1,8 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
5
6
 
6
7
  interface RegisterWebhookOptions {
7
8
  dev?: boolean;
@@ -10,10 +11,10 @@ interface RegisterWebhookOptions {
10
11
  }
11
12
 
12
13
  export const registerWebhookCommand = new Command('register-webhook')
13
- .description('Registra un webhook para WhatsApp')
14
- .requiredOption('-n, --number <phone>', 'Número de WhatsApp (con código de país, ej: 51912345678)')
15
- .requiredOption('-u, --url <webhook>', 'URL del webhook')
16
- .option('--dev', 'Usar ambiente de desarrollo', false)
14
+ .description('Register a webhook for WhatsApp')
15
+ .requiredOption('-n, --number <phone>', 'WhatsApp number (with country code, e.g.: 51912345678)')
16
+ .requiredOption('-u, --url <webhook>', 'Webhook URL')
17
+ .option('--dev', 'Use development environment', false)
17
18
  .action(async (options: RegisterWebhookOptions) => {
18
19
  try {
19
20
  const credentials = await getStoredCredentials();
@@ -24,8 +25,8 @@ export const registerWebhookCommand = new Command('register-webhook')
24
25
  ...(options.dev && { customUrl: "http://localhost:5090" })
25
26
  });
26
27
 
27
- logger.title('Registrando webhook de WhatsApp');
28
- logger.label('Numero', options.number);
28
+ logger.title('Registering WhatsApp webhook');
29
+ logger.label('Number', options.number);
29
30
  logger.label('URL', options.url);
30
31
 
31
32
  await messageClient.registerWebhook({
@@ -33,9 +34,14 @@ export const registerWebhookCommand = new Command('register-webhook')
33
34
  webhookUrl: options.url
34
35
  });
35
36
 
36
- logger.success('Webhook registrado exitosamente');
37
+ logger.success('Webhook registered successfully');
37
38
  } catch (error: unknown) {
38
39
  logger.error((error as Error).message);
39
40
  process.exit(1);
40
41
  }
41
- });
42
+ });
43
+
44
+ addExamples(registerWebhookCommand, [
45
+ { description: 'Register an inbound webhook for a WhatsApp number',
46
+ command: 'plazbot whatsapp register-webhook -n 51912345678 -u https://api.example.com/webhooks/whatsapp' },
47
+ ]);
@@ -1,18 +1,19 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { createSpinner } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { createSpinner } from '../../utils/ui.js';
6
7
 
7
8
  export const sendTemplateCommand = new Command('send-template')
8
- .description('Envia un mensaje de template de WhatsApp con variables')
9
- .requiredOption('-p, --phone <number>', 'Numero de telefono (con codigo de pais)')
10
- .requiredOption('-t, --template <name>', 'Nombre del template')
11
- .option('--var <vars...>', 'Variables del body (formato: name=valor)')
12
- .option('--header-var <vars...>', 'Variables del header (formato: name=valor)')
13
- .option('--file-url <url>', 'URL del archivo adjunto')
14
- .option('--file-name <name>', 'Nombre del archivo adjunto')
15
- .option('--dev', 'Usar ambiente de desarrollo', false)
9
+ .description('Send a WhatsApp template message with variables')
10
+ .requiredOption('-p, --phone <number>', 'Phone number (with country code)')
11
+ .requiredOption('-t, --template <name>', 'Template name')
12
+ .option('--var <vars...>', 'Body variables (format: name=value)')
13
+ .option('--header-var <vars...>', 'Header variables (format: name=value)')
14
+ .option('--file-url <url>', 'Attachment file URL')
15
+ .option('--file-name <name>', 'Attachment file name')
16
+ .option('--dev', 'Use development environment', false)
16
17
  .action(async (options: any) => {
17
18
  try {
18
19
  const credentials = await getStoredCredentials();
@@ -31,23 +32,23 @@ export const sendTemplateCommand = new Command('send-template')
31
32
  // Archivo adjunto
32
33
  const file = options.fileUrl ? {
33
34
  fileUrl: options.fileUrl,
34
- fileName: options.fileName || 'archivo',
35
+ fileName: options.fileName || 'file',
35
36
  } : undefined;
36
37
 
37
- logger.title('Enviando template WhatsApp');
38
- logger.label('Destino', options.phone);
38
+ logger.title('Sending WhatsApp template');
39
+ logger.label('Destination', options.phone);
39
40
  logger.label('Template', options.template);
40
41
  if (variablesBody.length > 0) {
41
- logger.label('Variables body', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
42
+ logger.label('Body variables', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
42
43
  }
43
44
  if (variablesHeader.length > 0) {
44
- logger.label('Variables header', variablesHeader.map(v => `${v.variable}=${v.value}`).join(', '));
45
+ logger.label('Header variables', variablesHeader.map(v => `${v.variable}=${v.value}`).join(', '));
45
46
  }
46
47
  if (file) {
47
- logger.label('Archivo', file.fileUrl);
48
+ logger.label('File', file.fileUrl);
48
49
  }
49
50
 
50
- const spinner = createSpinner('Enviando...');
51
+ const spinner = createSpinner('Sending...');
51
52
  spinner.start();
52
53
 
53
54
  const params: any = {
@@ -60,19 +61,30 @@ export const sendTemplateCommand = new Command('send-template')
60
61
 
61
62
  const response = await messageClient.onConversation(params);
62
63
 
63
- spinner.succeed('Template enviado exitosamente');
64
+ spinner.succeed('Template sent successfully');
64
65
 
65
66
  if (options.dev) {
66
- logger.warning('Ambiente: desarrollo');
67
+ logger.warning('Environment: development');
67
68
  }
68
69
 
69
70
  } catch (error: unknown) {
70
- const message = (error as Error)?.message || 'Error desconocido al enviar el template';
71
+ const message = (error as Error)?.message || 'Unknown error while sending the template';
71
72
  logger.error(message);
72
73
  process.exit(1);
73
74
  }
74
75
  });
75
76
 
77
+ addExamples(sendTemplateCommand, [
78
+ { description: 'Send a template with no variables',
79
+ command: 'plazbot whatsapp send-template -p 51912345678 -t welcome_message' },
80
+ { description: 'Send a template with body variables',
81
+ command: 'plazbot whatsapp send-template -p 51912345678 -t order_status --var name=Anna code=PB-123' },
82
+ { description: 'Send a template with an attached PDF',
83
+ command: 'plazbot whatsapp send-template -p 51912345678 -t invoice_template --file-url https://files.example.com/inv.pdf --file-name invoice.pdf' },
84
+ { description: 'Send a template with header and body variables',
85
+ command: 'plazbot whatsapp send-template -p 51912345678 -t promo --header-var image=https://img.example.com/banner.png --var amount=20' },
86
+ ]);
87
+
76
88
  function parseVariables(vars: string[] | undefined): { variable: string; value: string }[] {
77
89
  if (!vars) return [];
78
90
  return vars.map(v => {
@@ -1,15 +1,16 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { DirectMessageCommandOptions } from '../../types/message';
6
- import { createSpinner } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { DirectMessageCommandOptions } from '../../types/message.js';
7
+ import { createSpinner } from '../../utils/ui.js';
7
8
 
8
9
  export const sendMessageCommand = new Command('send-message')
9
- .description('Envia un mensaje directo de WhatsApp')
10
- .requiredOption('-t, --to <phone>', 'Numero de telefono (con codigo de pais, ej: 51912345678)')
11
- .requiredOption('-m, --message <text>', 'Mensaje a enviar')
12
- .option('--dev', 'Usar ambiente de desarrollo', false)
10
+ .description('Send a direct WhatsApp message')
11
+ .requiredOption('-t, --to <phone>', 'Phone number (with country code, e.g.: 51912345678)')
12
+ .requiredOption('-m, --message <text>', 'Message to send')
13
+ .option('--dev', 'Use development environment', false)
13
14
  .action(async (options: DirectMessageCommandOptions) => {
14
15
  try {
15
16
  const credentials = await getStoredCredentials();
@@ -21,11 +22,11 @@ export const sendMessageCommand = new Command('send-message')
21
22
  ...(options.dev && { customUrl: "http://localhost:5090" })
22
23
  });
23
24
 
24
- logger.title('Enviando mensaje WhatsApp');
25
- logger.label('Destino', options.to);
26
- logger.label('Mensaje', options.message);
25
+ logger.title('Sending WhatsApp message');
26
+ logger.label('Destination', options.to);
27
+ logger.label('Message', options.message);
27
28
 
28
- const spinner = createSpinner('Enviando...');
29
+ const spinner = createSpinner('Sending...');
29
30
  spinner.start();
30
31
 
31
32
  const response = await messageClient.onWhatsappMessage({
@@ -33,15 +34,22 @@ export const sendMessageCommand = new Command('send-message')
33
34
  to: options.to
34
35
  });
35
36
 
36
- spinner.succeed('Mensaje enviado exitosamente');
37
+ spinner.succeed('Message sent successfully');
37
38
 
38
39
  if (options.dev) {
39
- logger.warning('Ambiente: desarrollo');
40
+ logger.warning('Environment: development');
40
41
  }
41
42
 
42
43
  } catch (error: unknown) {
43
- const message = (error as Error)?.message || 'Error desconocido al enviar el mensaje';
44
+ const message = (error as Error)?.message || 'Unknown error while sending the message';
44
45
  logger.error(message);
45
46
  process.exit(1);
46
47
  }
47
48
  });
49
+
50
+ addExamples(sendMessageCommand, [
51
+ { description: 'Send a quick WhatsApp message',
52
+ command: 'plazbot whatsapp send-message -t 51912345678 -m "Hello from Plazbot"' },
53
+ { description: 'Send through the development backend',
54
+ command: 'plazbot whatsapp send-message -t 51912345678 -m "Hi" --dev' },
55
+ ]);
@@ -1,17 +1,25 @@
1
1
  import { Command } from 'commander';
2
2
  import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { createSpinner } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { createSpinner } from '../../utils/ui.js';
6
7
 
7
8
  const widgetGroup = new Command('widget')
8
- .description('Gestionar widget de WhatsApp');
9
+ .description('Manage WhatsApp widget');
10
+
11
+ addExamples(widgetGroup, [
12
+ { description: 'Enable the WhatsApp click-to-chat widget on an agent',
13
+ command: 'plazbot whatsapp widget enable agt_AbcDef123 -u https://wa.me/51912345678' },
14
+ { description: 'Disable the widget',
15
+ command: 'plazbot whatsapp widget disable agt_AbcDef123' },
16
+ ]);
9
17
 
10
18
  widgetGroup.command('enable')
11
- .description('Activar widget de WhatsApp en un agente')
12
- .argument('<agentId>', 'ID del agente')
13
- .requiredOption('-u, --url <url>', 'URL de WhatsApp (ej: https://wa.me/51912345678)')
14
- .option('--dev', 'Usar ambiente de desarrollo', false)
19
+ .description('Enable the WhatsApp widget on an agent')
20
+ .argument('<agentId>', 'Agent ID')
21
+ .requiredOption('-u, --url <url>', 'WhatsApp URL (e.g.: https://wa.me/51912345678)')
22
+ .option('--dev', 'Use development environment', false)
15
23
  .action(async (agentId: string, options: any) => {
16
24
  try {
17
25
  const credentials = await getStoredCredentials();
@@ -22,26 +30,26 @@ widgetGroup.command('enable')
22
30
  ...(options.dev && { customUrl: "http://localhost:5090" })
23
31
  });
24
32
 
25
- const spinner = createSpinner('Activando widget WhatsApp...');
33
+ const spinner = createSpinner('Enabling WhatsApp widget...');
26
34
  spinner.start();
27
35
  await agent.updateAgent(agentId, {
28
36
  enableWhatsappWidget: true,
29
37
  urlWhatsappWidget: options.url,
30
38
  });
31
- spinner.succeed('Widget WhatsApp activado');
39
+ spinner.succeed('WhatsApp widget enabled');
32
40
  logger.label('URL', options.url);
33
41
 
34
42
  } catch (error) {
35
- const message = error instanceof Error ? error.message : 'Error desconocido';
43
+ const message = error instanceof Error ? error.message : 'Unknown error';
36
44
  logger.error(message);
37
45
  process.exit(1);
38
46
  }
39
47
  });
40
48
 
41
49
  widgetGroup.command('disable')
42
- .description('Desactivar widget de WhatsApp de un agente')
43
- .argument('<agentId>', 'ID del agente')
44
- .option('--dev', 'Usar ambiente de desarrollo', false)
50
+ .description('Disable the WhatsApp widget on an agent')
51
+ .argument('<agentId>', 'Agent ID')
52
+ .option('--dev', 'Use development environment', false)
45
53
  .action(async (agentId: string, options: any) => {
46
54
  try {
47
55
  const credentials = await getStoredCredentials();
@@ -52,13 +60,13 @@ widgetGroup.command('disable')
52
60
  ...(options.dev && { customUrl: "http://localhost:5090" })
53
61
  });
54
62
 
55
- const spinner = createSpinner('Desactivando widget WhatsApp...');
63
+ const spinner = createSpinner('Disabling WhatsApp widget...');
56
64
  spinner.start();
57
65
  await agent.updateAgent(agentId, { enableWhatsappWidget: false });
58
- spinner.succeed('Widget WhatsApp desactivado');
66
+ spinner.succeed('WhatsApp widget disabled');
59
67
 
60
68
  } catch (error) {
61
- const message = error instanceof Error ? error.message : 'Error desconocido';
69
+ const message = error instanceof Error ? error.message : 'Unknown error';
62
70
  logger.error(message);
63
71
  process.exit(1);
64
72
  }