What are the benefits to explain “Assignment required?” and “Visible to users?” flags to the customer?

Summary

To transition ADFS application to Entra ID you are creating the Enterprise application. You will notice two flags, “Assignment required?” and “Visible to users?”.

If you hover over the text it clearly states that if this flag is set to no means everyone will be able to see the app in the myapps.microsoft.com portal. This can be more educated to the customer to not to set as No because now the app is presence is available to everyone in the tenant.

The next flag is “Visible to users?”

This flag is important flag for the application modernization. I recommend to set to Yes, this will help end users to find the apps from myapps.microsoft.com flag. However, doing that you want to educate the customer not to set the previous flag “Assignment required?” to us, unless customer wants the app to be seen by everyone in the tenant.

What should you guide to the customer?

I recommend tell them the Entra ID application is like a fence now for their house (in this case application). The fence now can be controlled by them.

To control this application the customer can now add “User and groups”. Only those users or member of groups will be able to see the apps in myapps.microsoft.com portal.

What are the advantages?

Well, clearly you can educate customer that give visibility to those users you know they should see and access the apps. If they provide access to entire tenant that will make the apps visible to everyone in the tenant and most of time the end users will click to access the app. They most likely will fail or success to get in to the app but by doing the above simple step those issues can be addressed.

Conclusion

These flags are sometimes missed and I want to share for your awareness and reference.

https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/access-panel-collections

https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/custom-security-attributes-apps?pivots=portal

Posted in Azure, EntraID | Leave a comment

How to map ADFS roles claim rule to Entra ID application? 

Summary 

The following is a ADFS claim for the FooBar client’s application.   

@RuleTemplate = “LdapClaims” @RuleName = “AD Attributes” 

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname”, Issuer == “AD AUTHORITY”] =>  

issue( store = “Active Directory”,  

types = (  “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier”,  

“user.firstName”,  “user.lastName”), query = “;sAMAccountName,givenName,sn;{0}”, param = c.Value); 

@RuleTemplate = “EmitGroupClaims” @RuleName = “Contoso-CoolGroup-Admin” 

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid”, Value == “S-8-8-88-8888888888-888888808-80888888-888888”, Issuer == “AD AUTHORITY”] =>  

issue(Type = “http://schemas.microsoft.com/ws/2008/06/identity/claims/role”, Value = “Contoso-CoolGroup-Admin”, Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, ValueType = c.ValueType); 

@RuleTemplate = “EmitGroupClaims” @RuleName = “Contoso-CoolGroup-SSO” 

c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid”, Value == “S-9-9-99-9999999999-999999909-90999999-999999”, Issuer == “AD AUTHORITY”] =>  

