I'm working on an Actions on Google smart home device.
I'm using a service account key with the "Service Account Token Creator" role, getting a token with the official NuGet package.
This is the code I've got to create the token for the request. It's the same code for both the Report State call and Request Sync.
var oauth = global::Google.Apis.Auth.OAuth2.GoogleCredential.FromJson(jsonContent).CreateScoped("https://www.googleapis.com/auth/homegraph");
System.Diagnostics.Trace.WriteLine(".. Awaiting token");
string token = await oauth.UnderlyingCredential.GetAccessTokenForRequestAsync();
The call to the Report State API is working fine, and I can see the homegraph data updating using the Smart Home Dashboard, but I'm getting a 403 "The caller does not have permission" when trying to use it with the Request Sync API.
I'm sure I've followed the instructions at https://developers.google.com/assistant/smarthome/develop/request-sync#http-post correctly but I'm at a loss as to why this isn't working as expected.
I have read that if the actual SYNC request fails, the RequestSync will fail the same way - that is, the 403 could be actually coming from my fulfillment endpoint, however, if that were the case I should also be seeing that request in my logs, so it looks like it's not generating a SYNC request.
Also, I don't have the logs, but when I first set this up it was actually returning a success response. The problem at that time was that despite getting a success code from the homegraph, the test suite was still failing.
The rest of the code is as follows
using Google.Apis.Auth.OAuth2;
using Google.Apis.HomeGraphService.v1;
using Google.Apis.HomeGraphService.v1.Data;
var homeGraphServiceService = new HomeGraphServiceService();
var devicesResource = new DevicesResource(homeGraphServiceService);
var i = 1;
foreach (var key in keys)
{
System.Diagnostics.Trace.WriteLine(".. Building request for key " + i + " of " + keys.Length);
i++;
var requestSync = devicesResource.RequestSync(
new RequestSyncDevicesRequest
{
AgentUserId = key
});
requestSync.AccessToken = token;
try
{
System.Diagnostics.Trace.WriteLine(".. Sending request");
var _ = await requestSync.ExecuteAsync();
}
catch (GoogleApiException e)
{
System.Diagnostics.Trace.WriteLine(".. .. Request Sync returned error code: " + e.HttpStatusCode + "\n" + e.Message + "\n\n");
}
}
I also left a comment on an IssueTracker issue I found, but I'm not sure if I should be holding my breath on that one.