GitHubBeitragen in GitHub: Online bearbeiten

Google Apps Script

Google Apps Script ist eine JavaScript Cloud-Skriptsprache, die einfache Möglichkeiten zur Automatisierung von Aufgaben in Google Produkten und Diensten von Drittanbietern sowie zur Erstellung von Webanwendungen bietet.

Mit der eingebauten Targetprocess REST API ist es möglich, Daten aus Ihrem Targetprocess-Konto in das Google Spreadsheets-Dokument zu laden. Die Aktualisierungsaktion wird ebenfalls unterstützt und weiter unten beschrieben.

Wie Sie Ihr erstes Integrationsskript erstellen und ausführen

Öffnen Sie Ihr Arbeitsblatt Google.

Drücken Sie Werkzeuge > Skript-Editor

Skript-Editor

Benennen Sie das neu erstellte Projekt um.

Umbenennen

Kopieren Sie den Quellcode in den Editorbereich der Datei Code.gs . Verwenden Sie das Beispiel Fetch data from Targetprocess aus dem folgenden Artikel.

Ersetzen Sie die Werte für Hostname und Authentifizierungs-Token durch die Werte, die für Ihr eigenes Kundenkonto mit Targetprocess gelten.

kontoname

🚧 Wie erhält man ein Token?

Für isTokenSetFromUserProfileTab verwenden Sie eine der beiden Optionen. Verwenden Sie true , wenn Ihr Token über Benutzerprofil > Registerkarte Zugriffstoken in Targetprocess ausgestellt wird. Verwenden Sie false , wenn das Token vom /api/v1/authentication REST API-Endpunkt ausgestellt wird.

Wählen Sie in der Dropdown-Liste die Funktion fetchTargetprocessData zur Ausführung aus.

run-function

Drücken Sie Ausführen.

Ausführung

Erteilen Sie diesem Skript die gewünschten Berechtigungen. Diese Aktion darf nur einmal durchgeführt werden.

beantragte Genehmigung

Aktion

Erfolgreich! Ihre Kalkulationstabelle ist nun mit Targetprocess-Entitäten ausgefüllt.

us-liste

Daten von Targetprocess abrufen

Dieses Skript verbindet sich mit dem Targetprocess-Konto myaccount.tpondemand.com über eine Token-basierte Authentifizierung und fragt die Liste der User Stories ab. Einzelheiten zu den geladenen Geschichten werden an das ursprünglich freigegebene Google Spreadsheet angehängt.

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

Daten in Targetprocess aktualisieren

Dieses Skript verbindet sich mit dem Targetprocess-Konto myaccount.tpondemand.com unter Verwendung der Token-basierten Authentifizierung und erstellt eine neue User-Story-Entität in Projekt Nr. 2. Die numerische ID, der Name, die Beschreibung und der Erstellungszeitstempel der Benutzergeschichte werden an das ursprünglich gelöschte Google Spreadsheet angehängt.

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

Anzahl der Entitäten in der Antwort

Im Demo-Beispiel werden die ersten 10 übereinstimmenden User Stories abgerufen. Die Anzahl der abgefragten Entitäten wird im Skriptkopf kodiert:

var takeCount = 10;

Es ist möglich, den Parameter takeCount auf bis zu 1000 zu erhöhen.

Wenn Sie mehr als 1000 Entitäten haben, die Ihrer Abfrage entsprechen, müssen Sie ein Skript erstellen, das mehrere API-Aufrufe mit Paging-Parametern durchführt und dann die abgerufenen Daten zusammenführt.

Filtern

Es ist auch möglich, bei der Integration mit Excel fortgeschrittenere REST-API-Techniken (wie Filterung, angehängte Felder und Sammlungen) zu verwenden. Weitere Informationen zu Filtern finden Sie in der Beschreibung der Targetprocess REST API Filter.

Hier sind Beispiele dafür, wie der Quellcode geändert werden kann, um Filter zu unterstützen.

Im Datumsbereich im benutzerdefinierten Feld:

var filter = '(\'CustomFields.Next Date\' gte \'2017-01-09\') and (\'CustomFields.Next Date\' lte \'2017-01-16\')';

Weitere Lektüre

Verwenden Sie die Google Apps Script-Anleitungen oder wenden Sie sich an unser Support-Team für weitere Unterstützung.

📘 Alternative Option: Zapier

Targetprocess-Entitäten können auch mit Google Spreadsheets-Dokumenten über den Zapier Connector synchronisiert werden.