issue(Type = “http://schemas.somevendor.com/ws/2021/10/identity/AccessGroup”, Value = “Contoso-CoolGroup-SSO”, Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, ValueType = c.ValueType); 

Explanation of the above rule: 

  1. AD Attributes Rule:
    • Template: LdapClaims 
      • Name: AD Attributes 
      • Condition: If the incoming claim type is a Windows account name issued by AD AUTHORITY. 
      • Action: Issue new claims for the user’s name identifier, first name, and last name by querying the Active Directory with the user’s sAMAccountName, givenName, and sn attributes. 
  2. Contoso-CoolGroup-Admin Group Claim Rule:
    • Template: EmitGroupClaims 
    • Name: CSOC-SG-CineNet-Admin 
    • Condition: If the incoming claim type is a group SID with a specific value, indicating membership in the  Contoso-CoolGroup-Admin group, issued by AD AUTHORITY. 
    • Action: Issue a role claim with the value Contoso-CoolGroup-Admin, carrying over the issuer and original issuer from the incoming claim. 
  3. Contoso-CoolGroup-SSO Group Claim Rule:
    • Template: EmitGroupClaims 
    • Name: Contoso-CoolGroup-SSO 
    • Condition: If the incoming claim type is a group SID with a different specific value, indicating membership in the Contoso-CoolGroup-SSO group, issued by AD AUTHORITY. 
    • Action: Issue an access group claim with the value Contoso-CoolGroup-SSO, carrying over the issuer and original issuer from the incoming claim. 

SAML will have following Claim(Value) pairs in the payload. The same should be generated for Entra ID SSO claim. 

Claim Value 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier UserPrincipalName 
user.firstName givenName 
user.lastName sn 
http://schemas.microsoft.com/ws/2008/06/identity/claims/role  Contoso-CoolGroup-Admin 
http://schemas.somevendor.com/ws/2021/10/identity/AccessGroupContoso-CoolGroup-SSO 
Claim(Value) pair

Step By Step Claims in Entra ID. 

#1 Create an enterprise application in the Entra ID 

#2 Create Single Sign-on Claims rules. 

#3 Using the Application ID go to the App registration of the Enterprise Application. 

#4 Create the Roles as specified in the claims rules. E.g. CSOC-SG-CineNet-Admin and CSOC-SG-CineNet-SSO 

#5 go to the enterprise application to add the above two groups and assign the roles respectively. 

# 6 go to Single Sign-On to add the two claims with “user.assignedroles” attribute 

Conclusion

The above method is for setting the roles claims for the Entra ID similar to ADFS.  

ADFS claims rules (Very good article) 

Tips and tricks with ADFS claims rules 

Posted in EntraID | Tagged , , , , | Leave a comment

How to call Epic on FHIR using Postman?

Summary

I was tasked to get Sandbox Epic test data using FHIR APIs. This article will briefly demonstrate how to setup the App on Epic?, How provide required permissions for the App? and How to call the API using the Postman.

Prerequisites:

You will need register and log in on the Epic on FHIR.

To sign up you will need a company email and web sites.

You will need to create the App and Secret.

Step by Step Solution

You can follow the steps from here to create a new App.

The documentation has some missing information on the creation of the app secret. The following information worked for me to create the app secrect.

Using following repository you can import the Environments and Postman collections.

https://github.com/pankajsurti/EPIC-FHIR/

After importing the environments, set the environments variables as following.

VariableCurrent value
AuthorizeURLhttps://fhir.epic.com/interconnect-fhir-oauth/oauth2/authorize
TokenURLhttps://fhir.epic.com/interconnect-fhir-oauth/oauth2/token
ScopePatient.Read Patient.Search
BaseURLhttps://fhir.epic.com/interconnect-fhir-oauth/api/FHIR

Getting the Token.

Open the Postman collection. Go to the Top Folder “Epic_Sandbox (R4). Click on Authorization tab. At the bottom click on the “Get New Token”. You will be redirected to the Login in page.

Note: Please use the user id and password from Sandbox test data page. Please note based on what you have selected in your app you can use patient’s login or the provider’s login.

Once you have the token you can make a call to the Read or Search for the Patient entity. You can experiment with various other FHIR (R4) resources. But keep in mind you will need to the Scope variable in the environments settings.

Conclusion

This blog post will help you how to get the Epic Sandbox data using the Postman. There are more steps to the get the production data. You will need to talk to Epic support and your customer to get the correct production FHIR Url. It is beyond the scope of this post.

Here are list of the FHIR endpoints for various Epic installation.

The next you can do it to create the Power Platform Connector using this Postman collection. You will need to setup the security and set redirect url in the Epic app.

I hope this helps you.

Posted in FHIR, Power Apps, Power Apps, Power Automate, Technical Stuff | Tagged , , , , | 1 Comment

How to create a JSON string array in PowerApps?

Summary

In Power Apps, creating a JSON object is easy. It can be initialized like this.

// Created an object with the types as array of strings
Set (
    anObject,
    {
        service: "Food",
        types: [
            "Bread",
            "Pasta",
            "Soup"
        ]
    }
);

We can use the JSON function to convert the above object to a string. It will give you the JSON string representation to pass to the API as a payload. (Note: I am simplifying the API you may have. It may be complex, but this example will give you an idea.)

Set (
    aJSONStr,
    JSON(anObject)
);

The output of the above call will be the following. Note that the “Value” is added to the string array ‘types’. It will not be a valid payload.

“{\”service\”:\”Food\”,\”types\”:[{\”Value\”:\”Bread\”},{\”Value\”:\”Pasta\”},{\”Value\”:\”Soup\”}]}”

The valid output of the payload string should be:

“{\”service\”:\”Food\”,\”types\”:[\”Bread\”,”Pasta\”,”Soup\”]}”

So, how can we achieve that?

Solution:

So, in Power Apps, that is the expected behavior for the array of strings to add the “Value” property.

The following solution is to replace the highlighted and stricken characters with a blank for every occurrence of the match found.

“{\”service\”:\”Food\”,\”types\”:[ {\”Value\”: \”Bread\” } , {\”Value\”: \”Pasta\” } ,{\”Value\”: \”Soup\” } ]}”

Utilized the Look Ahead Regular Expression technique.


Set (
    aValidJSONStr,
    With (
        {
            InnerWorkStr: JSON(
                anObject,
                JSONFormat.Compact
            )
        },
        With (
            {
                matches: MatchAll(
                    InnerWorkStr,
                    "\{""Value"":(?=.*\})"
                )
            },
            Collect(
                labelTextColl,
                InnerWorkStr
            );
            ForAll(
                matches,
                Collect(
                    labelTextColl,
                    // Find and replace end curly bracket of {\"Value\":\"Bread\"}
                    Replace(
                        // substitute 9 spaces for the string match {\"Value\":
                        Substitute(
                            Last(labelTextColl).Value,
                            ThisRecord.FullMatch,
                            "         "
                        ),
                        Find(
                            "}",
                            Last(labelTextColl).Value,
                            ThisRecord.StartMatch
                        ),
                        1,
                        " "
                    )
                );
            );
            Last(labelTextColl).Value;
            // Very Important as the results returned
        )// End of inner With
    )// End of outer With
);

After executing the above search and replace logic using the logical expression, you will get the valid JSON string with the correct string array as expected for the API payload.

Conclusion

I hope you find this useful for your project as I had to figure this out for my project, and I spent some time understanding the problem and coming up with the solution.

Please also refer to my previous posts related to this post.

How to create a JSON String array in PowerApps?

How to find and replace an array of strings from a large string variable using PowerFx?

Posted in Power Apps, Power Apps | Leave a comment

How to solve PowerFx JSON double escape quotes problem?

Summary

I encountered an interesting problem while working on an app with a JSON function. To remove the clutter of the complexities of the app, I will explain the need and problem in a simple scenario. Later I added the solution I used to resolve the issue.

Two needs of the app were:

#1: To get table information from the app as a JSON string.

// Real application the JSON will looked diffrent and large FHIR bundle objects.
// For the simplicity, the table may look like the following as JSON.
Set(
    SampleTableJSONStr,
    JSON(
        [
            {
                name: "Homer Simpson",
                age: 61,
                secretIdentity: "CoolDad"
            },
            {
                name: "Marj Simpson",
                age: 60,
                secretIdentity: "SuperMom"
            }
        ]
    )
);

#2: Pass the above to an API in JSON format with the request as shown below.

// The above string SampleTableJSONStr must be passed as the JSON with escape quotes
{
    sourceType: "inline",
    value:       SampleTableJSONStr
}

Problem

I used the following method to pass the request to API. But the API failed with an error. The error was the “value” passed in was not a well-formatted JSON object.


// *** First time, JSON was used for search-replace some hard-coded values.
Set(
       FHIRStr,
       JSON(SampleTableJSONStr)
);

// *** Second time, JSON was used to create the payload.
Set(
      APIPayLoad,
      JSON (
          {
              sourceType: "inline,"
              value:            FHIRStr
           }
       )
);

// The APIPayLoad was passed to the API request.

Output of the First time JSON use:

You will notice the escape characters for the double quote are added as \”. That is all great, but using the same string if you call the JSON function, adds more escaped characters.

Output of the Second time JSON use:

You will notice that the additional escaping happened from the previous call. You will see the backslash character is escaped, which makes the JSON string invalid.

Solution:

As you can see, the final string will add multiple escape characters using JSON numerous times. In the above problem, I had to fix the problem by substituting the escape characters’ values. Use the Substitute function.

// FIXED code.
// *** First time, JSON was used for search-replace some hard-coded values.
// replace \" with "
// for adding quote in the string literal, you need to add two quotes ("").
Set(
    FHIRStr,
    Substitute(
        JSON(SampleTableJSONStr),
        "\""", // i.e. \"
        """"   // i.e. "
    )
);

// *** Second time, JSON was used to create the payload.
// The JSON here is adding escape characters for beginning and end of the string.
// replace "\" with "  AND
// replace \"" with "
Set(
    APIPayLoad,
    Substitute(
        Substitute(
            JSON (
                {
                    sourceType: "inline",
                    value:       FHIRStr
                }
            ),
            """\""", // i.e. "\" 
            """"     // i.e. "
        ),
        "\""""", // i.e. \""
        """"     // i.e. "
    )
);

