Last active
September 10, 2021 13:49
-
-
Save lars-erik/de5ab11109abedba19c246ff8c51ebe4 to your computer and use it in GitHub Desktop.
Power Query data source function for HubSpot CRM V3 objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let | |
Table.GenerateByPage = (getNextPage as function) as table => | |
let | |
listOfPages = List.Generate( | |
() => getNextPage(null), // get the first page of data | |
(lastPage) => lastPage <> null, // stop when the function returns null | |
(lastPage) => getNextPage(lastPage) // pass the previous page to the next function call | |
), | |
// concatenate the pages together | |
tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}), | |
firstRow = tableOfPages{0}? | |
in | |
// if we didn't get back any pages of data, return an empty table | |
// otherwise set the table type based on the columns of the first page | |
if (firstRow = null) then | |
Table.FromRows({}) | |
else | |
Value.ReplaceType( | |
Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])), | |
Value.Type(firstRow[Column1]) | |
), | |
ObjectsPage = (after, objectType, properties, associations) as table => | |
let | |
Source = Json.Document( | |
Web.Contents( | |
"https://api.hubapi.com/crm/v3/objects/" & Text.From(objectType) & "?limit=100&after=" & Text.From(after) & (if List.Count(properties) > 0 then "&properties=" & Text.Combine(properties, ",") else "") & (if List.Count(associations) > 0 then "&associations=" & Text.Combine(associations, ",") else ""), | |
[ApiKeyName="hapikey"] | |
) | |
), | |
results = Source[results], | |
#"Converted to Table" = Table.FromList(results, Splitter.SplitByNothing(), null, null, ExtraValues.Error), | |
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"id", "properties", "associations", "createdAt"}, {"id", "properties", "associations", "createdAt"}), | |
#"Expanded properties" = Table.ExpandRecordColumn(#"Expanded Column1", "properties", properties, properties) | |
in | |
#"Expanded properties" meta [next = try Source[paging][next][after] otherwise null], | |
ObjectType = type text meta [ | |
Documentation.FieldCaption = "Object Type", | |
Documentation.FieldDescription = "The CRM object type", | |
Documentation.AllowedValues={"companies", "contacts", "deals", "feedback_submissions", "line_items", "products", "tickets", "quotes", "schemas"}, | |
IsParameterQueryRequired=true | |
], | |
TypedFunction = type function( | |
objectType as ObjectType, | |
optional properties as (type text meta [ | |
Documentation.FieldCaption = "Properties", | |
Documentation.FieldDescription = "Comma separated list of properties", | |
Documentation.SampleValues = {"name, vat_number", "email, firstname, lastname"} | |
]), | |
optional associations as (type text meta [ | |
Documentation.FieldCaption = "Associations", | |
Documentation.FieldDescription = "Comma separated list of associations", | |
Documentation.SampleValues = {"contacts", "companies, deals"} | |
]) | |
) as table, | |
AllObjects = ( | |
objectType, | |
optional properties, | |
optional associations | |
) as table => | |
let | |
propsList = if properties is null then {} else List.Transform(Text.Split(properties, ","), each Text.Trim(_)), | |
associationList = if associations is null then {} else List.Transform(Text.Split(associations, ","), each Text.Trim(_)), | |
Source = Table.GenerateByPage((previous) => | |
let | |
next = if (previous = null) then 0 else Value.Metadata(previous)[next]?, | |
page = if (next <> null) then ObjectsPage(next, objectType, propsList, associationList) else null | |
in | |
page | |
) | |
in | |
Source, | |
TypedAll = Value.ReplaceType(AllObjects, TypedFunction) | |
in TypedAll |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment