ThingWorx Flow > SDK de ThingWorx Flow > Apéndice B: Tutorial del SDK de conectores de ThingWorx Flow
Apéndice B: Tutorial del SDK de conectores de ThingWorx Flow
Requisitos previos
A continuación, se indican los requisitos previos necesarios para este tutorial:
Versión LTS de Node.js 8.9.0 + instalador
Un entorno de desarrollo integrado (IDE) que pueda gestionar los proyectos de Node js.
En el tutorial se utiliza WebStorm como IDE.
Conocimientos de nivel medio del código de Node js
Carpeta de ejemplos
Introducción
En el tutorial se explican los pasos necesarios para crear un conector típico. Se creará un conector para Gmail, ya que es probable que la mayoría de los desarrolladores estén familiarizados con su funcionamiento. Con la creación del conector, el usuario se familiarizará con las herramientas, los elementos y los procesos implicados en la creación de un conector y le ayudará a crear un conector para la aplicación. La creación de un nuevo conector no requiere la implementación de ThingWorx Flow. Después de compilar y probar el conector localmente, se puede implementar en una instalación local para las pruebas.
En el tutorial se abarca lo siguiente:
1. Creación de un proyecto de conector.
2. Una configuración de OAuth2.
3. Creación de una búsqueda que busque filtros relacionados en la cuenta de Gmail.
4. Creación de una acción para obtener el ID y el asunto de los mensajes de correo electrónico que coincidan con el filtro seleccionado.
5. Creación de un activador que permite iniciar un nuevo flujo cuando se reciba un nuevo correo.
6. Adición de iconos.
7. Implementación de conectores en una instancia local de ThingWorx Flow.
Creación de un proyecto de conector
Un conector es un paquete npm especializado que consta de varios elementos, como la configuración de Oauth, acciones, búsquedas y activadores. El proyecto debe seguir los patrones para la creación de un paquete NPM. Debe tener una instancia de package.json, una carpeta lib, una carpeta test y carpetas para cada uno de los elementos y sus versiones.
Abra una ventana terminal/cmd y navegue hasta una carpeta donde desee crear un nuevo proyecto de conector. En este tutorial el conector se creará en el directorio c:\test.
1. Cambie al directorio de prueba: cd c:\test.
2. Ejecute el siguiente comando para crear un proyecto: flow init <projectname>
Se debería ver lo siguiente:
cd c:\test
[2018-10-21T15:35:11.519] [INFO] default - Project gmail created successfully in .
3. Abra el directorio del proyecto en un IDE para revisar los elementos creados por defecto.
En cada proyecto se incluyen un fichero index.js y un fichero package.json. No cambie el fichero index. js ya que es necesario para cargar los conectores en el servidor ThingWorx Flow.
* 
El fichero package.json hace referencia a ptc-flow-sdk. Sin esta dependencia, no es posible probar, implementar o ejecutar el conector. También se proporcionan algunas API que facilitan el desarrollo y la coherencia del conector.
1. Siga los pasos que se indican en el Apéndice A.
2. Instale el paquete async con el siguiente comando:
npm install async
3. Instale el módulo request con los siguientes comandos. En el módulo de solicitud se incluye una API para realizar solicitudes HTTP.
npm install request
npm install request-promise
4. Instale el módulo lodash en el que se proporciona una variedad de funciones útiles:
npm install lodash
npm install ptc-flow-sdk@<Versión de la herramienta> -g
Verifique la <Versión de la herramienta> de su versión de ThingWorx Flow aquí.
* 
Todos los comandos del tutorial se ejecutan desde el directorio de proyecto del conector c:\test\gmail. De este modo, no hace falta proporcionar la ruta completa del directorio del conector con las opciones -d/--projectDir.
Creación de una configuración de OAuth2
* 
Antes de comenzar, asegúrese de haber seguido los pasos proporcionados en la sección Configuración para pruebas de OAuths y activadores.
Gmail utiliza OAuth 2.0 para la autenticación. Por lo tanto, el conector de ejemplo utiliza OAuth 2.0 como mecanismo de autenticación. Todos los proveedores de OAuth2 requieren una aplicación para crear un ID de cliente y secreto de cliente. La aplicación puede solicitar a un usuario que se conecte al proveedor de Oauth con estas credenciales. El usuario puede conceder los permisos de aplicación para acceder a datos en su nombre. Los permisos se definen por ámbitos. El usuario puede proporcionar selectivamente a la aplicación acceso a sus datos. La información detallada sobre cómo se implementa para Gmail y otras aplicaciones de Google, visite los siguientes vínculos.
Proporcione un URL de redirección. El URL de redirección:
https://<nombre_host>:<puerto>//Thingworx/Oauths/oauth/return tiene el siguiente aspecto:
https://flow.local.rnd.ptc.com/Thingworx/Oauths/oauth/return
Algunos sistemas permiten varias redirecciones.
* 
Asegúrese de que el host que se utilice se añada al fichero .flow\flow.json en el directorio inicial del usuario. Si no es el nombre de host real, sino un alias del host local, añádalo al fichero del host del sistema operativo.
Por ejemplo,
1. En Windows, pulse con el botón derecho en el editor y, a continuación, seleccione Ejecutar como administrador.
2. Edite el fichero del host que se encuentra en c:\windows\system32\drivers\etc\hosts y añada o actualice una entrada como se indica a continuación:
127.0.0.1 flow.local.rnd.ptc.com
Donde, flow.local.rnd.ptc.com se debe reemplazar por el alias.
Después de completar los pasos anteriores, se habrá creado una aplicación, así como un ID de cliente y secreto de cliente para la aplicación.
1. Cree una configuración de Oauth con el siguiente comando.
c:\test\gmail>flow add oauth gmail
[2018-10-21T16:26:54.398] [INFO] add-oauth - Oauth configuration gmail added successfully.
Este comando crea la carpeta \auth\oauth\gmail-gmail en la carpeta del proyecto. La carpeta tendrá un único fichero config.json.
En este caso, el fichero config.json es una plantilla que se debe personalizar para que funcione con un proveedor de OAuth específico, como Google.
2. Ábralo en un editor de texto o IDE y, a continuación, realice los cambios, tal como se describe a continuación. Asegúrese de que el fichero está editado correctamente y que sigue siendo un fichero JSON válido.
3. Defina la categoría, el nombre, el título y los iconos según sea necesario. Consulte la sección Adición de iconos al conector para obtener información detallada sobre la creación y configuración de los iconos.
4. Busque la clave oauth2_params_other y reemplácela por el valor
[
"{\"access_type\":\"offline\"}"
]
5. Busque la clave oauth2_params_scope y reemplace su valor por la siguiente matriz JSON:
[
"{\"https://www.googleapis.com/auth/gmail.labels\":\"Manage mailbox labels\"}",
"{\"https://www.googleapis.com/auth/gmail.insert\":\"Insert mail into your mailbox\"}",
"{\"https://www.googleapis.com/auth/gmail.modify\":\"All read/write operations except immediate, permanent deletion of threads and messages, bypassing Trash.\"}",
"{\"https://www.googleapis.com/auth/gmail.readonly\":\"Read all resources and their metadata—no write operations.\"}",
"{\"https://www.googleapis.com/auth/gmail.compose\":\"Create, read, update, and delete drafts. Send messages and drafts.\"}",
"{\"https://www.googleapis.com/auth/gmail.send\":\"Send email on your behalf\"}"
]
Observe el valor de env_local_params. Aquí "local" es un nombre del entorno. Puede haber cinco entornos posibles y se representan por las claves env_production_params, env_pre_prod_params, env_staging_params, env_local_params. El valor tiene el formato {{{local.CLIENT_SECRET}}}. local.CLIENT_SECRET es una variable que sustituye al nombre del entorno. Debe estar entre tres llaves de apertura y cierre. Estos valores se reemplazan por valores que proporciona el cliente durante la ejecución del servicio LoadOAuthConfiguration en ThingWorx Composer para cargar los elementos OAuth en el servidor ThingWorx Flow. Los valores se proporcionan a través de un fichero JSON. El valor se sustituye al generar una configuración de OAuth solo para el entorno en el que el servidor ThingWorx Flow se ejecuta. Si el servidor tiene la variable de entorno NODE_ENV definida en production, el valor de producción CLIENT_SECRET se rellena con los valores proporcionados en el fichero de datos de OAuth. De este modo, se puede personalizar la configuración de OAuth para cada implementación de cliente.
6. Busque base_url y reemplace su valor por https://accounts.google.com/o/oauth2.
7. Busque oauth2_auth_url y reemplace su valor por /auth.
Pruebas de una configuración de OAuth
Se puede probar una configuración de OAuth antes de la implementación. Para ello, la CLI de ThingWorx Flow inicia un explorador que permite al usuario iniciar sesión en el proveedor de OAuth con sus credenciales. Si la autenticación es correcta, se genera el token de acceso y este se puede guardar en el disco para su uso posterior. También es posible probar cada configuración de implementación mediante la selección de la configuración apropiada en la ventana del explorador integrado Chrome.
Antes de poder ejecutar el comando de prueba, es necesario crear un fichero de datos de prueba que contenga el ID de cliente real y el secreto que se sustituirá por env_<nombre-entorno>_params, como se menciona arriba. Para hacer esto, cree un nuevo fichero JSON, el fichero testOauthData.json en c:\test y añádale el siguiente contenido.
{
"gmail-gmail": {
"Test Gmail Oauth": {
"CLIENT_ID": "<your-client-id-here>"
"CLIENT_SECRET": ""<your-client-secret-here>"
}
}
}
Asegúrese de reemplazar <your-client-id-here> y <your-client-secret-here> por los valores que se han recuperado anteriormente de la consola de Google.
A continuación, asegúrese de que en el fichero .flow\flow.json del directorio de inicio del usuario se incluyan el nombre de host, el puerto y la frase de contraseña del certificado correctos. Esta acción solo es necesaria si se ha proporcionado uno al crear el certificado autofirmado.
Ejecute el siguiente comando en un símbolo del sistema, set FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
Esta variable es obligatoria puesto que se utiliza un certificado autofirmado para ejecutar la herramienta.
1. Ejecute el siguiente comando para probar OAuth.
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. Seleccione la configuración que se va a probar y pulse en Validate Oauth Configuration.
3. Seleccione los ámbitos a los que desea permitir que la aplicación acceda y pulse en Permitir.
4. Introduzca el nombre de usuario para la cuenta de Google. Puede ser cualquier cuenta de Google, no necesariamente la que se utiliza para crear el ID de cliente y el secreto.
5. Introduzca la contraseña. Si la autenticación es correcta, se debe ver el token de acceso.
6. Pulse en Guardar y salir para guardar el token de acceso para su uso futuro.
Aparece el siguiente mensaje en la consola.
[2018-10-22T12:51:07.643] [INFO] oauth - Access token saved with ID :664ec37a-9720-460c-8536-fbf372198cb1
El ID de este mensaje se utilizará para probar otros elementos que dependen del token de acceso, como búsquedas, acciones y activadores. Se debe proporcionar el ID generado anteriormente para todos los comandos de prueba con la opción -a/--access_token.
* 
Si se recibe un error, como la discrepancia del URI de redirección, debe asegurarse de que la configuración de flow.json sea correcta y el URL que el flujo utiliza coincida con el registrado con Google. El URL de redirección utilizado por el flujo aparece en la consola cuando se inicia la prueba.
Por ejemplo [2018-10-22T11:07:53.868] [INFO] oauthServer: servidor iniciado, se ha utilizado redirect_uri para Oauth = https://flow.local.rnd.ptc.com:443/Thingworx/Oauths/oauth/return
* 
Los tokens de acceso de OAuth tienen una duración breve. Antes de utilizar el token de acceso para probar una acción, búsqueda y activador, se debe ejecutar el comando flow test oauth para regenerar un nuevo token.
Creación de una búsqueda
Las búsquedas son un mecanismo de búsqueda. Normalmente, se utilizan para obtener dinámicamente una lista de opciones para determinados campos de entrada de acciones o activadores. Por ejemplo, los mensajes de correo electrónico en Gmail pueden tener rótulos asociados. Esto ayuda a buscar rápidamente los correos electrónicos relacionados que están etiquetados con el rótulo. Sin embargo, es poco probable que un usuario final recuerde los nombres de todos los rótulos creados en su cuenta. La búsqueda que se creará aquí producirá pares de ID y valor para los rótulos que se encuentran en la cuenta de Gmail. Luego se podrá utilizar uno o varios de estos pares para obtener los ID y el asunto de los correos electrónicos con esos rótulos.
Las búsquedas no tienen metadatos, en su lugar se representan mediante un único fichero index.js. Tampoco tienen versión. Puede haber cualquier número de métodos de búsqueda en el fichero index.js.
Para crear una búsqueda, ejecute el siguiente comando:
c:\test\gmail>flow add lookup
[2018-10-22T14:41:52.298] [INFO] add-lookup - Lookup added successfully
La ejecución del comando generará un fichero index.js en la carpeta lookup\gmail.
Abra el fichero index.js en el IDE y añádale el código que aparece a continuación.
En la parte superior del fichero, importe los siguientes módulos.
const async = require('async')
const request = require('request')
const logger = require('ptc-flow-sdk').getLogger('gmail-lookup')
Copie el siguiente código después de todo el código existente en el fichero.

