An API that connects multiple Microsoft services, enabling data access and automation across platforms
Can't create graph account
I want to use the metered graph apis. To that effect I create a resource as per the documentation:
az graph-services account create --resource-group bot --resource-name bot-bill --subscription <my subscription id> --location global --app-id <Application (client) ID taken from entra>
This returns:
{
"id": "/subscriptions/<my subscription id>/resourceGroups/bot/providers/Microsoft.GraphServices/accounts/bot-bill",
"location": "global",
"name": "bot-bill",
"properties": {
"appId": "<my app id>",
"billingPlanId": "53cd401e-1a5f-xxxx-xxxx-0a0ec1b2e798",
"provisioningState": "Succeeded"
},
"resourceGroup": "bot",
"systemData": {
"createdAt": "2024-10-11T14:41:14.3095173Z",
"createdByType": "User",
"lastModifiedAt": "2024-10-11T14:41:14.3095173Z",
"lastModifiedByType": "User"
},
"type": "microsoft.graphservices/accounts"
}
Afterwards I run the following command to verify that everything is good:
root [ / ]# az resource list --resource-type Microsoft.GraphServices/accounts
[
{
"changedTime": "2024-10-11T14:41:19.637867+00:00",
"createdTime": "2024-10-11T14:41:14.221286+00:00",
"extendedLocation": null,
"id": "/subscriptions/<subscription id>/resourceGroups/bot/providers/Microsoft.GraphServices/accounts/bot-bill",
"identity": null,
"kind": null,
"location": "global",
"managedBy": null,
"name": "ntgr-bot-bill",
"plan": null,
"properties": null,
"provisioningState": "Succeeded",
"resourceGroup": "bot",
"sku": null,
"systemData": {
"createdAt": "2024-10-11T14:41:14.3095173Z",
"createdByType": "User",
"lastModifiedAt": "2024-10-11T14:41:14.3095173Z",
"lastModifiedByType": "User"
},
"tags": null,
"type": "Microsoft.GraphServices/accounts"
}
]
root [ / ]# az resource show -g ntgr-bot -n ntgr-bot-bill --resource-type Microsoft.GraphServices/accounts
{
"extendedLocation": null,
"id": "/subscriptions/<subscription id>/resourceGroups/bot/providers/Microsoft.GraphServices/accounts/bot-bill",
"identity": null,
"kind": null,
"location": "global",
"managedBy": null,
"name": "bot-bill",
"plan": null,
"properties": {
"appId": "<app id>",
"billingPlanId": "53cd401e-1a5f-48c9-a888-0a0ec1b2e798",
"provisioningState": "Succeeded"
},
"resourceGroup": "bot",
"sku": null,
"systemData": {
"createdAt": "2024-10-11T14:41:14.3095173Z",
"createdByType": "User",
"lastModifiedAt": "2024-10-11T14:41:14.3095173Z",
"lastModifiedByType": "User"
},
"tags": null,
"type": "microsoft.graphservices/accounts"
}
However, when I try to connect to msgraph and subscribe to users/{bot_user_id}/chats/getAllMessages?model=B I get the following error:
Error creating subscription:
APIError
Code: 402
message: None
error: MainError(additional_data={}, code='ExtensionError', details=None, inner_error=InnerError(additional_data={}, client_request_id='ccc5a76c-41c0-4652-b2a6-bd323e6e7216', date=DateTime(2024, 10, 11, 14, 43, 0, tzinfo=Timezone('UTC')), odata_type=None, request_id='b8c702aa-1ea2-4cc3-bf5c-7efc5f8052fa'), message='Operation: Create; Exception: [Status Code: PaymentRequired; Reason: To access this resource, the app must be associated with an Azure subscription, see https://aka.ms/teams-api-payment-requirements for details.]', target=None)
I'm using the python SDK to connect to msgraph with the following code:
credential = UsernamePasswordCredential(client_id=client_id, tenant_id=tenant_id, username=username, password=password)
client = GraphServiceClient(credential)
async def create_subscription_for_all_chats(client, user_id=None):
expiration_time = (datetime.utcnow() + timedelta(hours=1)).isoformat(timespec="seconds") + "Z"
bot_user_id = "7f5c5038-5909-4191-8589-3e8399877e3c"
# Create a subscription for all chats the user is involved in
subscription_body = Subscription(
change_type="created,updated", # Track both new messages and updates
notification_url=f"{PUBLIC_IP}/webhook-endpoint",
# Replace with your actual ngrok URL
lifecycle_notification_url=f"{PUBLIC_IP}/lifecycle",
resource=f"users/{bot_user_id}/chats/getAllMessages?model=B", # Subscribe to all messages across all chats
expiration_date_time=expiration_time, # Set expiration time
client_state="secretClientValue", # Optional client state for validation
latest_supported_tls_version="v1_2"
)
try:
subscription = await client.subscriptions.post(subscription_body)
print(f"Subscription created for all chats of the chatbot: {subscription.id}")
return subscription.id
except Exception as e:
print(f"Error creating subscription: {e}")
return None
I can successfully subscribe if I ommit the ?model=B parameter but in this case I don't receive any change notification if someone writes to the respective use. Any ideas what am I doing wrong?