web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Copilot Studio / Calling the Graph API ...
Copilot Studio
Answered

Calling the Graph API to do a document search in PVA

(3) ShareShare
ReportReport
Posted on by

In the below example, I'm going to show how to do a document search on documents stored in a specific SharePoint site, from a Power Virtual Agents chatbot, using Power Automate and the Microsoft Graph API.

 

Here's the end result (using the new native chatbot component in Power Apps 😞

 

HenryJammes_0-1680916387986.png

 

I have the same question (0)
  • Verified answer
    HenryJammes Profile Picture
    on at

    Before starting, I suggest you start playing with the Microsoft Graph Explorer,  especially with the "search driveitems" query:

     

    HenryJammes_1-1680913922706.png

     

    You also might need an Azure Active Directory admin to create an application with the appropriate Graph API permissions. If not, in Power Automate, try the "HTTP with Azure AD" connector and the "Invoke an HTTP request" action (with "https://graph.microsoft.com" for both fields, the base resource URL and the resource URI).

     

    OK, to get my bot to search documents for me, I start on the Power Virtual Agents side:

    1. I create a new topic, called "Document Search", and I define trigger phrases for it.
    2. I then ask the question "I understand you're looking for documents. Please provide me with a few keywords to help with the search."
    3. I capture the "User's entire response" as a "Keywords" variable. 
    4.  Then I add a new node and select "Call an action" and choose "Create a flow".

    HenryJammes_0-1680913500078.png

     

    In Power Automate:

    1. I add as a text input "Keywords"
    2. I initiatize a string variable, called "ResultSet"
    3. I initialize a string variable called "SiteId", and give it the value of my SharePoint siteId (you can get the right siteId from the Microsoft Graph Explorer,  using the "search driveitems" query).
    4. I initialize an integer variable, called "NumberOfResults"

    HenryJammes_2-1680914110213.png

     

    I give my cloud flow a name, and I save.

     

    In this example, I'll run the queries against the Graph API with an application (if you don't/can't have one, try the HTTP with Azure AD instead of HTTP pproach in Power Automate, as recommended in the introduction

     

    In Azure Active Directory:

    1. Go to "App registrations"
    2. Click on "New registration"
    3. Give it a name and click on "Register"
    4. Copy the "Application (client) ID" and the "Directory (tenant) ID" somewhere for later.
    5. Go to "Certificates and secrets"
    6. Create a "New client secret"
    7. Copy the secret value (not the Secret ID!) somewhere, for later
    8. In "API Permissions", select "Add a Permission"
    9. Choose "Microsoft Graph", then "Application permissions", and select "Files.Read.All", and "Sites.Read.All".
    10. You can then "Grant admin consent" (this requires admin permissions)

    HenryJammes_3-1680914919664.png

     

    Back in Power Automate:

    1. Add an "HTTP" action from the "HTTP" connector"
    2. Method: "POST"
    3. URI: "https://graph.microsoft.com/v1.0/search/query"
    4. Hearders, "Content-Type" "application/json"
    5. In Body:
    {
    "requests": [
    {
    "entityTypes": [
    "driveItem"
    ],
    "query": {
    "queryString": "@{triggerBody()['text']}"
    },
    "region": "US"
    }
    ]
    }

    EDIT: in a below comment I also show how to filter by file type or SharePoint path to limit results.

    Don't forget to add and adjust the region, as you will get this error otherwise, when trying to call the Graph API from an application:

    SearchRequest Invalid (Region is required when request with application permission.)
    Region is required when request with application permission.

    You need to show the advanced option to then set authentication:

    1. Authentication: "Azure Directory OAuth".
    2. Tenant: the  "Directory (tenant) ID" you copied from the application.
    3. Audience: "https://graph.microsoft.com".
    4. Client ID: the "Application (client) ID" you copied from the application.
    5. Credential Type: "Secret".
    6. Secret: the secret value (not the Secret ID!) you copied from the application.

     

    HenryJammes_7-1680915719226.png

     

    Again, if you want to use your user account, you can use a similar query done with the "HTTP with Azure AD" connector and the "Invoke an HTTP request" action.

     

    The next step is to parse the JSON answer.

    You can generate the Schema from a sample, or paste the below:

    {
        "type""object",
        "properties": {
            "value": {
                "type""array",
                "items": {
                    "type""object",
                    "properties": {
                        "searchTerms": {
                            "type""array",
                            "items": {
                                "type""string"
                            }
                        },
                        "hitsContainers": {
                            "type""array",
                            "items": {
                                "type""object",
                                "properties": {
                                    "hits": {
                                        "type""array",
                                        "items": {
                                            "type""object",
                                            "properties": {
                                                "hitId": {
                                                    "type""string"
                                                },
                                                "rank": {
                                                    "type""integer"
                                               },
                                                "summary": {
                                                    "type""string"
                                                },
                                                "resource": {
                                                    "type""object",
                                                    "properties": {
                                                        "@@odata.type": {
                                                            "type""string"
                                                        },
                                                        "size": {
                                                            "type""integer"
                                                        },
                                                       "fileSystemInfo": {
                                                            "type""object",
                                                            "properties": {
                                                                "createdDateTime": {
                                                                    "type""string"
                                                                },
                                                                "lastModifiedDateTime": {
                                                                    "type""string"
                                                                }
                                                            }
                                                        },
                                                        "id": {
                                                            "type""string"
                                                        },
                                                        "createdBy": {
                                                            "type""object",
                                                            "properties": {
                                                                "user": {
                                                                    "type""object",
                                                                    "properties": {
                                                                        "displayName": {
                                                                            "type""string"
                                                                        },
                                                                        "email": {
                                                                            "type""string"
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "createdDateTime": {
                                                            "type""string"
                                                        },
                                                        "lastModifiedBy": {
                                                            "type""object",
                                                            "properties": {
                                                                "user": {
                                                                    "type""object",
                                                                    "properties": {
                                                                        "displayName": {
                                                                            "type""string"
                                                                        },
                                                                        "email": {
                                                                            "type""string"
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "lastModifiedDateTime": {
                                                            "type""string"
                                                        },
                                                        "name": {
                                                            "type""string"
                                                        },
                                                        "parentReference": {
                                                            "type""object",
                                                            "properties": {
                                                                "driveId": {
                                                                    "type""string"
                                                                },
                                                                "id": {
                                                                    "type""string"
                                                                },
                                                                "sharepointIds": {
                                                                    "type""object",
                                                                    "properties": {
                                                                        "listId": {
                                                                            "type""string"
                                                                        },
                                                                        "listItemId": {
                                                                            "type""string"
                                                                        },
                                                                        "listItemUniqueId": {
                                                                            "type""string"
                                                                        }
                                                                    }
                                                                },
                                                                "siteId": {
                                                                    "type""string"
                                                                }
                                                            }
                                                        },
                                                        "webUrl": {
                                                            "type""string"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "total": {
                                        "type""integer"
                                    },
                                    "moreResultsAvailable": {
                                        "type""boolean"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "@@odata.context": {
                "type""string"
            }
        }
    }

     

    HenryJammes_5-1680915396728.png

     

    Next, we add an "Apply to each" action, so that we can append our "ResultSet" variable with each matching document. We have to go a few levels done here.

    We also use an "Increment variable" action, to count the number of results we'll send back to PVA.

     

    We also add a "Condition" node, because we want to only return results to the user for a specific SharePoint site.

    EDIT: in a below comment I also show how to filter by file type or SharePoint path to limit results at the Graph API query level. A much more elegant solution than the condition in Power Automate.

     

    HenryJammes_8-1680915910180.png

     

    On the "Append to string variable" action, you can see I use an expression.
    This is to make sure the URL doesn't get messed up as spaces and such are not encoded from the Graph API results.

    replace(items('Apply_to_each:_hitContainer')?['resource']?['webUrl'], ' ', '%20')

    The last step is to return values to Power Virtual Agents.

    Here I send back 2 variables:

    1. SearchResults: with the "ResultSet" variable
    2. NumberOfResults, with the "NumberOfResults" variable

    HenryJammes_9-1680916162932.png

    I save the Power Automate cloud flow.

     

    Back in PVA:

    1. I add the "Call an action" node and select my new flow.
    2. I map the appropriate variables to pass the keywords.
    3. After the flow, I add a "Send a message" node
    4. I use the cloud flow outputs to send the results to the user.

    HenryJammes_10-1680916332278.png

     

    Voilà

  • HenryJammes Profile Picture
    on at

    Thanks to my amazing colleague @RuiSantosNOR, I now know how to filter a Graph API driveitem search for a specific SharePoint library:

     

    {
     "requests": [
     {
     "entityTypes": [
     "driveItem"
     ],
     "query": {
     "queryString": "KEYWORDS filetype:pdf path:\"https://DOMAIN.sharepoint.com/sites/SITENAME/LIBRARY\""
     },
     "region": "US"
     }
     ]
    }
     
  • angerfire1213 Profile Picture
    90 on at

    How to use the method to prod Version PVA ? @HenryJammes 

  • HenryJammes Profile Picture
    on at

    Hi @angerfire1213, the approach should work very similarly whether you're on the production or unified canvas version of PVA. Most of the logic happens in Power Automate.

  • angerfire1213 Profile Picture
    90 on at

    @HenryJammes  Great!

    so is will also working on topic

    Use GPT/ChatGPT to summarize and reference the results from an internal document search

    right?

  • angerfire1213 Profile Picture
    90 on at

    @HenryJammes question:how to get the value in the step(cloud you give an screen shot ,thank you very much): I initialize a string variable called "SiteId", and give it the value of my SharePoint siteId (you can get the right siteId from the Microsoft Graph Explorer,  using the "search driveitems" query

  • HenryJammes Profile Picture
    on at

    @angerfire1213 wrote:

    @HenryJammes  Great!

    so is will also working on topic

    Use GPT/ChatGPT to summarize and reference the results from an internal document search

    right?


    Yes, correct

  • HenryJammes Profile Picture
    on at

    In the end I used a better approach: https://powerusers.microsoft.com/t5/Calling-Actions-from-PVA/Calling-the-Graph-API-to-do-a-document-search-in-PVA/m-p/2106450/highlight/true#M1080.

    Otherwise in the above experience I grabbed the siteId of the SharePoint site from the payload that was returned with the Graph Explorer (or a past Power Automate run).

     

     

  • angerfire1213 Profile Picture
    90 on at

    .......

     

  • angerfire1213 Profile Picture
    90 on at

    got it ,thank you Henry!

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Forum hierarchy changes are complete!

In our never-ending quest to improve we are simplifying the forum hierarchy…

Ajay Kumar Gannamaneni – Community Spotlight

We are honored to recognize Ajay Kumar Gannamaneni as our Community Spotlight for December…

Leaderboard > Copilot Studio

#1
Michael E. Gernaey Profile Picture

Michael E. Gernaey 251 Super User 2025 Season 2

#2
Romain The Low-Code Bearded Bear Profile Picture

Romain The Low-Code... 201 Super User 2025 Season 2

#3
S-Venkadesh Profile Picture

S-Venkadesh 93 Moderator

Last 30 days Overall leaderboard