(FIXED) Output of the First time JSON use:

As you can see, the final string does not have escape characters added to the quotes.

(FIXED) Output of the Second time JSON use:

As you can see, the final “value” property has the correct JSON escaped string.

Conclusion

Some simple things can take a long time to debug. I was trying to find out why the API we were using was not responding correctly with a valid response. It always failed that the “value” property does not have the correct JSON string.

For your information, the API I was trying to call with the abovementioned request is for Azure Health Insights, located here.

Please refer to my other blog article. The trick I used was for the same project.
How to create a JSON String array in PowerApps?

Posted in Power Apps, Power Apps | Leave a comment

How to find and replace an array of strings from a large string variable using PowerFx?

Summary

To remove the clutter of the requirement, let’s reproduce the problem here. I was given a large string variable. The value of the string had the following values. The last “99999999” values are the digits and they can be any value and any repetition.


https://uts\-ws.nlm.nih.gov/rest/content/2023AA/source/SNOMEDCT_US/99999999

Note: There was a Hyphen character, so I had to add the escape for it like '\-'

The task was to replace the above string with the following string.

http://snomed.info/sct

One mistake every developer will make is that the ForAll in PowerFx will treat like ForEach. There is no ForEach in PowerFX.

Also, in the above find string, I need to make use of the Regular Expression to find the digits using the MatchAll.

