plazbot-cli
Version:
CLI para Plazbot SDK
98 lines (97 loc) • 4.13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.broadcastCommand = void 0;
const commander_1 = require("commander");
const plazbot_1 = require("plazbot");
const credentials_1 = require("../../utils/credentials");
const logger_1 = require("../../utils/logger");
const ui_1 = require("../../utils/ui");
const promises_1 = __importDefault(require("fs/promises"));
exports.broadcastCommand = new commander_1.Command('broadcast')
.description('Envio masivo de mensajes de template WhatsApp')
.requiredOption('-t, --template <name>', 'Nombre del template')
.requiredOption('--phones <file>', 'Archivo CSV con numeros de telefono (uno por linea)')
.option('--var <vars...>', 'Variables del body (formato: name=valor)')
.option('--delay <ms>', 'Delay entre mensajes en ms', '1000')
.option('--dev', 'Usar ambiente de desarrollo', false)
.action(async (options) => {
try {
const credentials = await (0, credentials_1.getStoredCredentials)();
const messageClient = new plazbot_1.Message({
workspaceId: credentials.workspace,
apiKey: credentials.apiKey,
zone: credentials.zone,
...(options.dev && { customUrl: "http://localhost:5090" })
});
// Leer archivo de telefonos
let phones;
try {
const content = await promises_1.default.readFile(options.phones, 'utf-8');
phones = content.split('\n')
.map(line => line.trim())
.filter(line => line && !line.startsWith('#'));
}
catch {
throw new Error(`No se pudo leer el archivo: ${options.phones}`);
}
if (phones.length === 0) {
throw new Error('El archivo no contiene numeros de telefono');
}
// Parsear variables
const variablesBody = parseVariables(options.var);
console.log((0, ui_1.section)('Broadcast WhatsApp'));
logger_1.logger.label('Template', options.template);
logger_1.logger.label('Destinatarios', String(phones.length));
logger_1.logger.label('Delay', `${options.delay}ms`);
if (variablesBody.length > 0) {
logger_1.logger.label('Variables', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
}
console.log();
const delay = parseInt(options.delay) || 1000;
let sent = 0;
let failed = 0;
for (let i = 0; i < phones.length; i++) {
const phone = phones[i];
try {
const params = {
to: phone,
template: options.template,
};
if (variablesBody.length > 0)
params.variablesBody = variablesBody;
await messageClient.onConversation(params);
sent++;
}
catch {
failed++;
console.log(ui_1.theme.error(` ✖ Fallo: ${phone}`));
}
// Progress
console.log(` ${(0, ui_1.progressBar)(i + 1, phones.length)}`);
// Rate limiting
if (i < phones.length - 1) {
await new Promise(resolve => setTimeout(resolve, delay));
}
}
console.log((0, ui_1.section)('Resultado'));
logger_1.logger.label('Enviados', ui_1.theme.success(String(sent)));
logger_1.logger.label('Fallidos', failed > 0 ? ui_1.theme.error(String(failed)) : '0');
logger_1.logger.label('Total', String(phones.length));
}
catch (error) {
const message = error?.message || 'Error desconocido';
logger_1.logger.error(message);
process.exit(1);
}
});
function parseVariables(vars) {
if (!vars)
return [];
return vars.map(v => {
const [variable, ...rest] = v.split('=');
return { variable: variable.trim(), value: rest.join('=').trim() };
}).filter(v => v.variable && v.value);
}