June 22, 2023

Resolving Attachment Issues in Power Automate Approval Action - 'Start and Wait for an Approval': Step-by-Step Guide


Introduction: 

Recently, while working on a Power Automate Flow, we encountered a specific requirement involving the need to send attachments in an Approval action. To address this, we utilized the “Start and Wait for an approval” action. Within this action, we clicked on “Show advanced options” to configure the attachments field from the dynamic contents array variable that we had created for appending the attachment contents.




Here we passed the ApprovalAttachments array consisting of JSON objects with two properties “Name” and ContentBytes. 

 {   
  "Name": @{items('Apply_to_each_2')?['DisplayName']},   
  "ContentBytes": @{body('Get_attachment_content')}   
 }   




The flow was executed without any errors, and I received the expected emailHowever, the attached files were missing from the email.  


It became evident that the attachments were not being successfully included in the email.  Therefore, in this blog, we will thoroughly examine the procedure for sending multiple attachments using the “Start and Wait for an Approval action within Power Automate. Our focus will be on resolving the specific issue that arises when attempting to send attachments using this particular action. Let’s dive into the step-by-step process and find a solution to this problem! 


Solution: 

Step 1: Initialize the array variable. 




Step 2: "Get attachments" action in Power Automate returns all attachments for given item in the array.



 

Step 3: To read all the attachment contents, click on the next step and then select the "Get attachment content". 




Step 4: Proceed to the next step and select theAppend to array variableaction inside the apply to each loop. 

- Now select the variable ApprovalAttachment that you have previously created

- Configure the value using the following JSON structure: 

  • Name: Set the display name from the dynamic content. 

  • Content: Set the attachment content of the Get attachment contents from the dynamic content. 


   {   
               "Name": @{items('Apply_to_each_2')?['DisplayName']},   
               "Content": @{body('Get_attachment_content')}   
   }   

It is important to note that you should use the “Content” instead of “Content Bytes” to avoid any issue in sending attachments. Now you will get an email with attachments too. 



Step 5: In this final action, go to the advanced options and set the dynamic content from the approval attachments array. 


 

Conclusion: 

So, this is how we can easily send attachments without encountering any issues using the approval action. 


If you have any questions you can reach out our SharePoint Consulting team here.

June 1, 2023

Configuring a DNS Private Resolver for Seamless Azure Cosmos DB Connectivity with Point-to-Site VPN

Introduction

This article will guide you through the setup of a DNS private resolver for Azure Cosmos DB, addressing the challenge of connecting to the database from different virtual networks or through VPNs. By configuring a DNS private resolver, you can ensure seamless and secure connectivity to your Azure Cosmos DB, enabling efficient data access, data restrictions, and management.

Problem:

When you add a private endpoint to Azure Cosmos DB, your client may not be able to connect to the database while connected to a VPN because the IP address of the database is not resolvable. Even with DNS integration enabled, connecting to the database from a different virtual network or through a VPN requires a DNS forwarder or another method to resolve the Fully Qualified Domain Name (FQDN) of the database.

Services Overview:

  1. Azure Cosmos DB: A globally distributed, multi-model database service that offers consistent performance and availability. Azure Cosmos DB supports storing and querying data of any size and type, ranging from relational data to documents to JSON.
  2. DNS Private Resolver: A server that resolves DNS queries for private resources in your Virtual Network (VNet). Configuring a DNS private resolver allows your client to resolve the IP address of your Azure Cosmos DB database and connect to it securely.
  3. Private Endpoint: A network interface that facilitates private connections to Azure Cosmos DB from your VNet. When you create a private endpoint, Azure Cosmos DB generates a virtual network interface in your VNet that is connected to the Azure Cosmos DB service.
  4. Private DNS Zone: A DNS zone hosted within your virtual network, enabling you to control how DNS queries for your private resources are resolved. You can create records for your private resources, such as Azure Cosmos DB databases, allowing clients to resolve their IP addresses without accessing the public internet.
  5. Virtual Network (VNet): A logical isolation of your Azure resources, similar to a traditional network, but implemented in the cloud.

Diagram:




Solution:

To overcome the connectivity issue, you can configure a DNS private resolver. A DNS private resolver is a server that resolves DNS queries for private resources in your VNet, enabling your client to resolve the IP address of your Azure Cosmos DB database and connect to it securely.

Follow these steps to configure a DNS private resolver:

1. Go to the Azure portal and navigate to the DNS private resolvers blade.

2. Select Create DNS private resolver.