Solution

I will first show you the entire solution code and explain the working of it.

/// The following is a record in some table... 
/// Assume the large value is in the "FHIRBundleObject" variable of type JOSN object.
/// Running JSON function on this variable returns a large string.
{
  sourceType: "inline",
  value: With (
    //// First part of With Operator
    {
      matches: MatchAll(
        JSON(FHIRBundleObject),
        "https://uts\-ws.nlm.nih.gov/rest/content/2023AA/source/SNOMEDCT_US/\d+",
        MatchOptions.IgnoreCase
      )
    }
    ,
    //// Second part of With operator
    Collect(
      labelTextColl,
      JSON(FHIRBundleObject)
    );
    ForAll(
      matches,
      Collect(
        labelTextColl,
        Substitute(
          Last(labelTextColl).Value,
          ThisRecord.FullMatch,
          "http://snomed.info/sct"
        )
      )
    );
    Last(labelTextColl).Value; // Very Important as the results returned
  ) // End of With
}

Assuming you are aware of how the PowerApps makes use of Tables and Records, I have reduced the code to start with a sample record. The first field is “sourceType”, which is just a hard-coded value. The second field “value” starts with the With Operator.

In this With’s initial record setting is to search for the RegEx expression using MatchAll. Notice there is “\d+” which does the job to find any digits with any repetitions. The matching values now are collected in the “matches” collection.

In the second part of With operator, we first convert the passed “FHIRBundleObject” variable as a large string using the JSON function.

Now iterate over the “matches” collection to find and replace the string using the Substitute function. The trick here is we will use the same collection i.e. “labelTextColl” and its Last index Value. Collect always add a new value at the end of the index. In this technique, we are always applying to replace to the last index value and adding the new value in the loop.

Conclusion

I hope this tip is useful to you in your scenario. I know it may be simple but if you want to do something similar using ForAll do something with a large string for a list of other collections such as a list of words to search. Just copy this code and make use of it. Thank you!

Posted in Power Apps | 1 Comment

Did you know the “addConnectorHideKey” query string parameter shows a hidden preview connector?

Summary

I was working with a colleague who asked me to test the new preview connector built. Since this is a preview connector I was not able to see it in my demo tenant.

I had to do the following steps.

#1 Go to Data -> Connection under https://make.powerautomate.com

#2 Select New connection

