Actualizado: 8/11/2024

¿Cómo desarrollar código en la plataforma?

Aquí aprenderás como crear código dentro de la plataforma Botmaker.



Aquí aprenderás cómo crear código dentro de la plataforma Botmaker.

Lectura estimada: 10 minutos


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.

Cómo disparar un código

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á:





Características del código

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.




Entrada de acción del cliente

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": {}

  }

}





El objeto de contexto

Un objeto de solo lectura que tiene información relevante que puede requerir una acción de código. Proporciona:

  • userData: toda la información sobre un usuario, incluidas etiquetas y variables, si las hay;
  • message: información sobre el último mensaje del usuario;
  • params: parámetros opcionales que pueden enviarse mediante una regla.

Por ejemplo:

const userFirstName = context.userData.FIRST_NAME;





El objeto user

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

  • Para leer un valor: user.get('valueKey') => retornará un string con valor o nulo
  • Para escribir un valor: user.set('valueKey', 'value')

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.




Usar entidades entityLoader

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);

    

});





El objeto DB

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. 

GET

Propósito

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.

Parámetros

  • key: El identificador único que se utiliza para buscar el par de valores en la base de datos.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podrías implementar este método:


SET

Propósito

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.

Parámetros

  • key: La clave única que identifica el registro en la base de datos.
  • value: El valor único (o conjunto de valores, dependiendo de tu diseño) que se desea almacenar en la base de datos.Siempre debe ser del tipo STRING.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método set:

EXISTS

Propósito

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.


Parámetros

  • key: La clave única utilizada para buscar el registro en la base de datos.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método exists:

DEL

Propósito

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.

Parámetros

  • key: La clave única utilizada para identificar y eliminar el registro en la base de datos.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método del:


ZADD

Propósito

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.

Parámetros

  • key: La clave utilizada para identificar la colección en la base de datos.
  • value: Es el valor que se registrará para el elemento de la colección.
  • score: Es el dato que se usará para ordenar la colección al ser consultada.
  • expiracion: Es el tiempo en segundos durante el cual el valor persistirá desde el momento de inserción.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zadd: 


ZRANGEBYSCORE

Propósito

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.

Parámetros

  • key: La clave utilizada para identificar la colección de registros a obtener.
  • min: Es el valor de rango mínimo para realizar la búsqueda.
  • max:: Es el valor de rango máximo para realizar la búsqueda.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zrangebyscore:


ZREMRANGEBYSCORE

Propósito

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.

Parámetros

  • key: La clave utilizada para identificar la colección de registros.
  • min: Es el valor de rango mínimo para realizar el borrado.
  • max: Es el valor de rango máximo para realizar el borrado.

Ejemplo de Código

Aquí tienes un ejemplo simple para ilustrar cómo podría implementar el método zremrangebyscore: 


Uso del objeto db en las ca endpoint o cron


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.


Ejemplo de Código






Resultado de una acción del cliente

Cualquier resultado adicional que una acción del cliente quiera crear, debe hacerse usando el objeto de resultado.

  • Para decirle algo al usuario usando texto: `result.text('un mensaje')`
  • Para mostrar una imagen al usuario: `result.image ('https://example.com/image.jpg')` `
  • Para mostrar un vídeo al usuario: `result.video ('https://example.com/video.mp4')`
  • Para enviar un archivo al usuario: `result.file ('https://example.com/myfile.doc')`
  • Para enviar un audio al usuario: `result.audio ('https://example.com/audio.mp3')`
  • También es posible enviar al usuario un texto con botones de acción.

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





Ir a la otra regla

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');

Terminación de la acción del cliente

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();

    });





Uso de listas personalizadas (Lista JSON)

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:




Integrar con un servicio REST

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();

});





Integrar con un servicio SOAP

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();

     });






Crear una acción del cliente con parámetros

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();


Para usar los parámetros enviados a Client Action:

const myVar = context.params.key

const myVar2 = context.params.key2 





Crear una librería de utilidades usando acciones de código

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:

Ejecutar una consulta a una API externa desde una client action de Botmaker

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