Instantly share code, notes, and snippets.

Embed
What would you like to do?
Report to Flow
/**
* Video demo: https://vimeo.com/290089502
*/
public class ReportRunService extends Service
{
/**
* Using step config, admins choose name of report in saga UI
*/
public class Definition
{
String Icon = 'report';
String Label = 'Report Run Service';
String Description = 'Run report and emit an event for each row.';
Map<String,String> StepConfig = new Map<String,String>{'reportDeveloperName' => 'String'};
}
/**
* Fetch report results using Rest API
*/
public void callout(Map<String,Object> event)
{
String developerName = (String)event.get('reportDeveloperName');
List<Report> reports = [
SELECT Id
FROM Report
WHERE DeveloperName = :developerName
];
if (reports.isEmpty())
{
//no such report, or report is in private folder
throw new StringException('Cannot find report with developer name: ' + developerName);
}
HttpRequest request = new HttpRequest();
request.setMethod('GET');
request.setHeader('Authorization', 'Bearer ' + event.get('sessionId'));
request.setEndpoint(Url.getSalesforceBaseUrl().toExternalForm() + '/services/data/v43.0/analytics/reports/' + reports[0].Id);
this.response = new Http().send(request);
}
HttpResponse response;
public List<Map<String,Object>> execute(Map<String,Object> event)
{
if (response.getStatusCode() != 200)
{
//report API error
throw new StringException('Cannot run report: ' + response.getBody());
}
//prepare output events
List<Map<String,Object>> events = new List<Map<String,Object>>();
//for each row, extract cells
Map<String,Object> result = (Map<String,Object>)Json.deserializeUntyped(response.getBody());
Map<String,Object> factMap = (Map<String,Object>)result.get('factMap');
Map<String,Object> tT = (Map<String,Object>)factMap.get('T!T');
List<Object> rows = (List<Object>)tT.get('rows');
for (Object untypedRow : rows)
{
//prepare each event
Map<String,Object> output = new Map<String,Object>();
//for each cell, extract values
Map<String,Object> row = (Map<String,Object>)untypedRow;
List<Object> dataCells = (List<Object>)row.get('dataCells');
for (Integer i = 0; i < dataCells.size(); i++)
{
Map<String,Object> cell = (Map<String,Object>)dataCells[i];
output.put('label' + i, cell.get('label'));
output.put('value' + i, cell.get('value'));
}
events.add(output);
}
//emit per row
return events;
}
}
{
"attributes": {
"describeUrl": "/services/data/v43.0/analytics/reports/00O6F00000DG8PtUAL/describe",
"instancesUrl": "/services/data/v43.0/analytics/reports/00O6F00000DG8PtUAL/instances",
"reportId": "00O6F00000DG8PtUAL",
"reportName": "DemoReport",
"type": "Report"
},
"allData": true,
"factMap": {
"T!T": {
"aggregates": [
{
"label": "6",
"value": 6
}
],
"rows": [
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Herp",
"value": "0016F00002UvkCJQAZ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
},
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Baz",
"value": "0016F00002UvkCiQAJ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
},
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Doop",
"value": "0016F00002UvkCTQAZ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
},
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Bar",
"value": "0016F00002UvkCdQAJ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
},
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Derp",
"value": "0016F00002UvkCOQAZ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
},
{
"dataCells": [
{
"label": "Admin",
"value": "0056F000009tuFjQAI"
},
{
"label": "Foo",
"value": "0016F00002UvkCYQAZ"
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "-",
"value": null
},
{
"label": "16/09/2018",
"value": "2018-09-16"
},
{
"label": "-",
"value": null
}
]
}
]
}
},
"groupingsAcross": {
"groupings": []
},
"groupingsDown": {
"groupings": []
},
"hasDetailRows": true,
"picklistColors": {},
"reportExtendedMetadata": {
"aggregateColumnInfo": {
"RowCount": {
"dataType": "int",
"label": "Record Count"
}
},
"availableDashboardSettings": null,
"detailColumnInfo": {
"USERS.NAME": {
"dataType": "string",
"filterValues": [],
"filterable": true,
"isLookup": true,
"label": "Account Owner"
},
"ACCOUNT.NAME": {
"dataType": "string",
"filterValues": [],
"filterable": true,
"isLookup": true,
"label": "Account Name"
},
"TYPE": {
"dataType": "picklist",
"filterValues": [
{
"label": "Prospect",
"name": "Prospect"
},
{
"label": "Customer - Direct",
"name": "Customer - Direct"
},
{
"label": "Customer - Channel",
"name": "Customer - Channel"
},
{
"label": "Channel Partner / Reseller",
"name": "Channel Partner / Reseller"
},
{
"label": "Installation Partner",
"name": "Installation Partner"
},
{
"label": "Technology Partner",
"name": "Technology Partner"
},
{
"label": "Other",
"name": "Other"
}
],
"filterable": true,
"isLookup": false,
"label": "Type"
},
"RATING": {
"dataType": "picklist",
"filterValues": [
{
"label": "Hot",
"name": "Hot"
},
{
"label": "Warm",
"name": "Warm"
},
{
"label": "Cold",
"name": "Cold"
}
],
"filterable": true,
"isLookup": false,
"label": "Rating"
},
"DUE_DATE": {
"dataType": "date",
"filterValues": [],
"filterable": true,
"isLookup": false,
"label": "Last Activity"
},
"LAST_UPDATE": {
"dataType": "date",
"filterValues": [],
"filterable": true,
"isLookup": false,
"label": "Last Modified Date"
},
"ADDRESS1_STATE": {
"dataType": "string",
"filterValues": [],
"filterable": true,
"isLookup": false,
"label": "Billing State/Province"
}
},
"groupingColumnInfo": {}
},
"reportMetadata": {
"aggregates": [
"RowCount"
],
"chart": null,
"crossFilters": [],
"currency": null,
"dashboardSetting": null,
"description": null,
"detailColumns": [
"USERS.NAME",
"ACCOUNT.NAME",
"TYPE",
"RATING",
"DUE_DATE",
"LAST_UPDATE",
"ADDRESS1_STATE"
],
"developerName": "DemoReport",
"division": null,
"folderId": "00D6F000002L8TdUAK",
"groupingsAcross": [],
"groupingsDown": [],
"hasDetailRows": true,
"hasRecordCount": true,
"historicalSnapshotDates": [],
"id": "00O6F00000DG8PtUAL",
"name": "DemoReport",
"reportBooleanFilter": null,
"reportFilters": [],
"reportFormat": "TABULAR",
"reportType": {
"label": "Accounts",
"type": "AccountList"
},
"scope": "user",
"showGrandTotal": true,
"showSubtotals": true,
"sortBy": [],
"standardDateFilter": {
"column": "CREATED_DATE",
"durationValue": "CUSTOM",
"endDate": null,
"startDate": "2018-09-09"
},
"standardFilters": null,
"supportsRoleHierarchy": false,
"userOrHierarchyFilterId": null
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="http://soap.sforce.com/2006/04/metadata">
<columns>
<field>USERS.NAME</field>
</columns>
<columns>
<field>ACCOUNT.NAME</field>
</columns>
<columns>
<field>TYPE</field>
</columns>
<columns>
<field>RATING</field>
</columns>
<columns>
<field>DUE_DATE</field>
</columns>
<columns>
<field>LAST_UPDATE</field>
</columns>
<columns>
<field>ADDRESS1_STATE</field>
</columns>
<format>Tabular</format>
<name>DemoReport</name>
<params>
<name>co</name>
<value>1</value>
</params>
<reportType>AccountList</reportType>
<scope>user</scope>
<showDetails>true</showDetails>
<showGrandTotal>true</showGrandTotal>
<showSubTotals>true</showSubTotals>
<timeFrameFilter>
<dateColumn>CREATED_DATE</dateColumn>
<interval>INTERVAL_CUSTOM</interval>
<startDate>2018-09-09</startDate>
</timeFrameFilter>
</Report>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment