DialogFlow / Actions: permite que o usuário do Google Assistant crie um evento no Google Calendar a partir do aplicativo Actions
Objetivo / Resumo: Tenho um aplicativo de ações desenvolvido no Google DialogFlow e desejo que o usuário possa criar um evento do Google Agenda usando o aplicativo (do Assistente do Google). Em outras palavras, autentique o usuário para permitirmeu aplicativo para usardele Calendário para criar eventos.
O que é feito:
Como o Google Actions não permite o uso de pontos de extremidade de autenticação / token do Google, optei por usarhttp://www.auth0.com.Criou uma conta (usou minha conta do Google) emauth0.com, criou um aplicativo e configurou os seguintes valores usando seu painel de gerenciamento (Domínio, CliendId eClientSecret gerado por auth0):ID do cliente OAuth criado na página Credenciais do Google Cloud Console:Ações configuradas Vinculação de conta da seguinte forma:Voltei para auth0.com> Conexões> Social> Google ativado:Verificado o "Login necessário" em DialogFlow> Integrações> Assistente do Google:Escreveu o log na primeira linha do meu método DialogFlow Webhook para registrar a seguinte resposta:
{
"originalRequest":{
"source":"google",
"version":"2",
"data":{
"isInSandbox":true,
"surface":{
"capabilities":[
{
"name":"actions.capability.AUDIO_OUTPUT"
},
{
"name":"actions.capability.WEB_BROWSER"
},
{
"name":"actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name":"actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs":[
{
"rawInputs":[
{
"query":"test",
"inputType":"KEYBOARD"
}
],
"arguments":[
{
"rawText":"test",
"textValue":"test",
"name":"text"
}
],
"intent":"actions.intent.TEXT"
}
],
"user":{
"lastSeen":"2018-05-03T11:40:57Z",
"accessToken":"4CfRs-Lt5lWVQuyOYODvf1xxxxxxx",
"locale":"en-US",
"userId":"15229245xxxxx"
},
"conversation":{
"conversationId":"15253476xxxxx",
"type":"ACTIVE",
"conversationToken":"[\"authentication\",\"wh_patient-details\"]"
},
"availableSurfaces":[
{
"capabilities":[
{
"name":"actions.capability.AUDIO_OUTPUT"
},
{
"name":"actions.capability.SCREEN_OUTPUT"
}
]
}
]
}
},
"id":"1d6ed865-0803-49ca-bbac-xxxx",
"timestamp":"2018-05-03T11:42:22.835Z",
"lang":"en-us",
"result":{
"source":"agent",
"resolvedQuery":"test",
"speech":"",
"action":"v00.xxxxx",
"actionIncomplete":false,
"parameters":{
"CallEnum":"Test"
},
"contexts":[
{
"name":"authentication",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":1
},
{
"name":"actions_capability_screen_output",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":0
},
{
"name":"actions_capability_audio_output",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":0
},
{
"name":"wh_patient-details",
"parameters":{
"patientId":0,
"CallEnum":"Test",
"fallbackLifespan":0,
"providerId":0,
"practiceId":0,
"CallEnum.original":"",
"fullDob":"01 January, 0001"
},
"lifespan":199
},
{
"name":"google_assistant_input_type_keyboard",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":0
},
{
"name":"actions_capability_web_browser",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":0
},
{
"name":"actions_capability_media_response_audio",
"parameters":{
"CallEnum":"Test",
"CallEnum.original":""
},
"lifespan":0
}
],
"metadata":{
"intentName":"v00xxxx",
"isResponseToSlotfilling":false,
"intentId":"c7bd9113-d5b4-4312-8851-xxxxxxx",
"webhookUsed":"true",
"webhookForSlotFillingUsed":"false",
"nluResponseTime":556
},
"fulfillment":{
"speech":"Test",
"messages":[
{
"type":0,
"speech":"Test"
}
]
},
"score":0.8399999737739563
},
"status":{
"code":200,
"errorType":"success"
},
"sessionId":"152534xxxxxxx",
"isStackdriverLoggingEnabled":false
}
onde a seção relevante é:
"user":{
"lastSeen":"2018-05-03T11:40:57Z",
"accessToken":"4CfRs-Lt5lWVQuyOYODvf1xxxxxxx",
"locale":"en-US",
"userId":"15229245xxxxx"
}
A partir deste post:Ver resposta de @PrisonerO token de autenticação (que você emitiu porque é o servidor OAuth) será enviado no objeto JSON em originalRequest.data.user.accessToken.
Então, usei o token de autorização de cima no código abaixo:
string clientId = "361385932727-ksg6jgjxxxxxSNIP";
string clientSecret = "rc2K1UUyntxxxxxxSNIP";
string accessToken = jsonObject.SelectToken("originalRequest.data.user.accessToken");
string userId = jsonObject.SelectToken("originalRequest.data.user.userId");
IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = clientId,
ClientSecret = clientSecret
},
Scopes = new[] { CalendarService.Scope.Calendar }
});
TokenResponse token = flow.ExchangeCodeForTokenAsync(userId, accessToken,
"https://oauth-redirect.googleusercontent.com/r/xxxxxxxxx", CancellationToken.None).Result;
UserCredential credential = new UserCredential(flow, userId, new TokenResponse { AccessToken = token.AccessToken });
CalendarService service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Test Auth0",
});
var list = service.CalendarList.List().Execute().Items;
E a exceção:
Error:"invalid_grant", Description:"Malformed auth code.", Uri:""
Stacktrace: at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<ExchangeCodeForTokenAsync>d__30.MoveNext()
E quando altero o ClientId / ClientSecret no código acima para o de auth0.com, a exceção é:
Error:"invalid_client", Description:"The OAuth client was not found.", Uri:""
Stacktrace: at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<FetchTokenAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.<ExchangeCodeForTokenAsync>d__30.MoveNext()
O que estou perdendo aqui? Alguém pode ajudar.