A Sample OpenAPI/Swagger file for PowerApps
Ever since I posted a video on how to use Flow to upload photos to SharePoint from PowerApps, I get a lot of requests for help with the most mysterious bit – the swagger/openAPI file…
To save you all much pain and suffering, here is a sample file that you can use to get started.
In this post I am going to assume you have watched the video and understand the intent. Here I will simply annotate the file with some notes that will help you customise and extend it for your own purposes.
Note 1: This only works for a HTTP request trigger in Flow
Flow is capable of being called like any other web service. To do so, you have to use the following trigger.
Note that the trigger states clearly “URL will be generated after save”, so the first thing to do is generate that URL…
Once you have done so, it will look like this:
If we break the URL it down, you will see:
- A domain something like <location>.logic.azure.com.
- A URL path of “/workflows/<instance ID>/triggers/manual/paths/invoke” which that identifies your specific workflow ID. Take note of this as you will need it.
- A parameter called api-version with a (at the time of writing) value of “2016-06-01” – eg api-version=2016-06-01
- A parameter called sp with an encoded value of “/triggers/manual/run” = eg sp=%2Ftriggers%2Fmanual%2Frun
- A parameter called sv with a value of 1.0 – eg &sv=1.0
- A parameter called sig with a random string value. eg sig=PeZc-ljtjmJhsz00SD78YrwEohTqlUxpQuc95BQQuwU
In combination, the URL looks as follows with the important bits in bold…
https://<location>.westus.logic.azure.com:443/workflows/<workflow instance ID>/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=<signature>
The bits in bold you will need to know, because they need to be added to the OpenAPI file. Why? because this file is what PowerApps uses to construct a HTTP call to your flow.
So let’s look at the Swagger File…
Note 2: Host, basePath and Path
Open the Swagger file and look for the section called “host”… Replace the section labelled [enter Flow URL here] with the URL from the flow Trigger I mentioned above. eg:
prod-23.westus.logic.azure.com or prod-01.australiasoutheast.logic.azure.com
Note: The image below shows the port number shown (443), this no longer works so omit it altogether as shown in my 2 examples above.
From this…
To this…
Now find the section labelled [enterid here]. This is where the workflow ID goes… so from this:
To this..
Note 3: Double check the sv, api-version and sp parameter sections.
All of the parameters expected by the Flow are specified in the OpenAPI file. You will see it in the “parameters” subsection of the “post” section…eg
Now for reference, each parameter section has:
- name: The name of the parameter as it appears on the URL
- in: specifies whether this parameter is in the query string, header or body. All of the default flow parameters are in the query string.
- default: This is the value to check!! If Flow is updated in future it is very likely this parameter will reflect it. Please do not come to me for support if you have not checked this!
- required: States that this parameter MUST be passed. PowerApps will not allow you to call this Flow without specifying this parameter
- x-ms-visibility: this basically says “use the default value and don’t show the user”. So in effect, the above “required” condition is met, but PowerApps will not ask the user to enter it.
- type: is self-explanatory. It tells PowerApps that the parameter is a string.
Note: For more detail on these parameters go and read the OpenAPI 2.0 standard and Microsoft’s documentation.
Note 4: Update the sig parameter…
The sig parameter is like an API key or a password. You need to paste it as the default value in your file like so…
Note: It is possible to set this up in PowerApps so that it has to be entered when a user adds a datasource. However I am not covering that here.
Note 5: Add (and remove) your own parameters…
This swagger file makes the assumption that PowerApps is going to send a file name for the photo, as well as a description, latitude and longitude. Note that all fields are set to required, but none have default values and the x-ms-visibility parameter is not specified, meaning that PowerApps will prompt the user to enter them.
Using the examples as a guide, add or remove parameters as you see fit.
Note 6: Set your function call names appropriately…
Going back to the top of of the file, update the description to suit the task you are performing. Pay special attention to “Title” and “operationId”, as PowerApps uses these. For example, based on the image below, you will be calling a function called PhotoHandler.UploadPhoto() from PowerApps.
At this point you should be able to save your file and register it as a custom connection and call it from PowerApps.
Note 7: Do not use the word “SharePoint” in your custom connector name
Believe it or not, if you name your custom connector with the word “SharePoint” it will confuse PowerApps completely. For example, consider this custom connector:
Now look what happens when you try to use it… you get the message “The data did not load correctly. please try again”, with a sub message of “Resource not found”…
The solution? Name your connector anything, so long as the word SharePoint is not there 🙂
Parting notes…
If you intend to send data back to Flow, you will also have the define the schema for what is returned to Flow in the responses section. I have not added any custom schema in the sample swagger file and discussing it is outside the scope of this article. But in case you are interested, to get you started, below is an example of calling Microsoft’s QNAmaker chatbot service REST API and sending the results back to PowerApps.
"responses": { "200": { "description": "OK", "schema": { "type": "object", "properties": { "answers": { "type": "array", "uniqueItems": true, "minItems": 1, "items": { "required": [ "answer", "score" ], "type": "object", "properties": { "answer": { "type": "string", "minLength": 1 }, "questions": { "type": "array", "items": { "type": "string" } }, "score": { "type": "number" } } } } }, "required": [ "answers" ] } }
Thanks for reading
Paul Culmsee
Hi Paul. How can I save images with same name without replacing the previous one ?
Hi,
i do exactly what you described in the video, but when i try to upload the file to custom connnection at flow, i got this error message:
Die angegebene Datei entspricht nicht der OpenAPI 2.0-Spezifikation: “JSON does not match all schemas from ‘allOf’. Invalid schema indexes: 0. Path ‘paths./e302efd6af064bde872e2c04edcb90e4/triggers/manual/paths/invoke.post.produces’.”
any idea?
Hello Paul,
You’re tutorial helped me a lot! but now I’m stuck at literally the last command of the tutorial 🙁
I get the error invalid number of arguments when I add the command: ForAll(Photolist;PhotoToSP.PhotoSP(FileName;Photo))
I have set api-version, sp, sv, sig on required and Internal and filled the default value with information from Flow.
Do you have a solution for this problem?
Thanks in advanced!
Hello Paul,
Formula: base64ToBinary(triggermultipartbody(0)[‘$content’]) is not working anymore in Flow as the formula is getting trimmed down to triggermultipartbody(0)[‘$content’] once you save the Flow. I am stuck now to get compatible file type in sharepoint.
Great tutorial and it explains in detail.
I got stuck . I get error when I tried to call the data connector and method as follows:
UploadIMageToSPList.PostPhoto failed:{“error”:{“code”:”DirectApiAuthorizationRequired”,”message”:”The request must be authenticated only by Shared Access scheme.”}
In my json file I have added default value for “sig” and used the same to create a custom data connector.
Is there anything I am missing?
Please help.
This is in reference to my previous post.
I have re-created .json file and edited in https://editor.swagger.io/ and tested from using “Execute” button with location of the picture and it added to the SP Library just fine.
Then,
1) I created a custom data connector and tried to test custom data connector using “test” option and I get no error in Custom Connector but picture does not get uploaded to the SP Library due to flow failure with error “InvalidTemplate. Unable to process template language expressions in action ‘Get_File_Content’ inputs at line ‘1’ and column ‘1903’: ‘The template language function ‘triggerMultipartBody’ failed to retrieve multipart contents from outputs. The supported multipart content type is ‘multipart/*’ and the provided content type is ”. ‘.” . This happening because I can not specify which picture (even though I specified full path to the .jpg file location).
2) When I tried to make a call to data connector to upload picture from PowerApps:
I get error “statusCode”: 404,
“message”: “Resource not found”
I am trying to do something similar to what TH did here:
http://www.cleverworkarounds.com/2017/11/13/a-sample-openapiswagger-file-for-powerapps/comment-page-1/#comment-85299
If I add “Update File properties” action after Create File in the flow, how to I extract metadata from URL?
Something like longitude and latitude you have in the sample swagger.json file you have.
If I am trying to send “Model”, trigger()[‘outputs’][‘queries’][‘Model’] is the right way to do?
Fabulous article. Thank you. Microsoft are making development extremely challenging. While I appreciate innovation will result in change the lack of remedial documentation is astounding. What works one day doesn’t the next and no explanation whatsoever. Contact Microsoft customer support and they themselves are unable to explain. Such a cavalier approach may lead to customers to seek alternative solutions. Might be an idea to slow innovation and ensure those who are likely to be affected or provide support have access to documentation providing the solution for the update.
Great work on all your guides! I am doing a similar task of uploading images to SharePoint with and HTTP trigger from PowerApps. Now I need to return the specific url of the posted image (Link to item, in my case). I have already been able to enable PowerApps to ask for a “answers” response and store this. Unfortunately, this is now a blank record (I am using the code example you posted to get a response). I can not figure out how to define this variable in flow which carries the image url. I am using an array (answers) with item answer holding the url (I didn’t modify your code yet before I could make it work). I have tried numerous things with the Response function with no luck. Could you elaborate on this?
Not sure if you reply to these comments, but I am running into a problem. I created this based on the template you provided and it uploads and creates a flow just fine. The problem I have is when I try to setup my upload picture button (which is for a single picture, not a gallery), I don’t get the same parameters for filename and photo. I am trying to add a photo to an existing list so I would like the photo name to pull from one of the columns and save it to a column I have in my list for pictures. I can’t figure out how to do it though. Any suggestions would be greatly appreciated.
What were the parameters you got? Your first sentence implied it worked so I am a little confused
Everything has worked up to the point where I try to implement it in the app. When I tried to use the same “ForAll” line that you did, (yours is PhotoToSPDemo and mine is UploadPhotoToSP) it does not let me use FileName, Photo. I’m guessing part of it is how my app is setup and that this template also adds a description? I don’t mind not using FileName,Photo as I would like to select auto-populated fields from the items information so it names the picture right and stores it with the right object.
You used a collection for your upload, but I’m using the “add picture” option. I figured it should be the same whether I’m adding 1 or multiple pictures.
I’ve posted my question and a picture of the app in the PowerApps forums if you’d like to see what it looks like.
https://powerusers.microsoft.com/t5/General-Discussion/Patch-picture-to-existing-list/td-p/184421
“ForAll()” has no place in this context as that is used to iterate through collections. Lose ForAll() and see how you do
losing the ForAll, I end up with AddPicture_1,UploadPhoto.UploadPhotoToSP(DataCardValue8.Text,DataCardValue7.Text,AddPicture_1)
AddPicture_1 is the Add Picture option. UpLoadedImage4 is where the actual image is (a sub item of AddPicture_1). Not sure what I’m doing wrong here.
DataCardValues would give it the name from the current item. it gives me an error with the comma after addpicture. I’ve tried removing the comma and the AddPicture but get errors elsewhere.
After fiddling with it a bit, I ended up with UploadPhoto.UploadPhotoToSP(Item_x0020__x0028_CIMs_x0029__x0_DataCard1.DisplayName,Title_DataCard1.DisplayName,UploadedImage4)… while it doesn’t error and the flow claims it succeeds successfully, it’s not adding a picture to the item in question nor is it creating a new item in the list . . . I have no idea where it’s putting the picture, if it’s uploading it at all…
i having:
“Authorization failed” on PostPhotoToSP.PostPhoto, “the authentication credentials are not valid”
im having:
“Authorization failed” on PostPhotoToSP.PostPhoto, “the authentication credentials are not valid”
Help! I am able to successfully publish an image to SharePoint through a REST client (Google Advanced REST Client), but when I connect to the PowerApp my flow fails with the error “Unable to process template language expressions in action ‘Get_File_Data’ inputs at line ‘1’ and column ‘1921’: ‘The template language function ‘triggerMultipartBody’ failed to retrieve multipart contents from outputs. The supported multipart content type is ‘multipart/*’ and the provided content type is ‘application/octet-stream’. ‘.” When running through the REST client the content type of the Get File Data node is coming in as ‘application/octet-stream’ and is being handled correctly.
Input from REST Client
Method: Post
URL: https://xxx/workflows/workflowID/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=7nX9puujHnVVSBa0s90byvZTLAUSsTK7z19gFliGCQI&filename=newimage.jpg
Headers: content-type mulitpart/form-data
Body: newImage.jpg
Get File Data in Flow showing
{“$content-type”:”application/octet-stream”,
“$content”: base64EncodedImage}
PowerApps Custom Connector
URL: https://xxx/workflows/workflowID/triggers/manual/paths/invoke
Query: (field, required, visibility, default)
api-version: required, internal, 2016-06-01
sp: required, internal, /triggers/manual/run
sv: required, internal, 1.0
sig: required, internal, 7nX9puujHnVVSBa0s90byvZTLAUSsTK7z19gFliGCQI
filename: required, none, “”
Header:
content-type: required, internal, multipart/form-data
Get File Data showing error mentioned above when reviewing Flow.
Hello Paul;
my problem is that the connector may not be added to the powerapps; company restrictions / loss of data etc.
Do you have an idea where to justice, that Im allowed to use the connector?
Did you used the “Test of the connector” in the area of the “edit userdefined connector”?
In the Textfield “Photo” I cannot insert jpg.Data.
Thanks in foreward
Jens