Aquí aprenderás como crear código dentro de la plataforma Botmaker.
Primero accedé al menú y haz clic en Código:
Las acciones del cliente son útiles para el desarrollo de intenciones más complejas o cuando se desea agregar códigos arbitrarios en una conversación. Es una excelente alternativa para conectar servicios externos para adquirir información relevante en tiempo real en la conversación con el usuario.
Por ejemplo:
Puedes informar al usuario que diga un color. Una vez enviado, puedes conectar la API de traducción de Google para que el bot responda al mismo color en otro idioma.
Primero, deberás crear una acción del cliente en la pantalla Códigos. Mira abajo:
Asigna un nombre a la acción (no lo olvide) y haz clic en “guardar”.
Con la intención de que se active la acción, haz clic en “Respuestas”. De ahí ve a “ Acción”, elija “Acciones de Código” y “Acción de Código” y ahí selecciona el código que se ejecutará:
Admitimos Node.js v6.14.0, junto con la lista de bibliotecas a continuación:
{
"@turf/helpers": "^6.1.4", // accessed by "turfHelpers" var
"@turf/turf": "^5.1.6", // accessed by "turf" var
"bluebird": "^3.5.1", // accessed by "bluebird" var
"googleapis": "^32.0.0", // accessed by "google" var
"js-sha256": "^0.9.0", // accessed by "sha256" var
"jsonwebtoken": "^8.3.0", // accessed by "jwt" var
"lodash": "^4.17.10", // accessed by "_" var
"md5": "^2.2.1", // accessed by "md5" var
"moment": "^2.22.2", // accessed by "moment" var
"request": "^2.87.0",
"request-promise": "^4.2.2", // accessed by "rp" var
"secure-random": "^1.1.1", // accessed by "securedRandom" var
"xml2js": "^0.4.19", // accessed by "xml2js" var
"aws-sdk": "^2.485.0" // accessed by "awsSdk" var
}
En caso de que quiera usar otra biblioteca, escríbenos un correo electrónico a architecture@botmaker.com, y nuestro equipo aceptará la solicitud.
Cuando se active el código, se proporcionará toda la información que tenemos sobre el usuario, las conversaciones y la configuración general. El json a continuación describe la entrada que puede usar una función de nube.
{
"context": {
"userData": {
"CHAT_PLATFORM_ID": "webchat",
"CHAT_CHANNEL_ID": "YPDXTZKM8Y3NXLXVQYAN-webchat-null",
"PLATFORM_CONTACT_ID": "0BBSX05QRF-3318782UBYKNLUIRBM0KL8XMDTM",
"LAST_MODIFICATION": "2018-07-23T03:43:51.243Z",
"HAS_TALKED": true,
"_id_": "O0IUBYCHJYSA4PNB0QH7",
"LAST_SEEN": "2018-07-23T03:43:52.279Z",
"variables": {
"svar": "sdas"
},
"tags": [
"testtest2"
]
},
"message": {
"BUSINESS_ID": "YPDXTZKM8Y3NXLXVQYAN",
"CREATION_TIME": "2018-07-23T03:43:52.281Z",
"FROM_NAME": "Usuario",
"CUSTOMER_ID": "O0IUBYCHJYSA4PNB0QH7",
"_id_": "LBIJGWZN4SJADFT2HUD2",
"FROM": "0BBSX05QRF-3318782UBYKNLUIRBM0KL8XMDTM",
"OBJECT_TYPE": "Message",
"SESSION_CREATION_TIME": "2018-07-23T03:43:52.281Z",
"AUDIOS_URLS": [],
"MESSAGE": "test",
"CHAT_PLATFORM_ID": "webchat",
"CHAT_CHANNEL_ID": "YPDXTZKM8Y3NXLXVQYAN-webchat-null",
"LAST_MODIFICATION": "2018-07-23T03:43:52.281Z",
"TO": "me",
"TAGS": {}
},
"params": {}
}
}
Un objeto de solo lectura que tiene información relevante que puede requerir una acción de código. Proporciona:
Por ejemplo:
const userFirstName = context.userData.FIRST_NAME;
Este objeto permite leer y escribir variables que persistirán al usuario. Es un local muy útil para guardar datos relacionados al usuario.
Ten en cuenta que los valores tendrán que ser del tipo de string
Por ejemplo:
if ( !user.get('neverWasHere') )
user.set('neverWasHere', 'true');
El valor neverWasHere será verdadero para siempre, o incluso cuando otra acción del cliente establezca un valor diferente.
En la sección de configuración de variables, es posible cambiar el tipo de variable y si será visible para los operadores.
También, es posible que la variable caduque junto con la sección, es decir, después de una hora de inactividad.
Cuando se carga un archivo cvs en el menú “registros” de la plataforma, las acciones del cliente tendrán acceso a él. Se puede filtrar una lista guardada.
/*Entidad cargada:
id | name
1 | Gabriel
2 | Dario
*/
//Utilizar la función entityLoader para leer las entidades cargadas
entityLoader('entity name', json => {
// here you got your entity object loaded as json
if (!json) {
user.set('error', 'No hay datos');
result.done();
return;
}
//Buscas el dato que necesitas
const data = json.find(row => row.id === 2);
result.text('Muestro el nombre ->' + data.name);
});
Agregamos un nuevo componente en la CAs, que es el componente “db”. El mismo no necesita ser importado a diferencia de redis, y se utiliza simplemente como utilizamos las funcionalidades de “user” o “result” dentro de las CAs. Este nuevo componente permite la utilización de varios métodos , los cuales serán detallados a continuación.
El método get tiene como objetivo recuperar un par de valores (pair) desde una base de datos propia, utilizando una clave (key) proporcionada como argumento.
El método set se encarga de almacenar un par de valores en una base de datos propia, donde se utiliza una clave (key) para identificar el registro y se almacena un valor asociado.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método set:
El método exists tiene el objetivo de verificar la existencia de un registro en la base de datos propia. Utiliza una clave (key) para consultar la base de datos y determinar si hay un registro correspondiente. Devuelve true si el registro existe y false si no existe.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método exists:
El método del tiene el objetivo de eliminar un registro en la base de datos propia. Utiliza una clave (key) para identificar el registro que debe eliminarse, y al hacerlo, elimina tanto la clave como el par de valores asociados a esa clave.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método del:
El método zadd tiene el objetivo de agregar un registro a una colección definida por la key. Esta colección estará ordenada por score en las consultas. Recibe el key, el value, el score y expiration para indicar en segundos cuánto tiempo persistirá el valor. Si el value es vacío no crea el registro, pero no altera registros existentes para la misma key.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zadd:
El método zrangebyscore devuelve una colección de registros que comparten la misma key, cuyo score se encuentre dentro del rango definido entre min y max. El resultado de la consulta estará ordenado por por score de modo ascendente, e incluye casos límite. Recibe el key, el min y el max. Si no existen registros, devuelve null.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zrangebyscore:
El método zremrangebyscore tiene el objetivo de eliminar una conjunto de registros de una colección definida por key cuyo score se encuentra dentro del rango definido entre min y el max, incluyendo los casos límite. Recibe el key, el min y el max. Si no existen registros para el criterio, no hace nada.
Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zremrangebyscore:
En las Client Actions del tipo “Endpoint” o del tipo “Cron”, se puede usar todos estos métodos simplemente se debe agregar antes del “db”, “request.” en la innovación. En caso de que se importe otra Client Action como librería y ésta utilice el objeto “db” también deberá agregar el “request.”, es decir no se puede usar el mismo método de la librería que se utiliza para client actions que no son de este tipo.
Cualquier resultado adicional que una acción del cliente quiera crear, debe hacerse usando el objeto de resultado.
result.buttonsBuilder()
.text('select an option')
.addURLButton('click me', 'https://www.google.com') // a button that will open a page
.addLocationButton() // ask the user for its location using GPSs
.quickReplies() // marks the button so it's showed as pills
.addPhoneButton('call me', '+11233212312')
.addButton('click me', 'rule with name XX') // when user clicks it will fire the rule named XX
.send(); // send must by always called to finalize
Es posible ejecutar una regla, después de completar la acción del cliente, muy fácilmente. Es útil porque, después de decirle algo al usuario, cambiar algunos datos o modificar su estado, querrás continuar el flujo de la conversación activando una regla.
result.gotoRule('a rule name');
result.done() deberá ser ejecutado cuando la acción del cliente fuese finalizada.
Es muy importante llamar a result.done() `en cada flujo que tenga una acción del cliente, para finalizar su ejecución
El siguiente código muestra una acción del cliente bien implementada, con el método done () llamado en todo el flujo.
rp({uri: 'https://script.google.com/macros/s/AKfycbyd5AcbAnWi2Yn0xhFRbyzS4qMq1VucMVgVvhul5XqS9HkAyJY/exec?tz=Asia/Tokyo Japan', json: true})
.then(json=> {
// saying the time
result.text('The time in Tokyo is ' + json.fulldate);
// do not forget to end the execution
result.done();
})
.catch(error => {
result.text('Problems: ' + error + '|' + JSON.stringify(error));
result.done();
});
Si deseas utilizar las opciones para una pregunta que está configurada dinámicamente y que cambia con el tiempo, es posible agregar un valor a una variable especial dentro de una acción del cliente.
En el código Javascript, será necesario crear una lista de objetos, cada uno con los campos “id” y “nombre”. Puedes agregar otras claves a estos objetos, pero no es obligatorio. Mira el ejemplo:
const COUNTRIES = ['Argentina', 'Bolivia', 'Brazil', 'Chile', 'México', 'Paraguay', 'Perú', 'Uruguay']; let myJSONList = [];
myJSONList = COUNTRIES.map((country, index) => { return { id: index, name: country }; });
//result.text(JSON.stringify(myJSONList)); user.set('countries', JSON.stringify(myJSONList));
result.done();
Para utilizar esta variable en una intención, será necesario declarar que los valores válidos para la pregunta son de una Lista JSON personalizada y hacer referencia a la variable utilizada en el código.
Finalmente, deberías ver algo como:
Este tipo de integraciones se utilizan en general para obtener o enviar datos a través de una API. En caso de ser necesario, los datos pueden ser guardados en el bot utilizando variables. Mira cómo llamar a un servicio externo REST para obtener o enviar información en el siguiente ejemplo.
rp({uri: 'https://httpbin.org/anything', json: true})
.then(response => {
//You can get/set user variables
user.set('data', response.data);
result.text('Successful call to remote service!: ' + JSON.stringify(response));
result.done();
}) .catch(err => {
result.text('Problems!: ' + err.message);
result.done();
});
Este tipo de integraciones se utilizan en general para obtener o enviar datos a través de una API. En caso de ser necesario, los datos pueden ser guardados en el bot utilizando variables. Mira cómo llamar a un servicio externo SOAP para obtener o enviar información a continuación.
const request = `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:itemData>
<tem:dataOne>My Data</tem:strUsuario>
</tem:itemData>
</soapenv:Body>
</soapenv:Envelope>`;
rp({uri: `https://www.custom-service.com/myService.asmx`,
method: 'POST',
headers: {
'Content-type': 'text/xml',
'SOAPAction': 'http://tempuri.org/MyAction',
'Content-Length': Buffer.byteLength(request)
},
body: request
})
.then(response => {
xml2js.parseString(response, (err, parsedResponse) => {
//You can get/set user variables
user.set('data', parsedResponse.responseResult);
result.text('Successful call to remote service!: ' + JSON.stringify(parsedResponse));
result.done();
});
}).catch(err => {
user.set('error', `Error rp SOAP ${err}`);
result.done();
});
Se puede crear utilizando la acción “Acción del cliente con parámetros”:
O desde un código, usando un botón que llama a otra Acción del Cliente:
result.buttonsBuilder()
.addClientActionButton('Nombre del boton', //Nombre que aparecerá en el boton
'Nombre de la Client Action', //Nombre de la client action
{
'key': 'valor',
'key2': 'otro_valor'
}) //Json Object con los parametros que se enviará
.buildButtons();
const myVar = context.params.key
const myVar2 = context.params.key2
En la librería de utilidades podrás crear funciones que quieras reutilizar para encontrarlas rápidamente. Así evitas código duplicado y agilizas el proceso.
Luego pueden llamarla desde cualquier otro código de la siguiente forma. El nombre debe ser exactamente el mismo:
Para ejecutar una consulta a una API externa desde una client action de Botmaker, mira el siguiente ejemplo:
Escrito por: Equipo Botmaker
Actualizado: 25/03/2025