gmailAPIs.getLabels = function (input, options, output) {
logger.debug('Trying to fetch labels')
// Gmail API to fetch th labels in the gmail account
options.url = 'https://www.googleapis.com/gmail/v1/users/me/labels'
// Validating that the authorization is done and we have a access_token to //make a request else throw the error
options.validateDependencies(input.access_token, function (err, status) {
if (err) {
return output({
error: err
})
}
// If the authorization is proper then execute the request
execute(input, options, output)
})
}
// common function for api to execute the request module
function execute (input, options, output) {
async.waterfall([
function (cb) {
// In input we get auth code which we can use to get access token
getAccessToken(input, options, cb)
}
], function (err, accessToken) {
if (err) {
return output({
error: err
})
} else {
// Execute the request to get the labels from the gmail api
requestExecute(input, accessToken, options, output)
}
})
}
// Extract the acces_token from the input and return it
function getAccessToken (input, options, cb) {
options.getAccessToken(input.access_token, function (err, oauth) {
if (err) {
cb(err)
} else {
oauth = JSON.parse(oauth)
cb(null, oauth.access_token)
}
})
}
// Make a request to the gmail url to get the labels
function requestExecute (input, accessToken, options, output) {
request({
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
url: options.url
}, function (err, res, body) {
let result = []
if (err) {
return output({
error: err
})
}
if (res.statusCode === 401) {
return output({
error: 'Your access token is Invalid or Expired'
})
}
if (res.statusCode >= 200 && res.statusCode < 400) {
if (typeof (body) === 'string') {
body = JSON.parse(body)
}
result = filterResult(body.messages || body.labels || body, input)
var pageDetails = options.getPage(result, input, options)
var data = {
'results': result.slice(pageDetails.page, (pageDetails.page + options.maxResults))
}
data.next_page = options.getNextPage(data.results.length >= options.maxResults)
return output(null, data)
}
return output({
error: body
})
})
}
// filter result on the basis of output demand
function filterResult (body, input) {
var result = []
if (body && Array.isArray(body)) {
body.forEach(function (item, index) {
result.push({
'id': String(item.name),
'value': item.name
})
})
}
return result
}
Para probar la búsqueda, ejecute los siguientes comandos:
1. Obtenga un nuevo token de acceso con el siguiente comando:
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. Guarde el token y salga.
3. Pruebe la búsqueda con el siguiente comando:
flow test lookup gmail getLabels -a cecd33a3-8a33-4c0c-b298-178fd80a9261 -l trace. Se debe ver la salida generada por la búsqueda. El resultado es una matriz JSON de los ID y valores.
Creación y prueba de una acción
Una acción interactúa con el sistema externo conectado para realizar una operación. Normalmente, es una operación Crear, Leer, Actualizar o Borrar. Las acciones toman entradas y generan alguna salida. Las entradas y salidas que produce una acción deben especificarse en el fichero action.json. Las propiedades de entrada y salida son un esquema JSON especial que se utilizan para representar el formulario de entrada y el esquema de salida se utiliza para representar la asignación de la interfaz de usuario. Entre otras propiedades útiles se incluyen la etiqueta y el icono que se utilizan para agrupar acciones y mostrar un icono de la acción en la interfaz de usuario.
Para crear una nueva acción, ejecute el siguiente comando:
c:\test\gmail>flow add action get-messages
[2018-10-22T16:26:53.925] [INFO] add-action - Action get-messages, version v1 added successfully
A continuación, abra el fichero action.json C:\test\gmail\action\gmail-get-messages\v1\action.json en el IDE.
Defina la propiedad de entrada e icono en Gmail. El esquema JSON de la propiedad de entrada se muestra en el siguiente código:
Set the input property to {
"title": "Get email messages",
"type": "object",
"properties": {
"auth": {
"title": "Authorize gmail",
"type": "string",
"oauth": "gmail-gmail",
"minLength": 1
},
"label": {
"title": "Label",
"type": "string",
"minLength": 1,
"lookup": {
"id": "getLabels",
"service": "gmail",
"enabled": true,
"searchable": false,
"auth": "oauth",
"dependencies": [
"auth"
]
}
}
}
}
En el esquema de entrada se define un único campo de entrada. Se trata de una lista, puesto que tiene una búsqueda especificada. Cuando se utiliza en el flujo de Composer, se ejecuta la búsqueda y se muestran los valores devueltos en la lista que aparece. Observe cómo se describen las dependencias de la búsqueda. Esto indica al sistema que se debe rellenar el campo de autorización antes de invocar la búsqueda.
La propiedad de autorización describe el método de autenticación que esta acción utiliza. En este caso, se utiliza una configuración Gmail de OAuth.
Set the “output” property to {
"messages": {
"title": "Messages",
"type": "array",
"items": {
"type": "object",
"properties": {
"messageId": {
"type": "string",
"title": "Message Detail ID"
},
"subject": {
"type": "string",
"title": "Message Detail Sub"
}
}
}
}
}
* 
La salida que la acción produce es una matriz JSON de objetos JSON. Cada objeto tendrá los campos messageId y subject.
Abra el fichero index.js en el IDE. En la parte superior del fichero, añada el siguiente código:
const rp = require('request-promise')
const logger = require('ptc-flow-sdk').getLogger('gmail-get-messages')
Reemplace el método execute por el código siguiente:
this.execute = function (input, output) {
// Create a request header to get messages under a label selected from
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages',
useQuerystring: true,
qs: {labelIds: ['STARRED']},
headers:
{
'Authorization': 'Bearer ' + input.auth,
'Content-Type': 'application/json'
}
}
rp(options).then((rawData) => {
const data = JSON.parse(rawData)
let mailRequests = []
if (data && data.messages) {
data.messages.forEach((msg) => {
mailRequests.push(this.fetchMessage(msg.id, input.auth))
})
return Promise.all(mailRequests)
} else {
logger.warn('No messages found')
Promise.resolve()
}
}).then((results) => {
if (results) {
let arr = []
results.forEach((result) => {
let resData = JSON.parse(result)
let msgHeader = resData.payload.headers.find(header => header.name === 'Subject')
arr.push({messageId: resData.id, subject: msgHeader ? msgHeader.value : 'No subject'})
})
return output(null, {messages: arr})
} else {
return output(null)
}
}).catch(err => {
return output(err)
})
}
Añada el nuevo método que se proporciona a continuación:
this.fetchMessage = function (msgId, authToken) {
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages/' + msgId,
qs: { format: 'metadata', metadataHeaders: 'Subject' },
headers:
{
'Authorization': 'Bearer ' + authToken,
'Content-Type': 'application/json'
}
}
return rp(options)
}
Asegúrese de que el fichero sea un fichero JavaScript válido.
1. Adquiera el token de acceso de nuevo siguiendo estos pasos:
Defina FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
Ejecute el siguiente comando y anote el ID que se devuelve.
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. Cree un nuevo fichero JavaScript C:\test\gmail\test\actionTestData.js, añádale el siguiente código y guárdelo.
module.exports = {
testInput: {
label: 'STARRED'//use a label that applies to a few emails.
},
testOutputFn: function (input, actualOutput) {
// validate the actualOutput against expected output
// return a rejected promise to fail the validation or a resolved promise for success
// return Promise.reject(new Error('Validation successful'))
return Promise.reject(new Error('Validation failed'))
}
}
* 
Los parámetros -i/--input y -o/--output aceptan datos o funciones que devuelven una promesa.
Cuando se ejecuta en un servidor, el rótulo está disponible como parte del parámetro de entrada y se puede acceder a él como input.label. La utilidad de prueba no ejecuta una búsqueda. Por lo tanto, se le debe pasar la salida de la búsqueda.
3. Ejecute el comando test, tal como se indica a continuación:
C:\test\gmail>flow test action gmail-get-messages -a 685b7377-7000-
4a92-8679-8630c68a3265 -l debug -i testInput -f
C:\test\gmail\test\actionTestData.js -o testOutput
The test run should succeed.
Creación y prueba de un activador de sondeo
1. Para crear un nuevo activador de sondeo, ejecute el siguiente comando:
flow add trigger -p
[2019-02-28T17:03:23.823] [INFO] add-trigger - Trigger gmail, version v1 added successfully
2. En el IDE, abra el fichero trigger.json ubicado en C:\test\gmail\trigger\poll\gmail \v1\trigger.json.
3. Defina la propiedad de icono para Gmail de la siguiente manera:
"icon": "gmail",
4. Defina las propiedades de entrada y salida.

