使用基于过滤器的Apps脚本从Salesforce获取报表数据

时间:2016-08-02 16:43:49

标签: google-apps-script salesforce

尝试根据Github上的handy script将Saleforce Analytics API中的数据导入Google电子表格。除了运行整个报告之外,我正在尝试根据同一文档的不同表单上的电子邮件列表列传递电子邮件过滤器。

    // Use the Analytics API to get report data
    function runContactsReport() {
      var reportId = '';
      var sheetName = 'Report';
      var sfService = getSfService();
      var userProps = PropertiesService.getUserProperties();
      var props = userProps.getProperties();
      var name = getSfService().serviceName_;
      var obj = JSON.parse(props['oauth2.' + name]);
      var instanceUrl = obj.instance_url;
      var queryUrl = instanceUrl + "/services/data/v29.0/analytics/reports/" + reportId + "?includeDetails=true";  // Actual request for report Data
      var response = UrlFetchApp.fetch(queryUrl, { method : "GET", headers : { "Authorization" : "OAuth "+sfService.getAccessToken() } });
      var queryResult = JSON.parse(response.getContentText());

// sheet to insert reports      
      var ss = SpreadsheetApp.getActive();
      var sheet = ss.getSheetByName(sheetName);

//emails to filter on
      var dataSheet = ss1.getSheetByName('DATA');
      var emails = getColumnNrByName(dataSheet, 'Email')
      var emailFilters = dataSheet.getRange(2, emailds, dataSheet.getLastRow() -1).getValues();

      var answer = queryResult.factMap["T!T"].rows;  // assumes tabular report
      var headers = queryResult.reportExtendedMetadata.detailColumnInfo;
      var headname = queryResult.reportMetadata.detailColumns;
      var filters = queryResult.reportMetadata.reportFilters; //get filters

      var myArray = [];
      var tempArray = [];


      for (i = 0 ; i < headname.length ; i++) {

        tempArray.push(headers[headname[i]].label);

      }

      myArray.push(tempArray);

      for (i = 0 ; i < answer.length ; i++ ) {

        var tempArray = [];
        function getData(element,index,array) {
          tempArray.push(array[index].label)
        }

        answer[i].dataCells.forEach(getData);

        myArray.push(tempArray);

    } 

      var lastRow = sheet.getLastRow();
      if (lastRow < 1) lastRow = 1;
    sheet.getRange(1,1,lastRow, myArray[0].length).clearContent();
    sheet.getRange(1,1, myArray.length, myArray[0].length).setValues(myArray);

    }

为此,我需要使用已编辑的过滤器发送回报告元数据对象。 以下是根据Salesforce API返回的一些典型元数据:

'{reportMetadata":{"name":"MerchandiseReport","id":"00OD0000001ZbP7MAK","developerName":"MerchandiseReport",​"reportType":{"type":"MerchandiseList","label":"Merchandise"},"reportFormat":"MATRIX",​"reportBooleanFilter":null,"reportFilters":[{"column": "QUANTITY", "operator":"greaterThan",​ "value":"12"}],"detailColumns":["MERCHANDISE.NAME","CREATED_DATE","QUANTITY"],​"currency":null,"aggregates":["RowCount"],"groupingsDown":[{"name":"CONTACT2.COUNTRY_CODE",​"sortOrder":"Asc","dateGranularity":"None"}],"groupingsAcross":[{"name":​"OWNER","sortOrder":"Asc","dateGranularity":"None"}]}}'

不幸的是,我不知道如何在Apps脚本中传递它。任何帮助表示赞赏!

更新:在与此代码作斗争后,以下是最新结果。根据API指令,我需要传递POST请求以传递过滤器参数。将POST请求发送到Execute Async资源。如果您要传递过滤器,请将它们包含在POST请求元数据中。请求返回存储运行结果的实例ID。

所以这就是我所拥有的:

function filterReport(){
 var reportId = '00O33000004Dels';
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var dataSheet = ss.getSheetByName('DATA');
 var emailds = getColumnNrByName(dataSheet, 'Email');
 var emailFilters = dataSheet.getRange(2, emailds, dataSheet.getLastRow() -1).getValues();

  for (var i = 0; i < emailFilters.length; i++) {

    var payload = JSON.stringify({
      'reportMetadata': {
        'reportFilters': [{
      'value' : emailFilters[i][0],
      'column': 'EMAIL',
      'operator': 'equals' 
        }]
      }
    });

    filter(reportId, payload);
}
 }

function filter(reportId, payload) {

  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var queryUrl = instanceUrl + "/services/data/v35.0/analytics/reports/" + reportId + "/instances";

  var options = {
    'headers': {
     'Authorization' : 'Bearer ' + sfService.getAccessToken()
    },
    'contentType' : 'application/json',
    'method' : 'POST',
    'payload' : payload
  }; 

  var response = UrlFetchApp.fetch(queryUrl, options);

  if (response.getResponseCode() == 200) {

    var params = JSON.parse(response.getContentText());
   //Logger.log(response.getContentText());
    var filterId = params.id;
    //Logger.log(filterId);
    Logger.log(response.getContentText())
  } 
}

这不会返回一个实例ID,而是返回4,就像我在示例电子表格中一样......我需要一个ID来传递4个结果(按照这个例子)。

之后,我需要发送带有此实例ID的GET请求,因此我可以将带有过滤器的数据放入电子表格中。

我有这个功能,它有点工作,但我不知道如何自动从我的POST请求中将该Instance id传递给它...

