Power Automate Custom Connector – Implement Retry Function, Azure Application Insights

Another journey on how to create a Power Automate Custom Connector with .NET API 8. Last week, we created a .NET API Project that implements the API Key for the Authorization process. Today, we will add more features including adding monitoring logs using Azure Application Insight and how to create an action where we can implement the retry function.

Add Azure Application Insight

If you already deployed your API into Azure App Service > you can go to “Monitoring” > Application Insights > you can click “Enable” > “Create new resource” > set the NameLocation, and also the Log Analytics Workspace > click “Apply“:

Create Azure Application Insight

Create Azure Application Insight

If you open the App Service > Settings Environment Variables, the system will generate the settings necessary for Azure Application Insight.

.NET API

From last week’s implementation, I learned that I was wrong about how to provide “Request-Response” information to Power Automate Custom Connector. The best way is still using swagger.json information which I corrected on today’s implementation. But, first, we need to add below NuGet package:

Microsoft.ApplicationInsights.AspNetCore

Once installed, you can create a Folder named “Logging” and add the below class:

123456789101112131415161718usingMicrosoft.ApplicationInsights.Channel;usingMicrosoft.ApplicationInsights.DataContracts;usingMicrosoft.ApplicationInsights.Extensibility;namespacePowerAutomateCustomConnector.Logging;publicclassCustomHeaderTelemetryInitializer(IHttpContextAccessor httpContextAccessor) : ITelemetryInitializer{    publicvoidInitialize(ITelemetry telemetry)    {        if(telemetry isnot RequestTelemetry requestTelemetry) return;                // Add custom headers to the request telemetry        varheaders = string.Join(",", httpContextAccessor.HttpContext?.Request.Headers.Select(x => $"{x.Key}: {x.Value}") ?? Array.Empty<string>());        requestTelemetry.Properties["HttpHeaders"] = headers;        requestTelemetry.Properties["HttpBody"] = httpContextAccessor.HttpContext?.Request.Body?.ToString();    }}

The purpose of the above code is to add more information to the Request table (inside the CustomDimensions). You can skip this part as this is not mandatory. The idea of this is to add more information if you need to use it later on for analysis purposes.

about:blank

Next, here are the changes on the Program.cs. Here I’m still using minimal API. But, for sure. If the requirements become more and more complex, we can split the implementation.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465usingMicrosoft.ApplicationInsights.Extensibility;usingMicrosoft.OpenApi.Models;usingPowerAutomateCustomConnector.Authentication;usingPowerAutomateCustomConnector.Logging;varbuilder = WebApplication.CreateBuilder(args);// Add services to the container.// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen(c =>{    c.AddSecurityDefinition("ApiKey", newOpenApiSecurityScheme    {        Type = SecuritySchemeType.ApiKey,        Name = "x-api-key",        In = ParameterLocation.Header    });    c.AddSecurityRequirement(newOpenApiSecurityRequirement { {         newOpenApiSecurityScheme { Reference = newOpenApiReference { Type = ReferenceType.SecurityScheme, Id = "ApiKey"} },        []    } });});builder.Services.AddAuthorization();builder.Services.AddAuthentication();builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();builder.Services.AddSingleton<ITelemetryInitializer, CustomHeaderTelemetryInitializer>();builder.Services.AddApplicationInsightsTelemetry();varapp = builder.Build();app.UseSwagger(c =>{    c.SerializeAsV2 = true;    c.PreSerializeFilters.Add((swagger, httpReq) =>         swagger.Servers = newList<OpenApiServer>( newOpenApiServer[]        {            new() { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}"}        }));});app.UseSwaggerUI();app.UseAuthorization();app.UseAuthentication();app.UseMiddleware<ApiAuthenticationMiddleware>();app.UseHttpsRedirection();app.MapPost("/orderAsc", (string[] stringArray) =>    {        if(stringArray.Contains("Error"))        {            returnResults.Problem("Error", statusCode: StatusCodes.Status429TooManyRequests);        }                varresult = stringArray.OrderBy(e=> e).ToArray();        returnResults.Ok(result);    })    .Produces(StatusCodes.Status200OK)    .Produces(StatusCodes.Status429TooManyRequests)    .WithName("OrderAsc");app.Run();

Let’s break down the changes for today’s implementation:

  • For lines 11-23, this is the mandatory setting for Swagger so we can enable API Key Authentication via Swagger UI. Once you add this and open the URL/swagger, you can see the below Authorize button and you can key in the x-api-key also for testing directly via Swagger UI:
Adding Authorize in Swagger
  • For lines 28 – 29, we added these 2 lines to supply the information needed CustomHeaderTelemetryInitializer.cs.
  • For line 30, we enabled the Application Insight (it will automatically use the settings in App Service > Settings Environment Variablesto our API.
  • For lines 34-42, we force the Swagger to use V2 and add the “Host” parameter as this is mandatory when we want to update the Custom Connector.
  • For lines 51-63, we changed the API implementation to a simple function to order an array of strings. If there is a string with the value of “Error“, it will throw an HTTP error code of 429 (Too Many Requests). With the return of these error codes (408, 429, and 5xx), we can ask Power Automate to run the retry function with the predefined policy (which will be explained later on).

With these changes, you can deploy to your App Service!

Update Custom Connector and Power Automate Testing

Once you deploy the changes into your App Service, you can go to YOUR-URL/swagger > there you can click the swagger.json:

swagger.json file

swagger.json file

You can copy the content of the above file > go to your Custom Connector > click the “Swagger editor” > then click in the editor > Ctrl + All to select all existing content >paste the swagger.json content:

Change the Custom Connector definition

Change the Custom Connector definition

Once you paste the content, it will be asking you if you want to replace the content as yaml:

Confirmation to paste the JSON as YAML

Confirmation to paste the JSON as YAML

Super Early Bird
Once you click “Ok”, you can “Update connector” and test the changes!

If you go to the “Definition“, then you can see that the Response now contains “200 – Success” and also “429 – Too Many Requests“:

Update Response API

Update Response API

Last, for the demo, I created the below flow to invoke the “Retry” mechanism:

Create Flow with "Error" string

Create Flow with “Error” string

Next, you can go to Advance Options (… button on the top left side of the action) of the Custom Connector > Settings > On “Retry Policy” we can set the Type as “Fixed Interval“, Count as 3, and Interval as PT20S which means it will keep retrying the process every 20 seconds (until 3 times). Once done, you can run the Test and we can verify it as well from the Azure Application Insights:

Retry function + Azure Application Insight Logs

Retry function + Azure Application Insight Logs

Here is the result if the Custom Connector is successfully run:

Demo success

Demo success

Hope you learn something today! Happy CRM-ing! 😎

About the Author

Temmy Wahyu Raharjo

Temmy Wahyu Raharjo, MVP

Dynamics CRM CE Technical Consultant | Power Platform | Blogger | MVP Business Applications | Loves the concept of Test Driven Development | Certified MCP | Certified Scrum Master

Reference:

Wahyu, T (2025). Power Automate Custom Connector – Implement Retry Function, Azure Application Insights. Available at: Power Automate Custom Connector – Implement Retry Function, Azure Application Insights – Temmy Wahyu Raharjo [Accessed: 15th January 2025].

Share this on...

Rate this Post:

Share: