Desarrollar código en la plataforma

En esta sección verás todo lo relacionado a acciones de código y cómo implementarlas.

Características de código

Soporta Node.js v8.0, junto a la lista de libraries abajo:

{
"@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
"redis": "^2.8.0",
"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
}

Input de Acción de Cliente

Cuando el código fue disparado, toda información que tenemos del usuario, conversaciones y configuraciones generales serán provistas. La json abajo describe el input que una Cloud Function podrá usar.

{
"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 context

Un objeto solamente lectura tiene información relevante que una acción de código puede requerir. Esto proporciona:

  • userData: toda información referente a un usuario, incluyendo tags y variables (si hubiera);

  • message: información referente al último mensaje del usuario;

  • params: parámetros opcionales que pueden ser enviados por una intención.

Por ejemplo:

const userFirstName = context.userData.FIRST_NAME;

El objeto user

Este objeto permite leer y escribir variables que persistirán en el usuario. Es muy útil para guardar datos relacionados con el usuario.

Ten presente que los valores tendrán que ser de tipo string

  • Para leer un valor: user.get('valueKey') => devolverá una string con un valor o nula

  • Para escribir un valor: user.set('valueKey', 'value')

Por ejemplo:

if ( !user.get('neverWasHere') )
user.set('neverWasHere', 'true');

El valor neverWasHere será true para siempre, o hasta cuando otra acción de cliente configure un valor diferente.

En la sección de configuración de variables se puede cambiar el tipo de la variable y si es visible a los agentes que atienden conversaciones.

También, es posible que la variable expire con la sesión luego de un periodo de inactividad.

Utilizar entidades (entityLoader)

Cuando se haga upload de un archivo cvs en menu "Entidades" de la plataforma, las Acciones de Cliente tendrán acceso a él. Una lista guardada podrá ser filtrada.

/*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;
}
//Buscamos el dato que necesitamos
const data = json.find(row => row.id === 2);
result.text('Muestro el nombre ->' + data.name);
});

El objeto connectRedis

Una instancia db instance está disponible para ser utilizada con Acciones de Clientes. Podrá:

const redis = connectRedis();
const myKey = redis.get('key');

Soporte completo a redes será proporcionado. De una mirada en el node oficial: [redis library](https://github.com/NodeRedis/node_redis)

Resultado de una Acción de Cliente

Cualquier resultado adicional que una Acción de Cliente quiera crear, precisa ser realizado usando el objeto result.

  • Para decir algo a un usuario usando texto: result.text('a message')

  • Para mostrar una imagen a un usuario: result.image('https://example.com/image.jpg')

  • Para mostrar un vídeo a un usuario: result.video('https://example.com/video.mp4')

  • Para enviar un archivo a un usuario: result.image('https://example.com/myfile.doc')

  • Para enviar un audio a un usuario: result.audio('https://example.com/audio.mp3')

Igualmente, es posible enviar a un 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 otra intención

Es posible ejecutar una intención, después de finalizada la Acción del Cliente, de forma muy sencilla. Después de decir algo a un usuario, cambiar algún dato o modificar su estado, podrás continuar el flujo de la conversación disparando alguna intención.

result.gotoRule('a rule name');

Término de Acción de Cliente

result.done() deberá ser ejecutado cuando una Acción de Cliente se dé por finalizada.

Es muy importante llamar result.done() en todo flujo que exista una Acción de Cliente, de modo de finalizar la ejecución del mismo.

El siguiente código muestra una Acción de 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:

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:

Crear una Client Action con parametros

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:

.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

Leer Spreadsheet de Google Drive

Para leer un spreadsheet de google drive debes:

const spreadsheetURI = `https://docs.google.com/spreadsheets/d/${SPREADSHEET_ID}/export?format=csv`;
rp({uri: spreadsheetURI})
.then(data => {
return new Promise (resolve => {
csv.fromString(data, {headers: true, ignoreEmpty: true})
.on("data", data => {
//Do something with data
})
.on("end", () => {
resolve(json); //finish spreadsheet
});
});
});

Más información acerca de parametros de google drive