// Use the Analytics API to get report data
// The try-catch can be removed if you do not need to track errors
function runContactsReport() {
  var reportId = '00O33000004Dels';
  var sheetName = 'Contact Email Validation Report';
  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var queryUrl = instanceUrl + "/services/data/v35.0/analytics/reports/" + reportId + "/instances/0LG33000005ZJdqGAG";  // Actual request for report Data
  var response = UrlFetchApp.fetch(queryUrl, { method : "GET", headers : { "Authorization" : "OAuth "+sfService.getAccessToken() } });
  var queryResult = JSON.parse(response.getContentText());

  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName(sheetName);

  var answer = queryResult.factMap["T!T"].rows;  // assumes tabular report
  var headers = queryResult.reportExtendedMetadata.detailColumnInfo;
  var headname = queryResult.reportMetadata.detailColumns;   

  var myArray = [];
  var tempArray = [];

  for (i = 0 ; i < headname.length ; i++) {

    tempArray.push(headers[headname[i]].label);

  }

  myArray.push(tempArray);

  for (i = 0 ; i < answer.length ; i++ ) {

    var tempArray = [];
    function getData(element,index,array) {
      tempArray.push(array[index].label)

    }

    answer[i].dataCells.forEach(getData);

    myArray.push(tempArray);

} 

  var lastRow = sheet.getLastRow();
  if (lastRow < 1) lastRow = 1;
sheet.getRange(1,1,lastRow, myArray[0].length).clearContent();
sheet.getRange(1,1, myArray.length, myArray[0].length).setValues(myArray);

}

所以,我再次陷入困境..请帮助!

1 个答案:

答案 0 :(得分:0)

我终于开始工作了。希望它对某人有帮助。我遇到的唯一问题是偶尔当我运行runContactsReport()时,它会返回错误 - “TypeError:无法读取属性”T!T“从null。”但它运行良好 - 非常令人费解......这就是我得到的:

        //this is POST request to pass filters based on email column into report
function filterContacts() {

         var reportId = 'YOUR REPORT ID'; //SF Contacts Report ID
         var ss = SpreadsheetApp.getActiveSpreadsheet();
         var dataSheet = ss.getSheetByName('DATA');
         var emailds = getColumnNrByName(dataSheet, 'Email'); //custom function that finds header name and returns column umber
         var emailFilters = dataSheet.getRange(2, emailds, dataSheet.getLastRow() -1).getValues(); //column with emails

    //put all emails in one comma separated string, so we get one instance ID
    var emails = emailFilters.toString().split(",").join();

            var payload = JSON.stringify({
            'reportMetadata': {
            'reportFilters': [{  
              'value' : emails,
              'column': 'EMAIL',
              'operator': 'equals' 
           }]
           }
            });

          var sfService = getSfService();
          var userProps = PropertiesService.getUserProperties();
          var props = userProps.getProperties();
          var name = getSfService().serviceName_;
          var obj = JSON.parse(props['oauth2.' + name]);
          var instanceUrl = obj.instance_url;
          var queryUrl = instanceUrl + "/services/data/v35.0/analytics/reports/" + reportId + "/instances";

          var options = {
            'headers': {
             'Authorization' : 'Bearer ' + sfService.getAccessToken()
            },
            'contentType' : 'application/json',
            'method' : 'POST',
            'payload': payload
          }; 

          //Logger.log(options)


          var response = UrlFetchApp.fetch(queryUrl, options);

          if (response.getResponseCode() == 200) {

            var params = JSON.parse(response.getContentText());

          } 

            //Logger.log("my id is:" + params.id);
            return params.id; //return instance ID
        }


        // use returned instance ID to run report based on email filter
        function runContactsReport() {
          filterContacts();
          var reportId = 'YOUR REPORT ID'; //SF Contact Email Validation Report
          Utilities.sleep(200);// pause in the loop for 200 milliseconds
          var instanceId = filterContacts();
         // Logger.log("And my id is:" + instanceId);
          var sheetName = 'Contact Email Validation Report';
          var sfService = getSfService();
          var userProps = PropertiesService.getUserProperties();
          var props = userProps.getProperties();
          var name = getSfService().serviceName_;
          var obj = JSON.parse(props['oauth2.' + name]);
          var instanceUrl = obj.instance_url;
          var queryUrl = instanceUrl + "/services/data/v35.0/analytics/reports/" + reportId + "/instances/" + instanceId;  // Actual request for report Data
          var response = UrlFetchApp.fetch(queryUrl, { method : "GET", headers : { "Authorization" : "OAuth "+sfService.getAccessToken() } });
          var queryResult = JSON.parse(response.getContentText());

          var ss = SpreadsheetApp.getActive();
          var sheet = ss.getSheetByName(sheetName);

          var answer = queryResult.factMap["T!T"].rows;  // assumes tabular report
          var headers = queryResult.reportExtendedMetadata.detailColumnInfo;
          var headname = queryResult.reportMetadata.detailColumns; 

          var filters = queryResult.reportMetadata.reportFilters;

          //Logger.log(filters)

          var myArray = [];
          var tempArray = [];


          for (i = 0 ; i < headname.length ; i++) {

            tempArray.push(headers[headname[i]].label);

          }

          myArray.push(tempArray);

          for (i = 0 ; i < answer.length ; i++ ) {

            var tempArray = [];
            function getData(element,index,array) {
              tempArray.push(array[index].label)

            }

            answer[i].dataCells.forEach(getData);

            myArray.push(tempArray);

        } 

          var lastRow = sheet.getLastRow();
          if (lastRow < 1) lastRow = 1;
        sheet.getRange(1,1,lastRow, myArray[0].length).clearContent();
        sheet.getRange(1,1, myArray.length, myArray[0].length).setValues(myArray);
        }