Set the input property to
{
"properties": {
"auth": {
"type": "string",
"title": "Authorize gmail",
"minLength": 1,
"oauth": "gmail-gmail",
"propertyOrder": 1
},
"search": {
"type": "string",
"title": "Search Text",
"propertyOrder": 2,
"description": "Enter the search text to search for a specific email. E.g., from:john or subject:Christmas"
},
"customFilters": {
"type": "array",
"propertyOrder": 5,
"title": "Custom Filters",
"items": {
"type": "object",
"title": "Filter",
"properties": {
"input": {
"type": "string",
"title": "Input",
"minLength": 1
},
"operator": {
"type": "string",
"title": "Condition",
"enum": [
"Equals",
"GreaterThan"
],
"enumNames": [
"Equals",
"Greater Than"
]
},
"expected": {
"type": "string",
"title": "Expected",
"minLength": 1
}
}
}
}
},
"oneOf": [
{
"type": "object",
"title": "New Email",
"description": "Triggers when a new email is received",
"properties": {
"event": {
"type": "string",
"readonly": true,
"enum": [
"new_mail"
],
"options": {
"hidden": true
},
"propertyOrder": 3
},
"label": {
"type": "string",
"title": "Label",
"propertyOrder": 4,
"description": "Select a label for which you wish to set a trigger. E.g., If you select label as ‘Trash’, the trigger will fire off every time a new mail is moved to label named ‘Trash’ in your Gmail account."
}
}
},
{
"type": "object",
"title": "New Attachment",
"description": "Triggers when a new attachment is received",
"properties": {
"event": {
"type": "string",
"readonly": true,
"enum": [
"new_attachment"
],
"options": {
"hidden": true
},
"propertyOrder": 3
},
"label": {
"type": "string",
"title": "Label",
"propertyOrder": 4,
"description": "Select a label for which you wish to set a trigger. E.g., If you select label as ‘Trash’, the trigger will fire off every time a new mail is moved to label named ‘Trash’ in your Gmail account."
}
}
}
]
}
En el esquema de entrada se define un único campo de entrada. El objeto oneOf define los eventos que soporta el activador. En el esquema anterior se definen dos eventos de activador:
Nuevo correo electrónico
Nuevo adjunto
La propiedad de autorización describe el método de autenticación que activador utiliza. En este caso, se utiliza una configuración Gmail de OAuth.
Set the “output” property to
{
"new_mail": {
"type": "object",
"properties": {
"messageId": {
"type": "string",
"title": "ID",
"displayTitle": "ID"
},
"subject": {
"title": "Subject",
"displayTitle": "Subject",
"type": "string"
}
}
},
"new_attachment": {
"type": "object",
"properties": {
"attachments": {
"title": "Attachments",
"displayTitle": "Attachments",
"type": "array",
"items": {
"type": "object",
"properties": {
"mimeType": {
"title": "Mime Type",
"displayTitle": "Mime Type",
"type": "string"
},
"filename": {
"title": "File Name",
"displayTitle": "File Name",
"type": "string"
},
"attachmentId": {
"title": "Attachment ID",
"displayTitle": "Attachment ID",
"type": "string"
}
}
}
}
}
}
}
En el esquema de salida anterior se definen las propiedades de salida para dos eventos de activador definidos en el esquema de entrada de activador.
1. Abra el fichero index. js en el IDE y, a continuación, añada el siguiente código en la parte superior del fichero:
const rp = require('request-promise')
const logger = require('ptc-flow-sdk').getLogger('gmail-trigger')
2. Reemplace el método execute por el código que se indica a continuación:
Trigger.execute = function (input, options, output) {
// Create a request header to get messages under a label selected from
var date = new Date(options.unixTime * 1000)
const httpOpts = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages',
useQuerystring: true,
qs: { q: 'newer:' + date.getFullYear() + '/' + date.getMonth() + '/' + date.getDay() },
headers:
{
'Authorization': 'Bearer ' + input.auth,
'Content-Type': 'application/json'
}
}
rp(httpOpts).then((rawData) => {
const data = JSON.parse(rawData)
let mailRequests = []
if (data && data.messages) {
data.messages.forEach((msg) => {
mailRequests.push(this.fetchMessage(msg.id, input.auth))
})
return Promise.all(mailRequests)
} else {
logger.warn('No messages found')
Promise.resolve()
}
}).then((results) => {
if (results) {
let arr = []
results.forEach((result) => {
let resData = JSON.parse(result)
let msgHeader = resData.payload.headers.find(header => header.name === 'Subject')
arr.push({ messageId: resData.id, subject: msgHeader ? msgHeader.value : 'No subject' })
})
return output(null, { messages: arr })
} else {
return output(null)
}
}).catch(err => {
return output(err)
})
}
3. Añada el nuevo método que se proporciona a continuación:
Trigger.fetchMessage = function (msgId, authToken) {
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages/' + msgId,
qs: { format: 'metadata', metadataHeaders: 'Subject' },
headers:
{
'Authorization': 'Bearer ' + authToken,
'Content-Type': 'application/json'
}
}
return rp(options)
}
* 
Asegúrese de que el fichero sea un fichero JavaScript válido.
Adquisición del token de acceso
Para volver a adquirir el token de acceso, siga estos pasos:
1. Defina la siguiente propiedad: FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
2. Ejecute el siguiente comando y anote el ID que se devuelve.
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
3. Ejecute el comando test, tal como se indica a continuación:
flow test trigger gmail execute -p -e new_mail -a e0d56340-2fc4-4618-931c-ad6c983ae0e5 --stopAfter 1 --unixTime 1551312000
Adición de iconos al conector
1. Cree una carpeta común en el proyecto de conector.
2. En la carpeta común, añada una carpeta denominada css.
3. Añada un fichero JSON con el siguiente formato:
{ "name": "connector-name",
"background": "#FFFFFF",
"png128pxBase64": "base64encodedbinarydata"
}
La propiedad name debe ser el nombre del conector y debe coincidir con la propiedad icon de las acciones en sus ficheros JSON de metadatos.
El fondo debe ser un código de color HEX, tal como se muestra en el ejemplo.
Las imágenes de icono deben estar en formato .PNG y los datos binarios deben estar codificados en base64. Para obtener más información, busque en Internet cómo convertir PNG a su representación binominal codificada en base64.