cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
PGordon1
Helper I
Helper I

Need help building JSON body for HTTP call dynamically

Hi all, I need a little help getting over the last hurdle in a flow I'm trying to make to allow self-service updates of Azure AD account attributes by (some) end users (so for example a simple change to an employee mobile phone number doesn't require a helpdesk ticket, and a HR manager, who has no AAD admin rights, can trigger the flow to implement this change)

 

I have a very specific set of attributes that I want to allow the users to be able to modify.  I've had success previously using the HTTP method to create Azure user accounts,  but in that scenario I can be very prescriptive & demand that the set of attributes given always and exactly matches my specification, so I can make the body quite simply, as I can hardcode the attribute name, and drop in the values - for example:

PGordon1_0-1631788680329.png

and so on.... with all my required key:value pairs, each with a continuation comma except the last one, and finally the closing curly brace.... 

 

In THIS flow however, I want users to be able to just provide whichever individual attributes need to change, and I won't necessarily know which attribute(s) they are.... and of course the http action fails, or does undesirable things if a key:value pair in the body is malformed, so I need to craft a body dynamically... currently the trigger is an email in which I allow the user to supply new key-value pair(s) in the body of the email. They can supply as many or as few attributes as they like (from the allowed list). and I won't know how many, or what they are. So an input to the flow could be something like:

UPN::test.user@contoso.com

mobileNumber::0123456789

and another could be:

UPN::test.user@contoso.com

surname::smith

I require that UPN is always provided, since I obviously need to know which AAD object to reference, but I don't necessarily require it to be first... I want to allow it to be fairly free-format.

I've got everything in place to parse all the content from the email, and do a bunch of validation on it, and currently I get the data as a set of key:value pairs in a STRING variable. My variable ends up looking something like this:


"city":"London",
"country":"United Kingdom",
"department":"Admin",
"CompanyName":"TEST",
"givenName":"TEST",
"jobTitle":"testing user",
"surname":"USER2",
"mobilePhone":"0123456789",
"employeeID":"000099",
"postalcode":"E11 1JE"

 

This is my test example with more attribute changes than would typically be the case... UPN isn't in the list, because I split that out earlier in the flow to a separate variable (since I need it that way to use it, plus I don't allow that attribute to be changed). It looks like a valid JSON body format - each key and each value is separately quoted, there's a single unquoted colon between them, and there's a continuation comma where there needs to be...

And yet, when I try to setup the HTTP request body, it doesn't like it:

PGordon1_1-1631788712704.png

Clearly something about the format of the variable isn't being liked... - but for the life of me I can't see what or why...
I compose the variable in an apply to each loop earlier in the flow:

PGordon1_2-1631788737374.png

What's going in here is
Double-quote
Key name
double-quote
colon
double-quote
value
double-quote
newline (composed earlier, I just hit enter in the input)

That results in an errant continuation comma on the last entry, so I deal with that after the loop has finished by adding back my UPN attribute without a trailing comma...

To summarise: I have a string variable: var_attributelist who's content is:
"city":"London",
"country":"United Kingdom",
"department":"Admin",
"CompanyName":"TEST",
"givenName":"TEST",
"jobTitle":"testing user",
"surname":"USER2",
"mobilePhone":"0123456789",
"employeeID":"000099",
"postalcode":"E11 1JE",
"UserPrincipalName":"test.user2@hub.com"

Which to my eye is a validly formed body, (NB: I tried adding spaces either side of the colon, that makes no difference), but as soon as I try to use that dynamic content in a http body I get a flow validation error "enter a valid JSON"

Anybody have any clue how I can get past this? - much TIA!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PGordon1
Helper I
Helper I

Got it! - actually, when I said above that I "struggled" to remove the trailing comma from the string variable, this was down to me having a senior moment...  I was using the following expression to strip off the last character:

substring(variables('var_attributelist'),0,sub(length(variables('var_attributelist')),1))

And looking at the output of that... it didn't look any different, and the comma was still there.... - subsequently it has dawned on me, that the trailing comma ISN'T the last character in the string... there's also a Newline after that as well, but when looking at the string you can't see that, so I forgot about it... - Of course, what I actually need to remove are the last 2 characters:

substring(variables('var_attributelist'),0,sub(length(variables('var_attributelist')),2))

THAT removes the comma (and the newline) from the end, allowing me to then add back on a Newline and the closing brace... 

 

Happy days! My flow now works like a charm, approved users can generate an email which will allow them to trigger an update to any 'allowed' attribute for any user in the directory. The HR department use a management app which can be setup to generate those emails automatically, so they literally just make their changes in their HR app as they normally would, and now they automatically flow out to Azure AD.

 

😎

View solution in original post

7 REPLIES 7
PGordon1
Helper I
Helper I

tiny bit more testing.... so, if I take the actual string that my flow builds for the body, and paste it directly into the body thus:

PGordon1_0-1631792556191.png

That is fine, no errors, the flow saves...

 

If I then paste the exact same string into a compose:

PGordon1_1-1631792644285.png

then use the Compose in the HTTP body:

 

PGordon1_2-1631792743141.png

Instantly an error....

 

