DEV Community

Cover image for Dynamically Updating Power Virtual Agents
david wyatt
david wyatt

Posted on

Dynamically Updating Power Virtual Agents

This blog did not go to plan, I hate Teams Dataverse, it's a bad idea and badly implemented, but lets start at the beginning...

So I had this idea, wouldn't it be cool if I could dynamically update the trigger phrases in my chatbot, it would go something like this:

bot flow

As everything is built in Dataverse my thought was I just need to update the topic row in the relevant table. I had the following challenges/learning opportunities:

  1. PVA Dataverse Tables
  2. Update Field/Key for Trigger phrases
  3. Find Topic

Quick call out, in case you haven't guessed this in Teams Dataverse, not full PVA, the licence costs are just too much for the full version for internal bots.


1. PVA Dataverse Tables

So after digging I found:

  • Chatbot - All bots
  • BotContent - No idea, it was always empty 🤷‍♂️
  • Chatbot Subcomponents - Topics & Entity
  • Entity - Default Entities
  • Conversationtran Script - Chat transcripts

So our 2 key tables are Chatbot and Chatbot subcomponets. Looking at the schema there are some fields that leap out as important:

Chatbot Table

Field Description
botid GUID for bot
name Bot name
solutionid GUID for solution
statecode Active(0)/Inactive(1)
bot_conversationtranscript GUID for bot transcript

Chatbot Subcomponents Table

Field Description
botcomponentid GUID for bot component
name Topic/Entity name
solutionid GUID for solution
statecode Active(0)/Inactive(1)
_parentbotid_value GUID for bot
content JSON definition

table relationship

2. Update Field/Key for Trigger phrases

So our steps after approval are:

  • Get Row
  • Update Content
  • Update Row

Not too difficult

flow update dataverse

For now we are just getting the topic we want and then adding a new trigger phrase.

The List rows subcomponents returns the below in the content:

{
  "intents": [
    {
      "triggerQueries": [
        "pay slip",
        "wage slip",
        "wage query",
        "wage",
        "pay",
        "pay slip",
        "pay query",
        "pay issues"
      ],
      "dialogId": "new_topic_789932f9a00999999999",
      "isTriggeringEnabled": true,
      "id": "new_topic_789932f9a0099999999993",
      "displayName": "Pay",
      "createdTime": "2022-07-26T10:17:16.4022364Z",
      "updatedTime": "2022-07-26T12:38:17.765303Z",
      "createdUserId": "999999999-feab-4bff-bc87-999999999",
      "updatedUserId": "999999999-feab-4bff-bc87-999999999"
    }
  ],
  "dialogs": [
    {
      "rootNodeId": "999999999-e047-418b-9735-999999999",
      "messageNodes": [
        {
          "botMessageId": "999999999-ee98-4bfe-9cfb-999999999",
          "nodeType": "BotMessageNode",
          "id": "999999999-e047-418b-9735-999999999",
          "defaultTargetNodeId": "999999999-3819-4a1e-a091-999999999"
        }
      ],
      "dialogChangeNodes": [
        {
          "targetDialogId": "new_topic_2dedddf95d7c4999999999991_aeabea4d071f419999999995424_assumedsuccess",
          "nodeType": "DialogChangeNode",
          "id": "999999999-3819-4a1e-a091-999999999"
        }
      ],
      "id": "new_topic_789932f9a009406999999999",
      "displayName": "Untitled",
      "createdTime": "2022-07-26T10:17:16.4022364Z",
      "updatedTime": "2022-07-26T12:38:17.765303Z",
      "createdUserId": "999999999-feab-4bff-bc87-999999999",
      "updatedUserId": "999999999-feab-4bff-bc87-999999999"
    }
  ],
  "botMessages": [
    {
      "channelContent": {
        "web": {
          "contentFormat": "Markdown",
          "content": "This is a test"
        }
      },
      "id": "999999999-ee98-4bfe-9cfb-999999999",
      "createdTime": "2022-07-26T10:14:26.556Z",
      "updatedTime": "2022-07-26T10:14:26.556Z"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

We want to add an item in this array:

"triggerQueries": [
        "pay slip",
        "wage slip",
        "wage query",
        "wage",
        "pay",
        "pay slip",
        "pay query",
        "pay issues"
      ],
Enter fullscreen mode Exit fullscreen mode

But as its a string we just need to do a fancy split concat expressions:

First we split into an array at the top of the triggerQueries array:

split(
    outputs('List_rows_subcomponents')?['body/value'][0]?['content']
,
    '"triggerQueries": ['
)
Enter fullscreen mode Exit fullscreen mode

Then we concat together with the first item, the split string and open speech marks, new phrase, close speech marks and comma, second item in the array:

concat(
    outputs('split_json')[0]
,
    '"triggerQueries": ["'
,
    triggerBody()['text']
,
    '",'
,
    outputs('split_json')[1]
)
Enter fullscreen mode Exit fullscreen mode

update a row

3. Find Topic

Cool so we can update our Topic, all we need to do now is find the right Topic (as every bot can have and often does have same named Topics).

This is where the _parentbotid_value key comes in as it will be the bots id, so we can have the bot as an environment variable, and filter the subcomponents _parentbotid_value by that id. Simple right, well no becuase the _parentbotid_value is null.

subcomponent response

It clearly shouldnt be because it needs the relationship for the Chatbot to work, and the documentation shows that. So whats the issue, well at a guess I don't have access somewhere, and this is where the really annoying part of Dataverse for Teams shows its head. I have full global power platform access and admin to the Team/Environemnt, but I can't use the Dataverse API to query it. I cant set security roles for tables, I can't do anything.

As a whole this gaping hole in seeing what is going on in the Teams Dataverse environments is so frustrating, and definitely not enterprise friendly.


So what's the point of this article, well

  1. Hopefully some learnings from how everything in Power Platform is now built in Dataverse, and you can do some cool stuff editing the Tables directly.
  2. Hopefully someone smarter then me can figure it out and get it working
  3. Its Ok to fail, as the learning is journey is just as valuable as an end solution
  4. Dataverse for Teams is terrible 😎

Further Reading

Top comments (5)

Collapse
 
jaloplo profile image
Jaime López

I like the way you work, you propose an application to learn the tech behind. It's a marvelloues way to understand how things works and the limits and boundaries of it.

Apart from this, did you try to reach the community to see if there is any possibility to solve the issues you found? DM me and I can give you some links.

Collapse
 
wyattdave profile image
david wyatt

Thank you for kind words, to be honest was more a learning experience then a needed solution, though would be cool to find out how to fix it

Collapse
 
jakemannion profile image
Jake Mannion

I like your idea. That's a good one.

Can you pull the chatbot into a solution... or is that not possible in a Teams dataverse environment? Might unlock a mystery or two if you can gather up all the tables and entities into one container.

Collapse
 
wyattdave profile image
david wyatt

Yep you can pull it into a solution, it normally adds an abstract layer (e.g shows as Topic instead of Dataverse row). But it is definitely worth investigating as adding to the solution pulls in the right components, so might help explain how it identifies those components. Thank you for the inspiration

Collapse
 
jakemannion profile image
Jake Mannion

Right back atcha