I recently had a requirement come up while implementing an On-Boarding Workflow. The requirement from my client was:
"we want to have multiple list item attachments for the new employee process but when the workflow starts I need to have different attachments emailed to different employees".
I started to think about this because there is not an action within Office 365 to get list item attachments, although there is a web service we can call to get them. I wanted to document the steps I needed to take just in case others needed to do something similar.
Step 1) Build Dictionary to set the Request Headers.
Drag and drop Build Dictionary action on to the canvas and Add the following Items: Below is what the action will look like when you are done.
- Key: Content-type
- Type: Text
- Value: application/json;odata=verbose
- Key: Accept
- Type Text
- Value: application/json;odata=verbose
- Output: RequestHeader of type Dictionary
Step 2) Build URL String
Use the Build String Action to build out your Web Service Call URL and Output to a String Variable (I used varWebServiceURL) . Everything in RED makes this URL Dynamic to pass in the right information.
REST Web Service URL to only return information around the list item Attachments
{Workflow Context:Current site URL}/_api/web/lists/getbytitle('{Workflow Context:List Name}')/items({Current Item:ID})/attachmentFiles
Break Down:
- I use the Get Current Site URL to make my workflow Dynamic instead of hard coding the URL to the Site
- /_api/web/lists/getbytitle('LIST NAME')
- get to the list you want to get attachments from
- /items(CURRENT ITEM:ID)
- we want to make sure we are working with the right list item so we need to tell the web service what ID we want to use
- attachmentFiles
- This is acting more or less like a filter because I only want properties around the attachments returned from my web service call
In the end this is what your action should look like:
Step 3) Use the Call HTTP Web Service Action
- Address: varWebServiceURL
- Request Type: HTTP GET
- Request Header: Use your Request Header Variable in my case it was called (RequestHeader) type Dictionary
- Request Content: Leave Blank
- Response Content: Create a new Variable called ResponseContent of type Dictionary
- Response Header: Create a new Variable called ResponseHeaders of type Dictionary
- Response Status Code: Create a new Variable called ResponseCode of type Text
Configured Action
Step 4) Next we need to get the Response Content returned from the web service.
We will use the Get an Item From a Dictionary Action to get our Response from the web service. Drag and Drop that action and double click to configure.
Dictionary: ResponseContent (var used from the action above)
Item Name or Path: Because this is getting returned as a JSON object we need to make sure we get to the right part and we want the results path so we need to enter: d/results
Output: I created a new variable called tempDictionary to store my results
Configured Action
Step 5) We need to get a count of the items so we know how many times we need to loop though the results to get the data we need. Use the Count Items in a Dictionary Action and double click to configure.
- Dictionary Variable: tempDictionary
- Output: New Variable ResonseCount of type Integer
Configured Action
Step 6) We also need to create a new Variable called LoopCounter of Type Integer and use the Set Variable Action to set it to 0
Step 7) Now we need to loop through our returned contents. Use the Loop n Times Action and configure it with the ResponseCount variable you set a couple steps ago so the action knows how many time to loop.
Configured Action
Step 8) Now that we are looping we can start to get the individual attachments from the response. We will use the Get an Item from Dictionary Action and configure it as follows.
- Dictionary: ResponseContent
- Item Name or Path: d/results({Variable:LoopCounter})/FileName (we use the loop counter as our index to get the file name so then I can build the URL later).
- Output: varTitle (this is a new string variable to store the attachment title we will use later)
Configured Action
Step 9) You will repeat this step as many times as you need to and You might handle this next step differently depending on your desired outcome, but with our new employees they will always have the same documents uploaded. So I created a string variable for each one. For example: varResumeURL, varEmpAgreementURL, so on and so forth. I did this because as of this post you cannot attach list items to an email.
(Disclaimer: I tried to use the External Email and attachment, but the attachment failed.)
Within my workflow I have an few Run IF Actions and I configure them to look to see if the contents of the varTitle Contains (ignoring case) key words in my file names, for example: Resume, Agreement, etc.
Here is an example configuration of one of my RUN IF Actions
If I get a match for what I am looking for I use the Set Workflow Variable Action and build out my URL to the Attachment. Each List item has a unique URL you can use to get to your attachments. I set my varResumeURL to the following URL within the action. The key here in this url is going to the ListName/Attachements/ID/FileName
{Workflow Context:Current site URL}/Lists/NewUserRequest/Attachments/{Current Item:ID}/{Variable:varTitle}
The next step is to build out my Send Email Action. I drag/Drop the Send Email Action on and then in the body of the email I create a section called Attachments and then use the Hyperlink Builder to create a link to the document, so I am not really attaching the document which saves on email bloat, I am just linking to it.
Click Insert Link and Configure as follows:
That's it. This would be a really good utility workflow as well, because you could pass in the List Name as well.
Here is what the full workflow looks like. If you have questions, post them as I am sure more than 1 person has the same question.