Google Script de aplicaciones
Google Apps Script es un lenguaje de programación JavaScript en la nube que ofrece formas sencillas de automatizar tareas en Google productos y servicios de terceros, así como de crear aplicaciones web.
Mediante la API REST integrada de Targetprocess, es posible transferir datos de su cuenta de Targetprocess a un documento Google de Spreadsheets. La acción de actualización también es compatible y se describe a continuación.
Cómo crear y ejecutar tu primer script de integración
Abre tu Google hoja de cálculo.
Herramientas de prensa Editor de scripts

Cambia el nombre del proyecto recién creado.

Copie el código fuente al área del editor para Code.gs el archivo. Utilice el ejemplo «Obtener datos de Targetprocess» del artículo que aparece a continuación.
Reemplaza los valores del nombre de host y del token de autenticación por los específicos de tu propia cuenta de cliente en Targetprocess.

true si su token se emite desde la pestaña Perfil de usuario > Tokens de acceso en Targetprocess. Utilizar false cuando el token se emite desde el punto final /api/v1/authentication de la API REST.Seleccione la función denominada fetchTargetprocessData en el menú desplegable para su ejecución.

Pulse «Ejecutar».

Concede a este script los permisos solicitados. Esta acción solo debe realizarse una vez.

Correcto. Tu hoja de cálculo ahora está rellenada con entidades de Targetprocess.

Obtener datos de Targetprocess
Este script se conecta a la cuenta de myaccount.tpondemand.com Targetprocess mediante autenticación basada en tokens y consulta la lista de historias de usuario. Los detalles de las historias cargadas se añaden a la hoja de cálculo inicialmente Google borrada.
function fetchTargetprocessData() {
var hostname = 'https://myaccount.tpondemand.com';
var authenticationToken = 'MTpFQUVXMHdRVGRMN0x1OXJPYWRXZWZaRkc2aDJaSkRyVWdyWm9rK2tFcldBPS==';
var isTokenSetFromUserProfileTab = true;
//use 'true' if token is issued from User Profile > Access Tokens tab
//use 'false' when token is issued from /api/v1/Authentication API endpoint
var takeCount = 10;
var entityTypeResourceName = 'userstories';
var filter = '';
var includeFields = '';
//use the example below to specify exact set of fields to include
//var includeFields = '[ID,Name,Project[Name],EntityState[Name],CustomFields]';
var dateFormat = 'yyyy-MM-dd';
//to see times with dates, use 'yyyy-MM-dd HH:mm';
var dataUrl = hostname + '/api/v1/' + entityTypeResourceName + '?format=json' + '&where=' + filter + '&take=' + takeCount + (includeFields.length > 0 ? '&include=' + includeFields : '') + '&' + (isTokenSetFromUserProfileTab ? 'access_token' : 'token') + '=' + authenticationToken;
var options = {
'method': 'get'
};
var response = UrlFetchApp.fetch(dataUrl, options);
var json = response.getContentText();
var data = JSON.parse(json);
var entities = data.Items;
var sheet = SpreadsheetApp.getActiveSheet();
//initial cleanup of the sheet
sheet.clear();
//creates column names row
var entity = entities[0];
var columnNames = Object.keys(entity);
var customFieldsColumnIndex = 0;
for (var i = 0; i < columnNames.length; i++) {
if (columnNames[i] == 'CustomFields') {
customFieldsColumnIndex = i;
}
}
if (customFieldsColumnIndex > 0) {
var entityArray = Object.keys(entity).map(function(k) { return entity[k] });
var customFieldsData = entityArray[customFieldsColumnIndex];
for (var k = 0; k < customFieldsData.length; k++) {
var fieldsPairData = customFieldsData[k];
columnNames.push(fieldsPairData.Name);
}
}
sheet.appendRow(columnNames);
//appends data line by line
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
var entityArray = Object.keys(entity).map(function(k) { return entity[k] });
if (customFieldsColumnIndex > 0) {
//format custom fields
var customFieldsData = entityArray[customFieldsColumnIndex];
var fieldValues = '';
for (var j = 0; j < customFieldsData.length; j++) {
var fieldsPairData = customFieldsData[j];
entityArray.push(fieldsPairData.Value);
}
entityArray[customFieldsColumnIndex] = customFieldsData.length;
}
//add data formatting functions there
for (var j = 0; j < entityArray.length; j++) {
var cellValue = entityArray[j];
if (typeof cellValue == 'string') {
if (cellValue.indexOf("Date") > -1) {
var milliseconds = cellValue.substring(6, cellValue.length - 7);
var originTimeZone = cellValue.substring(cellValue.length - 7, cellValue.length - 4);
var dateObject = new Date(parseInt(milliseconds) + originTimeZone * 1000 * 60 * 60);
entityArray[j] = Utilities.formatDate(dateObject, originTimeZone, dateFormat);
}
}
if (typeof cellValue == 'object') {
var keys = [];
var resourceType = '';
var name = '';
var items = null;
for(var key in cellValue) {
keys.push(key);
if (key == "ResourceType") {
resourceType = cellValue[key];
}
if (key == "Name") {
name = cellValue[key];
}
};
if (
resourceType == "Project"
|| resourceType == "EntityState"
|| resourceType == "EntityType"
|| resourceType == "Priority"
|| resourceType == "Feature"
|| resourceType == "Epic"
|| resourceType == "UserStory"
|| resourceType == "Program"
|| resourceType == "Release"
|| resourceType == "Iteration"
|| resourceType == "TeamIteration"
) {
entityArray[j] = name;
}
}
}
sheet.appendRow(entityArray);
}
}
Actualizar datos en Targetprocess
Este script se conecta a la cuenta de myaccount.tpondemand.com Targetprocess mediante autenticación basada en tokens y crea una nueva entidad User Story en el Proyecto n.º 2. El ID numérico, el nombre, la descripción y la marca de tiempo de creación de la historia de usuario se añaden a la hoja de cálculo inicialmente Google despejada.function updateTargetprocessData() {
var payload = {
"Project" : {"ID" : 2},
"Name": "Test Google Script Story Name",
"Description": "Test Google Script Story Description"
};
var hostname = 'https://myaccount.tpondemand.com';
var authenticationToken = 'MTozemxBMjI4dkNPMFVqbmlWV21WUVlSb0RYTTAzbkhQZ1lvaTJKanMvQWFBPS==';
var isTokenSetFromUserProfileTab = true;
//use 'true' if token is issued from User Profile > Access Tokens tab
//use 'false' when token is issued from /api/v1/Authentication API endpoint
var entityTypeResourceName = 'userstories';
var resultIncludeFields = '[Id,Name,Description,CreateDate]';
var dateFormat = 'yyyy-MM-dd HH:mm'; //to see no times with dates, use 'yyyy-MM-dd';
var dataUrl = hostname + '/api/v1/' + entityTypeResourceName + '/?format=json'
+ '&resultInclude=' + resultIncludeFields
+ '&' + (isTokenSetFromUserProfileTab ? 'access_token' : 'token') + '=' + authenticationToken;
var options = {
'method': 'POST',
'payload': JSON.stringify(payload),
'contentType' : 'application/json',
};
var response = UrlFetchApp.fetch(dataUrl, options);
var sheet = SpreadsheetApp.getActiveSheet();
//initial cleanup of the sheet
sheet.clear();
var json = response.getContentText();
var data = JSON.parse(json);
var entities = data;//data.Items; for multiple objects
var entity = entities;//entities[0]; for multiple objects
var columnNames = Object.keys(entity);
var customFieldsColumnIndex = 0;
for (var i = 0; i < columnNames.length; i++) {
if (columnNames[i] == 'CustomFields') {
customFieldsColumnIndex = i;
}
}
if (customFieldsColumnIndex > 0) {
var entityArray = Object.keys(entity).map(function(k) { return entity[k] });
var customFieldsData = entityArray[customFieldsColumnIndex];
for (var k = 0; k < customFieldsData.length; k++) {
var fieldsPairData = customFieldsData[k];
columnNames.push(fieldsPairData.Name);
}
}
sheet.appendRow(columnNames);
var entity = entities;//entities[i]; for multiple objects
var entityArray = Object.keys(entity).map(function(k) { return entity[k] });
if (customFieldsColumnIndex > 0) {
//format custom fields
var customFieldsData = entityArray[customFieldsColumnIndex];
var fieldValues = '';
for (var j = 0; j < customFieldsData.length; j++) {
var fieldsPairData = customFieldsData[j];
entityArray.push(fieldsPairData.Value);
}
entityArray[customFieldsColumnIndex] = customFieldsData.length;
}
//add data formatting functions there
for (var j = 0; j < entityArray.length; j++) {
var cellValue = entityArray[j];
if (typeof cellValue == 'string') {
if (cellValue.indexOf("Date") > -1) {
var milliseconds = cellValue.substring(6, cellValue.length - 7);
var originTimeZone = cellValue.substring(cellValue.length - 7, cellValue.length - 4);
var dateObject = new Date(parseInt(milliseconds) + originTimeZone * 1000 * 60 * 60);
entityArray[j] = Utilities.formatDate(dateObject, originTimeZone, dateFormat);
}
}
if (typeof cellValue == 'object') {
var keys = [];
var resourceType = '';
var name = '';
var items = null;
for(var key in cellValue) {
keys.push(key);
if (key == "ResourceType") {
resourceType = cellValue[key];
}
if (key == "Name") {
name = cellValue[key];
}
};
if (
resourceType == "Project"
|| resourceType == "EntityState"
|| resourceType == "EntityType"
|| resourceType == "Priority"
|| resourceType == "Feature"
|| resourceType == "Epic"
|| resourceType == "UserStory"
|| resourceType == "Program"
|| resourceType == "Release"
|| resourceType == "Iteration"
|| resourceType == "TeamIteration"
) {
entityArray[j] = name;
}
}
}
sheet.appendRow(entityArray);
}
Recuento de entidades en respuesta
En la muestra de demostración, recuperamos las primeras 10 historias de usuario coincidentes. El número de entidades que consultamos está codificado en el encabezado del script:var takeCount = 10;Es posible aumentar takeCount el parámetro hasta 1000. Si tiene más de 1000 entidades que coinciden con su consulta, debe crear un script que realice varias llamadas a la API utilizando parámetros de paginación y, a continuación, combine los datos recuperados.Filtrado
También es posible incluir técnicas más avanzadas de la API REST (como filtrado, campos añadidos y colecciones) al integrarse con Excel. Para obtener más información sobre los filtros, consulte la descripción de los filtros de la API REST de Targetprocess. A continuación se muestran ejemplos de cómo se puede modificar el código fuente para admitir filtros. En el campo personalizado «Rango de fechas»:var filter = '(\'CustomFields.Next Date\' gte \'2017-01-09\') and (\'CustomFields.Next Date\' lte \'2017-01-16\')';