New command: `m365 pp chatbot list`
Usage
m365 pp chatbot list
Description
Lists Microsoft Power Platform chatbots
Options
| Option | Description |
|---|---|
-e, --environment <environment> |
The name of the environment for which to retrieve available chatbots |
Examples
Retrieves all chatbots for the default environment
m365 pp chatbot list -e "Default-2ca3eaa5-140f-4175-8261-3272edf9f339"
Additional Info
We should spend a few minutes to check if this is possible; the PowerShell cmdlets are not supporting this and there is no documentation, but I do see URL's with: /providers/microsoft.powerapps/apis/shared_bot for chatbots linked to apps and in the PVA webinterface https://powervamg.eu-il107.gateway.prod.island.powerapps.com/api/botmanagement/v1/environments/envName/bots is called, a URL we can retrieve from the runtime endpoints the same way we retrieve the https://europe.api.bap.microsoft.com URL.
Add private channel to the specified Microsoft Teams team with owner UPN
What's that second example doing there?
That should totally be deleted! (and is done so ;))
Did you already get this working using our fabulous m365 request command? 😉
@martinlingstuyl no :( looks like we are missing either a scope on our app reg or it is not being passed on correctly ;-). But havent spend more time than just pasting in the URL to see what happens, will see if we can get a token for this endpoint with the current app reg.

@appieschot, this is one of those endpoints where the URL does not equal the resource that is registered in Azure AD. You might want to try specifying the --resource option. I'm not sure which resource you need though. Maybe https://management.azure.com works, or https://api.powerapps.com or https://api.bap.microsoft.com.
aka:
m365 request --url "url" --resource "https://management.azure.com"
I don't know if the endpoint is called from the UI using a bearer token? Probably not, but if so, you could decode it to see what the token audience is.
@martinlingstuyl decoding is next on the list, wanted to push #3655 first 😂
Hmm, not a resource we can use or so it seems. The UI uses the following ID for the token 96ff4394-9197-43aa-b393-6a41652e21f8 (Dynamics 365 AI for Customer Service Bot).. Will investigate if we have other API's we can use!
Long story short I do not think we can get this to work. In the Power Platform UI they use GraphQL to get the chatbots from an API (with random graphql prefix that is put to the window._makerConfig, so that is a no go for us.
The https://powervamg.eu-il107.gateway.prod.island.powerapps.com/api/botmanagement/ andpoint can be used, but does require us to have access to the Dynamics 365 AI for Customer Service Bot with id 96ff4394-9197-43aa-b393-6a41652e21f8 living in tenant f8cdef31-a31e-4b4a-93e4-5f571e91255a and I have the feeling they will not allow CLI to be connected to that app 😉.
Leaves us with a single implementation option and that is to read the Chatbot dataverse table: https://www.expiscornovus.com/2021/09/08/list-all-power-virtual-agents/
If we implement #3653 we can spec a m365 pp dataverse table row list or m365 pp dataverse row list command to list all rows in a specified table. That one can then be used to build this command I would say. I'll put this one on hold untill we have dataverse one in specced and in place.
So is the skinny that we should close this issue because right now, there's no way for us to implement it?
@waldekmastykarz happy to close the command, but as soon as we have #3653 implemented we could use that command to retrieve the required values and provide this command for ppl who are not aware on how to get values from dataverse :)
Let me see if I understand it correctly: while there's no API that we can use, we can grab the list of chatbots from Dataverse, is that correct @appieschot?
That is correct; there is a fixed dataverse table present if you create chatbots and they hold the references and names to those chatbots
@appieschot I'm removing the on hold label because the blocking issue has been implemented 🚀
Wellll.... We can't get table rows yet but well get there soon enough 🦾
Hi All,
There is also an api for this: dynamicsApiUrl/api/data/v9.0/bots to which you can give a fetchXml parameter for more specific info from the bot
Greets
That's great news, If I understand correct we can use that API to retrieve bots and include a --details if we need more details?
That's great news, If I understand correct we can use that API to retrieve bots and include a
--detailsif we need more details?
Maybe we should include the details response with the fetchXml standard, because a call without the fetchXml doesn't say much.
For example, the response from the call dynamicsApiUrl/api/data/v9.0/bots without fetchXml parameter returns:
{
"value": [
{
"@odata.etag": "W/\"1411208\"",
"authenticationtrigger": 0,
"_owningbusinessunit_value": "6da087c1-1c4d-ed11-bba1-000d3a2caf7f",
"statuscode": 1,
"createdon": "2022-11-13T19:11:35Z",
"statecode": 0,
"schemaname": "new_bot_9be05428a2794aa3ae548449c2cc2722",
"_ownerid_value": "5fa787c1-1c4d-ed11-bba1-000d3a2caf7f",
"overwritetime": "1900-01-01T00:00:00Z",
"name": "test",
"solutionid": "fd140aae-4df4-11dd-bd17-0019b9312238",
"ismanaged": false,
"versionnumber": 1411208,
"language": 1033,
"_modifiedby_value": "5f91d7a7-5f46-494a-80fa-5c18b0221351",
"_modifiedonbehalfby_value": "5fa787c1-1c4d-ed11-bba1-000d3a2caf7f",
"modifiedon": "2022-11-13T19:11:37Z",
"componentstate": 0,
"botid": "9be05428-a279-4aa3-ae54-8449c2cc2722",
"_createdby_value": "5fa787c1-1c4d-ed11-bba1-000d3a2caf7f",
"componentidunique": "468e0999-568f-4f68-b345-34bf0eb2f5b7",
"authenticationmode": 1,
"_owninguser_value": "5fa787c1-1c4d-ed11-bba1-000d3a2caf7f",
"accesscontrolpolicy": 0,
"runtimeprovider": 0,
"_publishedby_value": null,
"authenticationconfiguration": null,
"authorizedsecuritygroupids": null,
"overriddencreatedon": null,
"applicationmanifestinformation": null,
"importsequencenumber": null,
"synchronizationstatus": null,
"template": null,
"_providerconnectionreferenceid_value": null,
"configuration": null,
"utcconversiontimezonecode": null,
"publishedon": null,
"_createdonbehalfby_value": null,
"iconbase64": null,
"supportedlanguages": null,
"_owningteam_value": null,
"timezoneruleversionnumber": null,
"iscustomizable": {
"Value": true,
"CanBeChanged": true,
"ManagedPropertyLogicalName": "iscustomizableanddeletable"
}
}
]
}
but the response from the call dynamicsApiUrl/api/data/v9.0/bots with fetchXml parameter returns:
{
"value": [
{
"@odata.etag": "W/\"versionnumber\"",
"botid": "9be05428-a279-4aa3-ae54-8449c2cc2722",
"language": 1033,
"overwriteTime": "1900-01-01T00:00:00Z",
"botModifiedOn": "2022-11-13T19:11:37Z",
"displayName": "test",
"schemaName": "new_bot_9be05428a2794aa3ae548449c2cc2722",
"solutionId": "fd140aae-4df4-11dd-bd17-0019b9312238",
"componentIdUnique": "468e0999-568f-4f68-b345-34bf0eb2f5b7",
"stateCode": 0,
"statusCode": 1,
"isManaged": false,
"accessControlPolicy": 0,
"botModifiedBy": "SYSTEM",
"ownerId": "5fa787c1-1c4d-ed11-bba1-000d3a2caf7f",
"componentState": 0,
"authenticationMode": 1,
"versionNumber": 1411208,
"owner": "De Cleyre, Nico",
"createdOn": "2022-11-13T19:11:35Z",
"authenticationTrigger": 0,
"cdsBotId": "9be05428-a279-4aa3-ae54-8449c2cc2722"
}
]
}
where the fetchXml parameter is the following xml:
<fetch mapping='logical' version='1.0' >
<entity name='bot'>
<attribute name='accesscontrolpolicy' alias='accessControlPolicy' />,<attribute name='applicationmanifestinformation' alias='applicationManifestInformation' />,<attribute name='authenticationmode' alias='authenticationMode' />,<attribute name='authenticationtrigger' alias='authenticationTrigger' />,<attribute name='authorizedsecuritygroupids' alias='authorizedSecurityGroupIds' />,<attribute name='componentidunique' alias='componentIdUnique' />,<attribute name='componentstate' alias='componentState' />,<attribute name='configuration' alias='configuration' />,<attribute name='createdon' alias='createdOn' />,<attribute name='importsequencenumber' alias='importSequenceNumber' />,<attribute name='ismanaged' alias='isManaged' />,<attribute name='language' alias='language' />,<attribute name='modifiedon' alias='botModifiedOn' />,<attribute name='overriddencreatedon' alias='overriddenCreatedOn' />,<attribute name='overwritetime' alias='overwriteTime' />,<attribute name='iconbase64' alias='iconBase64' />,<attribute name='publishedon' alias='publishedOn' />,<attribute name='schemaname' alias='schemaName' />,<attribute name='solutionid' alias='solutionId' />,<attribute name='statecode' alias='stateCode' />,<attribute name='statuscode' alias='statusCode' />,<attribute name='timezoneruleversionnumber' alias='timezoneRuleVersionNumber' />,<attribute name='utcconversiontimezonecode' alias='utcConversionTimezoneCode' />,<attribute name='versionnumber' alias='versionNumber' />,<attribute name='name' alias='displayName' />,<attribute name='botid' alias='cdsBotId' />,<attribute name='ownerid' alias='ownerId' />,<attribute name='synchronizationstatus' alias='synchronizationStatus' />
<link-entity name='systemuser' to='ownerid' from='systemuserid' link-type='inner' >
<attribute name='fullname' alias='owner' />
</link-entity>
<link-entity name='systemuser' to='modifiedby' from='systemuserid' link-type='inner' >
<attribute name='fullname' alias='botModifiedBy' />
</link-entity>
</entity>
</fetch>
my opinion: we should always log the response from the api with the fetchXml parameter
Totally agree! So oppened up
Can i work on this one?