“I don’t want hundreds of flow runs, the Power Automate flow should run only if the email contains attachment with a specific name!”
When you build a flow to process incoming emails, you’ll start from the ‘When a new email arrives’ trigger. This trigger allows you to do some basic configuration, e.g. process only emails with attachments, or with a specific subject. But what about the settings not available directly in the action? What if you’re not interested in all emails with attachments, but only emails with a specific one? How do you tell the flow to run only if the attachment has some name? You surely don’t want to solve it with the ‘Condition’ action.
Add a trigger condition
As for any other trigger, you’re not limited only to the available options. You can add your own trigger condition to specify when the flow should run. In this case it’s when the email contains an attachment with a specific name.
If you check the trigger output, you’ll see that the attachments are an array within the trigger body. Each of the objects in this array then contains the attachment information. That’s the information you must access in the trigger condition.
Following the article on extracting values from JSON, you’ll end with the expression below. It’ll return the whole content of the “attachments” array from the trigger.
triggerOutputs()?['body']?['attachments']
Now, when you have the attachments information, you can start looking for a specific attachment.
Search for a full attachment name
If you’re looking for a full attachment name, you can use a very simple, not very elegant solution. Convert the array into a string, and search if it contains the full attachment name incl. the extension, e.g.
@contains(string(triggerOutputs()?['body']?['attachments']),'Ultimate PA expressions cheatsheet.docx')
Since you’re searching for a full name, there’s no risk that the array would contain exactly the same string in another place. It doesn’t matter if you search only among the file names, or if you keep also the other information.
Search for a part of a name
When you search only for a single word, or if you want to use another condition than ‘contains’, it’s better to extract the file names. With only the file name you can use also the startsWith(…) and endsWith(…) conditions.
In this situation you can’t preprocess the attachments in any way. You can’t add another action to extract the attachment names, you must access them directly in the trigger. Therefore, you’ll need the xpath(…) expression. The approach is the same as when exporting multiple choice columns to csv. Take the array, and extract only a specific value – here it’s the attachment ‘name’.
xpath(xml(json(concat('{"body":{"value":', triggerOutputs()?['body']?['attachments'], '}}'))), '/body/value/name/text()')
Convert it into a string for easier use in the trigger condition with the expression below. It’ll return attachment names separated by comma.
join(xpath(xml(json(concat('{"body":{"value":', triggerOutputs()?['body']?['attachments'], '}}'))), '/body/value/name/text()'),',')
All that’s left is to turn it into a trigger condition, e.g. to check if the attachment name starts with the string ‘Ultimate’.
@startswith(join(xpath(xml(json(concat('{"body":{"value":', triggerOutputs()?['body']?['attachments'], '}}'))), '/body/value/name/text()'),','), 'Ultimate')
Note: just be careful about the startsWith(….) condition as it’ll check only the name of the first attachment. The same applies to endsWith(…) and the last attachment.
You can also search if the file attachment name contains a specific word, e.g.
@contains(join(xpath(xml(json(concat('{"body":{"value":', triggerOutputs()?['body']?['attachments'], '}}'))), '/body/value/name/text()'),','), 'Ultimate')
Summary
If you want to run Power Automate flow only for email with a specific attachment, you’ve got two options. You can run the flow for all incoming emails and evaluate them in a flow, or you can add a trigger condition to reduce the flow runs.
Don’t be worried only because the trigger action doesn’t have a field for that. With trigger conditions you can do much more, as already shown when searching for multiple subjects. Just extract the attachment information from a trigger, and build a trigger condition that’ll check it. This way you can save flow runs, your flow will be simpler, and the flow run history will be easy to read.
Hey I’ve tried your solution filter for mails with an attachment which contains e.g. project in it. But while testing my flow is running and running and running endless.
here the filter: @startswith(join(xpath(xml(json(concat(‘{“body”:{“value”:’, triggerOutputs()?[‘body’]?[‘attachments’], ‘}}’))), ‘/body/value/name/text()’),’,’), ‘Project’)
what am i doing wrong?
Best Regards,
Eddy
Hello Eddy,
running flow is not a problem of a trigger condition, wrong trigger condition would cause it to not run at all.
If you’re looking for string in the attachment name, use contains(…) instead of startswith(…) expression. StartsWith(…) searches for a match at the beginning of the first attachment name, contains(…) will search anywhere among the attachments name.
Hi, Tom.
I like this solution a lot! However, is it possible to process all of the attachments contained within an email using the endsWith to filter for ‘.xlsx’? I’m finding that images in my signature will be the first item in the attachments array instead of the intended Excel file which does not allow me to set the trigger with endsWith.
Thanks,
John
Hello John,
you can’t use endsWith for multiple files, but you can use the contains expression to check if any of the file names contains the specific string (the last example), I guess there won’t be many files with ‘.xlsx’ in the file name itself.
Could you plese tell me if we are using get email v3 action and how to use the condition to get the specfic attachment from email
Hello Asha,
this example is build over trigger – it’ll start the flow only if the email contains a specific attachment. You don’t need ‘Get email’ action as it processes the emails as they arrive.
Instead of processing EACH attachment, can I get only a specific attachment like .CSV and ignore the rest inside the email.