3. In the Create DNS private resolver blade, complete the following steps:

  • In the Name field, enter a name for your DNS private resolver.
  • In the Location field, select the location for your DNS private resolver.
  • In the Resource group field, select the resource group for your DNS private resolver.
  • Select the Subnet field and choose the subnet in your VNet where VPN is configured.
  • Select Create.

Configuring the Inbound endpoint:

1. In the Settings section of DNS private resolver, select Inbound endpoints.
2. In the Inbound endpoints blade, select Add inbound endpoint.
3. Add the inbound endpoint.

Note: Ensure that the subnet you choose for the Inbound endpoint is in the same VNet where the VPN is configured.

Configure DNS IP:

Once the Inbound endpoint is created, you will see an IP address assigned to it from the selected subnet range. Copy this IP address and go to your VNET where VPN is configured. From the left panel, select DNS servers and add this IP as a custom DNS IP.

After completing these steps, when you connect to the VPN, you should see the same IP address as the DNS IP address in the VPN settings. Now you should be able to connect to Azure Cosmos DB while connected to the Azure Point-to-Site VPN.

If you have any questions you can reach out our SharePoint Consulting team here.

April 27, 2023

How to trigger Power Automate from SPFx webpart and return result back to SPFx webpart?

Introduction:

In this blog, we will learn how we can trigger Power Automate from SPFx web part, fetch some data or perform any operation and return result back to SPFx web part.

Scenario:

We need to fetch data from API which was not accessible by SharePoint site due to CORS issue. So we created Power Automate which will triggered from SPFx web part, and this flow will fetch the data from API and return the result to SPFx web part.

Implementation:

Follow below steps to trigger Power Automate from SPFx web part and return result back to SPFx web part.

Step 1: First, we need to create Power Automate which will have trigger of When HTTP request is received.

Note: HTTP POST URL will be generated only when you Save the Power Automate.

Step 2: If we want to pass some data from SPFX web part to Power Automate, we need to specify JSON schema in Request Body JSON Schema. 
For example, we can use JSON Schema for Startdate and Enddate as below:
{
    "type": "object",
    "properties": {
        "Startdate": {
            "type": "string"
        },
        "Enddate": {
            "type": "string"
        }
    }
}

Step 3: Now, in Power Automate we need to action for Response at the end of the Power Automate which will return the response to SPFX web part.

Step 4: Now, you can save the flow and copy the HTTP POST URL from first action, which we will use this URL in SPFX web part.

Step 5: In a SPFX web part, first we need to import below namespaces.
import { HttpClient, HttpClientResponse, IHttpClientOptions} from '@microsoft/sp-http';

Step 6: Now, we will create a new method which will be called when we want to trigger Power Automate. So in that method, first we will create a body, which will pass data to Power Automate:

const body: string = JSON.stringify({
      'Startdate': '1-1-2023',
      'Enddate': 12-31-2023
 });

Step 7: Now, we will create header, which will be used when we trigger Power Automate:
const requestHeaders: Headers = new Headers();
requestHeaders.append('Content-type', 'application/json');

Step 8: As we will be using HTTP request, we need to use body and headers in HTTPClient Options:

const httpClientOptions: IHttpClientOptions = {
      body: body,
      headers: requestHeaders
};

Step 9: Now we will trigger the flow using HTTP request as shown in below code:

 return this.props.context.httpClient.post(
      postURL, //This will be the URL which is generated in Power Automate
      HttpClient.configurations.v1,
      httpClientOptions)
      .then((response: HttpClientResponse): Promise<HttpClientResponse> => {
        return response.json();
  });
Note: Before we write above code, we need to create new property for context and we need to assign below value:
context: this.context

Step 10: Here is the full code snippet of the method which will trigger Power Automate:
private getMetricsData(StartDate: string, EndDate: string): Promise<HttpClientResponse> {
    const postURL = ""; // This will be the URL which is generated from Power Automate

    const body: string = JSON.stringify({
      'Startdate': StartDate,
      'Enddate': EndDate
    });

    const requestHeaders: Headers = new Headers();
    requestHeaders.append('Content-type', 'application/json');

    const httpClientOptions: IHttpClientOptions = {
      body: body,
      headers: requestHeaders
    };

    return this.props.context.httpClient.post(
      postURL,
      HttpClient.configurations.v1,
      httpClientOptions)
      .then((response: HttpClientResponse): Promise<HttpClientResponse> => {
        return response.json();
      });
  }

Step 11: Now when we call the method, it will trigger the Power Automate and return the result to SPFX web part. 

Conclusion:

This is how we can trigger Power Automate from SPFX web part and return the result back to SPFX web part. Hope this blog will be helpful for you!

If you have any questions you can reach out our SharePoint Consulting team here.