Skip to content

Commit

Permalink
Merge pull request #13 from pnp/dlaskewitz-always-reply-to-request
Browse files Browse the repository at this point in the history
Migrated sample from powerautomate to powerplatform
  • Loading branch information
Laskewitz committed Aug 19, 2023
2 parents c082471 + 57f651d commit cc5665e
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 0 deletions.
76 changes: 76 additions & 0 deletions samples/always-reply-to-request/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Pattern: Always respond to a request

## Summary

A pattern for making sure that the Flow always provides a responds to a request.

![picture of the flow](assets/flow.png)

## Applies to

* [Microsoft Power Automate](https://docs.microsoft.com/en-us/power-automate/getting-started)
* [Azure Logic Apps](https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-overview)

## Compatibility

![Premium License](https://img.shields.io/badge/Premium%20License-Required-yellow.svg "Premium license required")
![On-Premises Connectors](https://img.shields.io/badge/On--Premises%20Connectors-No-green.svg "Does not use on-premise connectors")
![Custom Connectors](https://img.shields.io/badge/Custom%20Connectors-Not%20Required-green.svg "Does not use custom connectors")

## Authors

Solution|Author(s)
--------|---------
always-reply-to-request | [Remy Blok](https://github.com/remyblok), Prodware

## Version history

Version|Date|Comments
-------|----|--------
1.0|May 02, 2021|Initial release

## Features

Power Automate has the ability to be called by 3th parties using HTTP requests or via the API. In these cases the caller will wait for the Flow to respond. If the Flow does not respond you get an HTTP 500 error from the Flow runtime with the message `The server did not receive a response from an upstream server.`

This pattern makes sure that you always respond to the caller. Also in case you Flow fails you can then send back relevant information on why the flow has failed. In this sample it returns the error that occurred in the Scope. But responses to the end user with a descriptive message is always preferred.

Requests and responses are used in multiple areas:
* Per this sample, using `HTTP Request`-trigger and `HTTP Response`-action to create a Flow that is callable via HTTP by any party that can handle HTTP
* When using the Flow as a [child Flow](https://docs.microsoft.com/en-us/power-automate/create-child-flows). The trigger will be `Manual trigger`, the response will be a `Respond to PowerApp` or a `HTTP Response` action
* When starting a [Flow from a Canvas Power App](https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/using-logic-flows). In this case the trigger is `PowerApps`, the response will be a `Respond to PowerApp` or a `HTTP Response` action

In this sample we use a Scope to contain all the logic of the Flow. By setting the 'Configure run after' on the error `Response`-action to run only on error we can differentiate the error between sending a OK or an Error message. By default any action's 'Configure run after' is set to 'is successful'.
![Go to Run After](assets/RunAfter.png)
![Go to Run After](assets/RunAfterSettings.png)

Note: you can setup the responses to use the [Asynchronous pattern](https://docs.microsoft.com/en-us/azure/connectors/connectors-native-http#asynchronous-request-response-behavior). This is useful for long running flows. In this case the error will also be correctly returned as result for your long running flow. This can also be used when the Flow is used as a child flow using the `Respond to PowerApps`-action. It does *not* work when the Flow is called from a Power App.

Note 2: The reason that the OK response is outside the Scope in stead of having one of more responses inside the Scope, is to make sure the schema of the result is the same. Since there is only one place where the result (and it's schema) is defined, changes to the result (schema) are easily realized. Since you are basically setting up an API having a single consistent schema for all responses is recommended.

## Minimal Path to Awesome

* [Download](solution/always-reply-to-request.zip) the `.zip` from the `solution` folder
* [Import](https://flow.microsoft.com/en-us/blog/import-export-bap-packages/) the `.zip` file using **My Flows** > **Import** > **Upload** within Microsoft Flow.

## Disclaimer

**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**

## Help

We do not support samples, but we this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.

If you encounter any issues while using this sample, [create a new issue](https://github.com/pnp/powerautomate-samples/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=bug-report.yml&sample=always-reply-to-request&authors=@remyblok&title=always-reply-to-request%20-%20).

For questions regarding this sample, [create a new question](https://github.com/pnp/powerautomate-samples/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=question.yml&sample=always-reply-to-request&authors=@remyblok&title=always-reply-to-request%20-%20).

Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/powerautomate-samples/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected&template=suggestion.yml&sample=always-reply-to-request&authors=@remyblok&title=always-reply-to-request%20-%20).

## For more information

- [Create your first flow](https://docs.microsoft.com/en-us/power-automate/getting-started#create-your-first-flow)
- [Microsoft Power Automate documentation](https://docs.microsoft.com/en-us/power-automate/)


<img src="https://telemetry.sharepointpnp.com/powerautomate-samples/samples/exception-handing-in-do-until-loop" />
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/always-reply-to-request/assets/flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions samples/always-reply-to-request/assets/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/pnp/samples/v1.0/metadata-schema.json",
"name": "pnp-powerplatform-samples-always-respond-to-request",
"version": "1.0.0.0",
"source": "pnp",
"creationDateTime": "2021-05-02",
"updateDateTime": "2021-05-02",
"title": "Pattern: Always respond to a Request",
"shortDescription": "A pattern for making sure that the Flow always provides a responds to a request.",
"longDescription": [
"A pattern for making sure that the Flow always provides a responds to a request."
],
"url": "https://github.com/pnp/powerplatform-samples/tree/main/samples/always-reply-to-request",
"products": [
"Power Automate",
"Power Platform"
],
"tags": [
"PATTERNS",
"EXCEPTION-HANDLING"
],
"categories": [
"POWERAUTOMATE"
],
"metadata": [
{
"key": "POWERAUTOMATE-PREMIUM",
"value": "yes"
},
{
"key": "POWERAUTOMATE-ONPREM",
"value": "No"
},
{
"key": "POWERAUTOMATE-CUSTOMCONNECTOR",
"value": "No"
}
],
"thumbnails": [
{
"type": "image",
"order": 100,
"url": "https://github.com/pnp/powerplatform-samples/blob/main/samples/always-reply-to-request/assets/flow.png?raw=true",
"alt": "Preview of the solution"
}
],
"authors": [
{
"gitHubAccount": "remyblok",
"name": "Remy Blok",
"pictureUrl": "https://github.com/remyblok.png"
}
],
"references": [
{
"name": "Create your first flow",
"description": "Anyone from a basic business user to an IT professional can create automated processes using Power Automate's no-code/low-code platform.",
"url": "https://docs.microsoft.com/en-us/power-automate/getting-started#create-your-first-flow"
},
{
"name": "Microsoft Power Automate documentation",
"description": "Power Automate is a service that helps you create automated workflows between your favorite apps and services to synchronize files, get notifications, collect data, and more.",
"url": "https://docs.microsoft.com/en-us/power-automate/"
}
]
}
]
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PowerAppsTargetsPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps</PowerAppsTargetsPath>
</PropertyGroup>

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.props" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.props')" />

<PropertyGroup>
<ProjectGuid>a058e0c4-51e0-45a0-953f-ca4da3cc082a</ProjectGuid>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<!--Remove TargetFramework when this is available in 16.1-->
<TargetFramework>net462</TargetFramework>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<SolutionRootPath>src</SolutionRootPath>
</PropertyGroup>

<!--
Solution Packager overrides, un-comment to use: SolutionPackagerType (Managed, Unmanaged, Both)
Solution Localization Control, if you want to enabled localization of your solution, un-comment SolutionPackageEnableLocalization and set the value to true. - Requires use of -loc flag on Solution Clone or Sync
-->
<!--
<PropertyGroup>
<SolutionPackageType>Managed</SolutionPackageType>
<SolutionPackageEnableLocalization>false</SolutionPackageEnableLocalization>
</PropertyGroup>
-->

<ItemGroup>
<PackageReference Include="Microsoft.PowerApps.MSBuild.Solution" Version="1.*" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\.gitignore" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\bin\**" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\obj\**" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.cdsproj" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.cdsproj.user" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.sln" />
</ItemGroup>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\**" Exclude="@(ExcludeDirectories)" />
<Content Include="$(SolutionPackageZipFilePath)">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.targets" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.targets')" />

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Entities />
<Roles />
<Workflows />
<FieldSecurityProfiles />
<Templates />
<EntityMaps />
<EntityRelationships />
<OrganizationSettings />
<optionsets />
<CustomControls />
<EntityDataProviders />
<Languages>
<Language>1033</Language>
</Languages>
</ImportExportXml>
85 changes: 85 additions & 0 deletions samples/always-reply-to-request/sourcecode/src/Other/Solution.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<ImportExportXml version="9.2.23073.178" SolutionPackageVersion="9.2" languagecode="1033" generatedBy="CrmLive" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SolutionManifest>
<UniqueName>AlwaysReplyToHTTPRequest</UniqueName>
<LocalizedNames>
<LocalizedName description="Always reply to HTTP request" languagecode="1033" />
</LocalizedNames>
<Descriptions />
<Version>1.0.0.0</Version>
<Managed>2</Managed>
<Publisher>
<UniqueName>PnP</UniqueName>
<LocalizedNames>
<LocalizedName description="PnP" languagecode="1033" />
</LocalizedNames>
<Descriptions />
<EMailAddress xsi:nil="true"></EMailAddress>
<SupportingWebsiteUrl xsi:nil="true"></SupportingWebsiteUrl>
<CustomizationPrefix>pnp</CustomizationPrefix>
<CustomizationOptionValuePrefix>89378</CustomizationOptionValuePrefix>
<Addresses>
<Address>
<AddressNumber>1</AddressNumber>
<AddressTypeCode>1</AddressTypeCode>
<City xsi:nil="true"></City>
<County xsi:nil="true"></County>
<Country xsi:nil="true"></Country>
<Fax xsi:nil="true"></Fax>
<FreightTermsCode xsi:nil="true"></FreightTermsCode>
<ImportSequenceNumber xsi:nil="true"></ImportSequenceNumber>
<Latitude xsi:nil="true"></Latitude>
<Line1 xsi:nil="true"></Line1>
<Line2 xsi:nil="true"></Line2>
<Line3 xsi:nil="true"></Line3>
<Longitude xsi:nil="true"></Longitude>
<Name xsi:nil="true"></Name>
<PostalCode xsi:nil="true"></PostalCode>
<PostOfficeBox xsi:nil="true"></PostOfficeBox>
<PrimaryContactName xsi:nil="true"></PrimaryContactName>
<ShippingMethodCode>1</ShippingMethodCode>
<StateOrProvince xsi:nil="true"></StateOrProvince>
<Telephone1 xsi:nil="true"></Telephone1>
<Telephone2 xsi:nil="true"></Telephone2>
<Telephone3 xsi:nil="true"></Telephone3>
<TimeZoneRuleVersionNumber xsi:nil="true"></TimeZoneRuleVersionNumber>
<UPSZone xsi:nil="true"></UPSZone>
<UTCOffset xsi:nil="true"></UTCOffset>
<UTCConversionTimeZoneCode xsi:nil="true"></UTCConversionTimeZoneCode>
</Address>
<Address>
<AddressNumber>2</AddressNumber>
<AddressTypeCode>1</AddressTypeCode>
<City xsi:nil="true"></City>
<County xsi:nil="true"></County>
<Country xsi:nil="true"></Country>
<Fax xsi:nil="true"></Fax>
<FreightTermsCode xsi:nil="true"></FreightTermsCode>
<ImportSequenceNumber xsi:nil="true"></ImportSequenceNumber>
<Latitude xsi:nil="true"></Latitude>
<Line1 xsi:nil="true"></Line1>
<Line2 xsi:nil="true"></Line2>
<Line3 xsi:nil="true"></Line3>
<Longitude xsi:nil="true"></Longitude>
<Name xsi:nil="true"></Name>
<PostalCode xsi:nil="true"></PostalCode>
<PostOfficeBox xsi:nil="true"></PostOfficeBox>
<PrimaryContactName xsi:nil="true"></PrimaryContactName>
<ShippingMethodCode>1</ShippingMethodCode>
<StateOrProvince xsi:nil="true"></StateOrProvince>
<Telephone1 xsi:nil="true"></Telephone1>
<Telephone2 xsi:nil="true"></Telephone2>
<Telephone3 xsi:nil="true"></Telephone3>
<TimeZoneRuleVersionNumber xsi:nil="true"></TimeZoneRuleVersionNumber>
<UPSZone xsi:nil="true"></UPSZone>
<UTCOffset xsi:nil="true"></UTCOffset>
<UTCConversionTimeZoneCode xsi:nil="true"></UTCConversionTimeZoneCode>
</Address>
</Addresses>
</Publisher>
<RootComponents>
<RootComponent type="29" id="{cd602b70-a83e-ee11-bdf3-0022482a4279}" behavior="0" />
</RootComponents>
<MissingDependencies />
</SolutionManifest>
</ImportExportXml>
Loading

0 comments on commit cc5665e

Please sign in to comment.