Hmm... I may have stumbled on an answer... I have been including only the actual key:value items in the variable, and placing the curly braces in the HTTP body...  Seems like I stop the error occurring if I put the braces in the variable:

 

PGordon1_3-1631794052582.png

 

Then put only the variable in the body:

 

PGordon1_4-1631794111357.png

 

That does not throw any errors, & I can save the flow... - whether the HTTP call actually works or not is another matter that I shall soon discover... but at least I am a step closer...

PGordon1
Helper I
Helper I

Nothing in life is ever quite as straightforward as it seems, and I had to go through several iterations of trial & error, but it seems I've now hit upon the setup that works...  

 

Firstly, I have to include the opening curly brace and a newline in the initial initialise variable step:

PGordon1_0-1631804594324.png

 

Then in my apply to each loop, I add all the various key:value pairs with the appropriate formatting via an append to string variable action.

PGordon1_1-1631804594328.png

 

Then when I add the final key:value pair (the UPN) - to mitigate the errant trailing comma that gets left on the last item in the variable, I also have to add the newline and the closing brace:

PGordon1_2-1631804594330.png

 

 And _that_ specific combination seems to work in as much as I can then successfully submit the request to Graph...

The run history shows the body as:

{
"department" : "Admin",
"CompanyName" : "Hub (TEST)",
"givenName" : "TEST",
"jobTitle" : "testing user",
"surname" : "USER2",
"mobilePhone" : "9876543210",
"employeeID" : "000059",
"postalcode" : "SE1 2TU",
"UserPrincipalName":"test.user2@contoso.com"
}

 

I still get an "insufficient privileges to complete the operation" error from Graph which I'm still trying to figure out - my app registration has all the permissions I believe it needs - it can create a new user object, it can set group memberships of users, it can set the Manager attribute, so I'm now a bit stumped as to why it can't  update attributes on an existing user…

PGordon1
Helper I
Helper I

Nope, it's not permissions, it's STILL this **bleep** body!!! - to prove this, I made 1 tiny change to the flow - in the HTTP action, I took out my variable, and just typed in a simple body:

PGordon1_3-1631807414164.png

run the flow, and that works, and I see the updated value on the user account. Drop my variable back in and I get the  "insufficient privileges to complete the operation" error. Wondering if it might be the combination of attributes I'm trying to update in a single query, I pasted the output from my variable into graph explorer & ran that, and it works fine... so there's nothing intrinsic to the content of my body that precludes it from being acted upon.  - of course, graph explorer isn't using my app permissions (there's no way to do that is there? - could I retrieve the token the app has via PowerShell & overwrite the token in graph explorer after I've signed in?)

 

This really shouldn't be this darn hard!!!!

 

😞

 

PGordon1
Helper I
Helper I

I was on to something with my previous thought.... - I wondered if the inclusion of the UPN attribute in the body might have been a problem... - It is not a problem in graph explorer, but clearly that's using my user account delegated permissions... - if I change the flow to not include the UPN attribute in the body, it works! 🙂

Yay!

Clearly there IS a different permission required to change a users UPN, that my user account has, and my app registration does not... - surprises me, since I've added a fairly broad set of application rights to the app including

directory.readwrite.all

group.readwrite.all

groupmember.readwrite.all

user.readwrite.all

 

After a bit of ferreting around in the permissions list, my eye was drawn to: user.manageidentities.all

and his seems to be the one, - after adding this to my app permissions, and setting the flow back as it was, I can now run it successfully with the UPN as the last item in the body...

 

So now the question is, should I go with that as my "solution"? - the only reason I tacked that attribute back on to the end of the list was because I struggled to remove the errant trailing comma that gets left on there by the apply to each loop... it's invalid JSON if the very last element has a continuation comma... If I could figure out a way to remove it, that would be more elegant I think... - anyone got any ideas as to how to do this?

 

Sooooo very close!

 

PGordon1
Helper I
Helper I

Got it! - actually, when I said above that I "struggled" to remove the trailing comma from the string variable, this was down to me having a senior moment...  I was using the following expression to strip off the last character:

substring(variables('var_attributelist'),0,sub(length(variables('var_attributelist')),1))

And looking at the output of that... it didn't look any different, and the comma was still there.... - subsequently it has dawned on me, that the trailing comma ISN'T the last character in the string... there's also a Newline after that as well, but when looking at the string you can't see that, so I forgot about it... - Of course, what I actually need to remove are the last 2 characters:

substring(variables('var_attributelist'),0,sub(length(variables('var_attributelist')),2))

THAT removes the comma (and the newline) from the end, allowing me to then add back on a Newline and the closing brace... 

 

Happy days! My flow now works like a charm, approved users can generate an email which will allow them to trigger an update to any 'allowed' attribute for any user in the directory. The HR department use a management app which can be setup to generate those emails automatically, so they literally just make their changes in their HR app as they normally would, and now they automatically flow out to Azure AD.

 

😎

Hi @PGordon1 :

Glad to hear that you have solved this problem.

Thanks for sharing this solution.

Best Regards,

Bof

Helpful resources

Top Solution Authors
Users online (3,051)