Skip to content

Instantly share code, notes, and snippets.

@lars-erik
Last active September 10, 2021 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lars-erik/de5ab11109abedba19c246ff8c51ebe4 to your computer and use it in GitHub Desktop.
Save lars-erik/de5ab11109abedba19c246ff8c51ebe4 to your computer and use it in GitHub Desktop.
Power Query data source function for HubSpot CRM V3 objects
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