Google Script do Apps

Google O Apps Script é uma linguagem JavaScript de script em nuvem que oferece maneiras fáceis de automatizar tarefas em Google produtos e serviços de terceiros e criar aplicativos da web.

Usando a API REST integrada do Targetprocess, é possível transferir dados da sua conta Targetprocess para um documento Google do Spreadsheets. A ação de atualização também é suportada e descrita abaixo.

Como criar e executar seu primeiro script de integração

Abra sua Google planilha.

Ferramentas de imprensa Editor de scripts

Editor de roteiros

Renomeie o projeto recém-criado.

Renomear

Copie o código-fonte para a área do editor do Code.gs arquivo. Use o exemplo “Buscar dados do Targetprocess” do artigo abaixo.

Substitua os valores do nome do host e do token de autenticação pelos valores específicos da sua conta de cliente no Targetprocess.

nome da conta
Aviso: Como obter um token? Para isTokenSetFromUserProfileTab o parâmetro, use uma das duas opções. Use true se o seu token for emitido a partir do Perfil do usuário > guia Tokens de acesso no Targetprocess. Use false quando o token for emitido a partir do /api/v1/authentication ponto final da API REST.

Selecione a função chamada fetchTargetprocessData no menu suspenso para execução.

função de execução

Pressione Executar.

execução

Conceda a este script as permissões solicitadas. Esta ação deve ser realizada apenas uma vez.

solicitou permissão ação

Sucesso! Sua planilha agora está preenchida com entidades do Targetprocess.

lista-dos-e-s

Buscar dados do Targetprocess

Este script conecta-se à conta Targetprocess myaccount.tpondemand.com usando autenticação baseada em token e consulta a lista de Histórias de Usuário. Os detalhes das histórias carregadas são anexados à planilha inicialmente Google limpa.


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

Atualizar dados no Targetprocess

Este script conecta-se à conta Targetprocess myaccount.tpondemand.com usando autenticação baseada em token e cria uma nova entidade User Story no Projeto #2. A identificação numérica, o nome, a descrição e a data e hora de criação da história do usuário são anexados à planilha inicialmente Google limpa.
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);
}

Contagem de entidades na resposta

Na amostra de demonstração, recuperamos as primeiras 10 histórias de usuários correspondentes. O número de entidades que consultamos está codificado no cabeçalho do script:
var takeCount = 10;
É possível aumentar takeCount o parâmetro até 1000. Se você tiver mais de 1000 entidades que correspondem à sua consulta, será necessário criar um script que faça várias chamadas de API usando parâmetros de paginação e, em seguida, mescle os dados recuperados.

Filtragem

Também é possível incluir técnicas mais avançadas da API REST (como filtragem, campos anexados e coleções) ao integrar com o Excel. Para obter mais informações sobre filtros, consulte a descrição dos filtros da API REST do Targetprocess. Aqui estão alguns exemplos de como o código-fonte pode ser modificado para suportar filtros. No campo personalizado, as datas variam entre:
var filter = '(\'CustomFields.Next Date\' gte \'2017-01-09\') and (\'CustomFields.Next Date\' lte \'2017-01-16\')';

Leitura adicional

Use os Google guias do Apps Script ou entre em contato com nossa equipe de suporte para obter mais assistência.
Observação: Opção alternativa: As entidades do Targetprocess podem ser sincronizadas com documentos do Google Spreadsheets dentro do conector Zapier também.