#3 In the URL append ?addConnectorHideKey={name_of_the_preview_connector}

Conclusion

This is a simple post with just a little trick to see the hidden connectors. I saw the article here as well.

Also, you could add ?addConnectorHideKey={name_of_the_preview_connector}&showHiddenConnectors=true.

Posted in Technical Stuff | Leave a comment

How to create smaller chunks of record collection from the large list of records in PowerApps?

Summary

The need was to create smaller chunks of records from the large list of record collections in the PowerApps using PowerFx functions.

To demonstrate the large list I have generated it using the Sequence PowerFx function. I used the “cur_date” and “ID” properties. The “ID” property is useful in the logic below, for your large list just simply create an ID property or anything else to put the record number value.

// just create 5,000 dates
// Make sure you have ID property with values as record number.
ClearCollect (
    LargeTestList,
    ForAll (
        Sequence(5000),
        {
            cur_date: DateAdd(
                Today(),
                Value,
                TimeUnit.Days
            ),
            ID: Value
        }
    )
);

Solution

Here is the solution code for the above large list to create chunks of 500 records.

// First get the first record of the large list
Set(
    firstRecord,
    First(LargeTestList)
);
// Now get the last record of the large list. NOTE: we make use of ID property.
Set(
    lastRecord,
    First(
        Sort(
            LargeTestList,
            ID,
            SortOrder.Descending
        )
    )
);
// Now, we need to check the large list count of rows how many chunks can be created.
Set(
    iterationsNo,
    RoundUp(
        CountRows(LargeTestList) / 500,
        0
    )
);
// Based on the number of chucks finding, now create the list of possible iterations
ClearCollect(
    iterations,
    Sequence(
        iterationsNo,
        0
    )
);
// Iterate over the iterations.
ForAll(
    iterations,
    With(
        {
            prevThreshold: Value(Value)       * 500,
            nextThreshold: (Value(Value) + 1) * 500
        },
        If (
            lastRecord.ID > Value,
            // Send the 500 resource to the FHIR
            // To similify the logic I have done collect here. But you can 
            // do whaterver with the chuncked data.
            Collect(
                datasource_temp,
                Filter(
                    LargeTestList,
                    ID > prevThreshold && ID <= nextThreshold
                )
            )
        )
    )
);

Conclusion

It took me some time to figure out how to create the chunks in Power Fx. I hope it may be useful to you if you have a similar need. To simplify the complexity of the Large collection I created a TEST collection here but you can simply add ID field in the collection.

Posted in FHIR, Power Apps | Leave a comment

How to POST master/details FHIR objects using bundle?

Summary

I was helping a colleague to store the ReaserchStudy and ResearchSubject FHIR objects. The objects are in the master details format. Every ReaserchStudy has ResearchSubject and they are linked using the Reference objects. The ResearchSubject has the “study” property of the ResearchStudy object.

Solution

To create such objects in large numbers, it is better to use the Bundle FHIR object. The Bundle objects have many different types and one of them is “transaction”. Using the “transaction” type we can post both objects and let the FHIR server add the references with the ACID transaction.

You will need to make a POST query to the FHIR. Just specify the FHIR Url, now /Bundle is needed. Use the following in the body of the request.

