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:
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:
- PVA Dataverse Tables
- Update Field/Key for Trigger phrases
- 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 |
2. Update Field/Key for Trigger phrases
So our steps after approval are:
- Get Row
- Update Content
- Update Row
Not too difficult
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"
}
]
}
"triggerQueries": [
"pay slip",
"wage slip",
"wage query",
"wage",
"pay",
"pay slip",
"pay query",
"pay issues"
],
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": ['
)
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]
)
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.
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
- 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.
- Hopefully someone smarter then me can figure it out and get it working
- Its Ok to fail, as the learning is journey is just as valuable as an end solution
- Dataverse for Teams is terrible 😎
ABOUT THE AUTHOR
Lead Power Platform Developer with side hustle in Blue Prism. Passion for RPA and all things LowCode, back story in shadow IT with Excel/VBA/SharePoint and whatever I could get my hands on
REFERENCES
Wyatt, D., (2023), ‘DYNAMICALLY UPDATING Copilot Studio’, available at: https://dev.to/wyattdave/dynamically-updating-power-virtual-agents-26ia [accessed 28th March 2024].