{
    "resourceType": "Bundle",
    "id": "bundle-transaction",
    "type": "transaction",
    "entry": [
        {
            // Point # 1
            "fullUrl": "urn:uuid:61ebe359-bfdc-6754-8bf2-c6e300945f0a",
            // Point # 2 
            "request": {
                "method": "POST",
                "url": "ResearchStudy"
            },
            "resource": {
                "resourceType": "ResearchStudy",
                "identifier": [
                    {
                        "use": "official",
                        "system": "https://clinicaltrials.gov",
                        "value": "NCT04625647"
                    }
                ],
                "title": "NCT04625647",
                "status": "active",
                "primaryPurposeType": {
                    "coding": [
                        {
                            "system": "http://some-url",
                            "code": "diagnostic",
                            "display": "Diagnostic"
                        }
                    ]
                },
                "phase": {
                    "coding": [
                        {
                            "system": "http://some-url",
                            "code": "phase1",
                            "display": "phase1"
                        },
                        {
                            "system": "http://some-url",
                            "code": "phase2",
                            "display": "phase2"
                        }
                    ]
                },
                "condition": [
                    {
                        "text": "Small carcinoma of lung"
                    }
                ],
                "keyword": [
                    {
                        "text": "NCT04625647"
                    }
                ]
            }
        },
        {
            "fullUrl": "urn:uuid:61ebe359-bfdc-4613-8bf2-c5e300945f0a",
            "request": {
                "method": "POST",
                "url": "ResearchSubject"
            },
            "resource": {
                "resourceType": "ResearchSubject",
                "identifier": [
                    {
                        "value": "ResearchStudy-NCT04625647"
                    }
                ],
                "status": "candidate",
                "period": {
                    "start": "2022-06-10"
                },
                "study": {
                    // Point # 1 
                    "reference": "urn:uuid:61ebe359-bfdc-6754-8bf2-c6e300945f0a",
                    "type" : "ResearchStudy"
                },
                "individual": {
                    "reference": "Patient/b1e9b0b9-da6e-4f68-b603-bd896a50ca86"
                }
            }
        }
    ]
}

Point #1 from the above JSON code. The “fullURL” property of the master and the detail as the study is the reference you need to create dynamically by setting the “urn:uuid:guid”.

Point #2 from the above JSON code is the request must be specified as the “POST query for both objects.

Conclusion

There may be many blog posts or articles on the bundle object but this post is to simplify one specific case I worked on. I hope it may be useful to you.

Posted in FHIR | Leave a comment

How to retrieve Response header values from the Custom Connector in PowerApps Canvas App?

Summary

For a project, I wrote a new Power Platform Custom Connector for an API call which returned the values in the response header. I wrote the connector with the response header values mapped but the Power Apps did not see those values. I always got the blank values in PowerApps. I used the Power Apps Monitor tool, and it showed the network Response did pass the header values on the Network.

After searching and asking experts I found that the Power Apps designer does not work to get the response headers. So I used the ScriptBase code for the connector to read the response header values and add to the response body with other response data.

NOTE: This post is an advanced-level step so please follow the following articles before you follow the tips from here.

Get started with custom connectors in Power Automate

Steps to resolve

Create the custom connector with the above steps or get any existing custom connector for which you need to read the response header.

To get familiar with writing the ScriptBase code follow this article. Once you have done all of the above steps you can copy the code from below in the ScriptBase.

    public class Script : ScriptBase
    {
        public override async Task<HttpResponseMessage> ExecuteAsync()
        {
            if (this.Context.OperationId == "TM_CreateJob" ||
                this.Context.OperationId == "OP_CreateJob")
            {
                // forward the request
                HttpResponseMessage response = await this.Context.SendAsync(this.Context.Request, this.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
                // get the response
                var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                // parse the response to Jobject
                // create new body
                var headers = response.Headers;
                if (response.IsSuccessStatusCode)
                {
                    var xPag = "Not Found";
                    if (headers.Contains("Operation-Location"))
                    {
                        var xHeader = headers.GetValues("Operation-Location").FirstOrDefault();
                        xPag = xHeader.ToString();
                    }
                    var _newBody = new JObject
                    {
                        ["jobId"] = xPag

                    };
                    response.Content = CreateJsonContent(_newBody.ToString());
                }
                return response;
            }
            else
            {
                var response = await this.Context.SendAsync(this.Context.Request, this.CancellationToken).ConfigureAwait(false);
                return response;
            }
        } // End of ExecuteAsync
    } // end of class Script

Conclusion

I hope this code is useful to you. I have found some of the following articles useful.

Create custom connector for own APIhttps://benediktbergmann.eu/2021/12/30/create-custom-connector-for-own-api/
Make Your First Custom Connector For Power Automate And Power Appshttps://www.matthewdevaney.com/make-your-first-custom-connector-for-power-automate-and-power-apps/
Custom Connector + Custom Headers? – Power CAT Livehttps://www.youtube.com/watch?v=oVR3dFpepYc
Transform A Custom Connector Response With C# Codehttps://www.matthewdevaney.com/transform-a-custom-connector-response-with-c-code/
Posted in Power Apps, Power Automate | Leave a comment