gpt4 book ai didi

node.js - GoogleActions帐户尚未链接但出错

转载 作者:搜寻专家 更新时间:2023-10-31 23:36:58 25 4
gpt4 key购买 nike

我正在尝试在使用(DialogFlow或API.ai和google action)开发的nodejs Google助手应用上实现oauth2身份验证。

所以我遵循了这个answer。但是我总是收到“看来您的测试oauth帐户尚未链接。”错误。当我尝试打开调试选项卡上显示的URL时,它显示了500个损坏的URL错误。

对话流完成
index.js

'use strict';

const functions = require('firebase-functions'); // Cloud Functions for Firebase library
const DialogflowApp = require('actions-on-google').DialogflowApp; // Google Assistant helper library

const googleAssistantRequest = 'google'; // Constant to identify Google Assistant requests

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));

// An action is a string used to identify what needs to be done in fulfillment
let action = request.body.result.action; // https://dialogflow.com/docs/actions-and-parameters

// Parameters are any entites that Dialogflow has extracted from the request.
const parameters = request.body.result.parameters; // https://dialogflow.com/docs/actions-and-parameters

// Contexts are objects used to track and store conversation state
const inputContexts = request.body.result.contexts; // https://dialogflow.com/docs/contexts

// Get the request source (Google Assistant, Slack, API, etc) and initialize DialogflowApp
const requestSource = (request.body.originalRequest) ? request.body.originalRequest.source : undefined;
const app = new DialogflowApp({request: request, response: response});

// Create handlers for Dialogflow actions as well as a 'default' handler
const actionHandlers = {
// The default welcome intent has been matched, welcome the user (https://dialogflow.com/docs/events#default_welcome_intent)
'input.welcome': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
//+app.getUser().authToken
if (requestSource === googleAssistantRequest) {
sendGoogleResponse('Hello, Welcome to my Dialogflow agent!'); // Send simple response to user
} else {
sendResponse('Hello, Welcome to my Dialogflow agent!'); // Send simple response to user
}
},
// The default fallback intent has been matched, try to recover (https://dialogflow.com/docs/intents#fallback_intents)
'input.unknown': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
if (requestSource === googleAssistantRequest) {
sendGoogleResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
} else {
sendResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
}
},
// Default handler for unknown or undefined actions
'default': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
if (requestSource === googleAssistantRequest) {
let responseToUser = {
//googleRichResponse: googleRichResponse, // Optional, uncomment to enable
//googleOutputContexts: ['weather', 2, { ['city']: 'rome' }], // Optional, uncomment to enable
speech: 'This message is from Dialogflow\'s Cloud Functions for Firebase editor!', // spoken response
displayText: 'This is from Dialogflow\'s Cloud Functions for Firebase editor! :-)' // displayed response
};
sendGoogleResponse(responseToUser);
} else {
let responseToUser = {
//richResponses: richResponses, // Optional, uncomment to enable
//outputContexts: [{'name': 'weather', 'lifespan': 2, 'parameters': {'city': 'Rome'}}], // Optional, uncomment to enable
speech: 'This message is from Dialogflow\'s Cloud Functions for Firebase editor!', // spoken response
displayText: 'This is from Dialogflow\'s Cloud Functions for Firebase editor! :-)' // displayed response
};
sendResponse(responseToUser);
}
}
};

// If undefined or unknown action use the default handler
if (!actionHandlers[action]) {
action = 'default';
}

// Run the proper handler function to handle the request from Dialogflow
actionHandlers[action]();

// Function to send correctly formatted Google Assistant responses to Dialogflow which are then sent to the user
function sendGoogleResponse (responseToUser) {
if (typeof responseToUser === 'string') {
app.ask(responseToUser); // Google Assistant response
} else {
// If speech or displayText is defined use it to respond
let googleResponse = app.buildRichResponse().addSimpleResponse({
speech: responseToUser.speech || responseToUser.displayText,
displayText: responseToUser.displayText || responseToUser.speech
});

// Optional: Overwrite previous response with rich response
if (responseToUser.googleRichResponse) {
googleResponse = responseToUser.googleRichResponse;
}

// Optional: add contexts (https://dialogflow.com/docs/contexts)
if (responseToUser.googleOutputContexts) {
app.setContext(...responseToUser.googleOutputContexts);
}

app.ask(googleResponse); // Send response to Dialogflow and Google Assistant
}
}

// Function to send correctly formatted responses to Dialogflow which are then sent to the user
function sendResponse (responseToUser) {
// if the response is a string send it as a response to the user
if (typeof responseToUser === 'string') {
let responseJson = {};
responseJson.speech = responseToUser; // spoken response
responseJson.displayText = responseToUser; // displayed response
response.json(responseJson); // Send response to Dialogflow
} else {
// If the response to the user includes rich responses or contexts send them to Dialogflow
let responseJson = {};

// If speech or displayText is defined, use it to respond (if one isn't defined use the other's value)
responseJson.speech = responseToUser.speech || responseToUser.displayText;
responseJson.displayText = responseToUser.displayText || responseToUser.speech;

// Optional: add rich messages for integrations (https://dialogflow.com/docs/rich-messages)
responseJson.data = responseToUser.richResponses;

// Optional: add contexts (https://dialogflow.com/docs/contexts)
responseJson.contextOut = responseToUser.outputContexts;

response.json(responseJson); // Send response to Dialogflow
}
}
});

// Construct rich response for Google Assistant
const app = new DialogflowApp();
const googleRichResponse = app.buildRichResponse()
.addSimpleResponse('This is the first simple response for Google Assistant')
.addSuggestions(
['Suggestion Chip', 'Another Suggestion Chip'])
// Create a basic card and add it to the rich response
.addBasicCard(app.buildBasicCard(`This is a basic card. Text in a
basic card can include "quotes" and most other unicode characters
including emoji 📱. Basic cards also support some markdown
formatting like *emphasis* or _italics_, **strong** or __bold__,
and ***bold itallic*** or ___strong emphasis___ as well as other things
like line \nbreaks`) // Note the two spaces before '\n' required for a
// line break to be rendered in the card
.setSubtitle('This is a subtitle')
.setTitle('Title: this is a title')
.addButton('This is a button', 'https://assistant.google.com/')
.setImage('https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'Image alternate text'))
.addSimpleResponse({ speech: 'This is another simple response',
displayText: 'This is the another simple response 💁' });

// Rich responses for both Slack and Facebook
const richResponses = {
'slack': {
'text': 'This is a text response for Slack.',
'attachments': [
{
'title': 'Title: this is a title',
'title_link': 'https://assistant.google.com/',
'text': 'This is an attachment. Text in attachments can include \'quotes\' and most other unicode characters including emoji 📱. Attachments also upport line\nbreaks.',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'fallback': 'This is a fallback.'
}
]
},
'facebook': {
'attachment': {
'type': 'template',
'payload': {
'template_type': 'generic',
'elements': [
{
'title': 'Title: this is a title',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'subtitle': 'This is a subtitle',
'default_action': {
'type': 'web_url',
'url': 'https://assistant.google.com/'
},
'buttons': [
{
'type': 'web_url',
'url': 'https://assistant.google.com/',
'title': 'This is a button'
}
]
}
]
}
}
}
};

实际上,我部署的代码存在于对话框流内联编辑器中。但是不知道如何实现oauth端点,无论它应该是单独的云功能还是必须包含在现有的云功能中。而且,我也对oauth授权代码流的实际工作方式感到困惑。假设我们在Assistant应用程序上,一旦用户说“与foo app对话”,它会自动打开Web浏览器以进行oauth代码交换过程吗?

最佳答案

answer you referenced已于10月25日发布更新,表明他们已采取措施阻止您输入google.com端点作为帐户链接的身份验证提供者。他们似乎可能已采取其他措施来阻止以这种方式使用Google的身份验证服务器。

如果您使用自己的身份验证服务器,则错误500表示您的oauth服务器上存在错误,因此您应检查oauth服务器上是否有错误。

更新以回答您的其他一些问题。

But don't know how to implement an oauth endpoint



Google提供了有关使用 Implicit FlowAuthorization Code Flow进行最低限度的OAuth服务所需执行的操作的指南(但未提供代码),以及如何进行测试的指南。

whether it should be a separate cloud function or it has to be included within the existing one



它应该是分开的-甚至可以争论它必须分开。在“隐式流”和“授权代码流”中,您都需要提供一个URL端点,将在其中重定向用户以登录到您的服务。对于授权码流,您还需要一个助手用来交换 token 的附加Webhook。

这些功能背后的功能与您对Dialogflow Webhook所做的功能非常不同。尽管某人可能会制作一个可以处理所有不同任务的单一功能,但是没有必要。您将单独提供OAuth URL。

但是,您的Dialogflow Webhook与OAuth服务器确实存在某些关系。特别是,OAuth服务器交给助手的 token 将被交还给Dialogflow Webhook,因此Dialogflow需要某种方式来基于该 token 获取用户的信息。有许多方法可以做到这一点,但仅列举几种:
  • token 可以是JWT,并在正文中包含用户声明的用户信息。 Dialogflow Webhook应该使用公钥来验证 token 是有效的,并且需要知道声明的格式。
  • OAuth服务器和Dialogflow Webhook可以使用共享帐户数据库,并且OAuth服务器将 token 存储为用户帐户的 key ,并删除过期的 key 。然后,Dialogflow Webhook可以将其获取的 token 用作查找用户的键。
  • OAuth服务器可能有一个(另一个)webhook,其中Dialogflow可以请求用户信息,将 key 作为Authorization header 传递并得到答复。 (例如,这就是Google的工作。)

  • 确切的解决方案取决于您的需求以及您可以使用的资源。

    And also I am so confused with how oauth authorization code flow will actually work.. Let's assume we are on the Assistant app, once the user say "talk to foo app", does it automatically opens a web browser for oauth code exchange process?



    从广义上讲-是的。细节各不相同(并且可以更改),但不要过于关注细节。

    如果您在扬声器上使用助手,系统将提示您打开“家庭”应用程序,该应用程序应显示一张卡片,说明“操作”需要什么权限。单击该卡将打开“ Action ”网站的浏览器或Web View 以开始流程。

    如果您在移动设备上使用助手,它将直接提示您,然后打开浏览器或Web View 以访问Actions网站以开始流程。

    身份验证流程主要涉及:
  • 如有必要,让用户进行身份验证。
  • 让用户授权Assistant代表用户访问您的资源。
  • 然后使用一次性代码重定向到Google的服务器。
  • 然后Google的服务器获取代码...并关闭窗口。那就是用户看到的程度。

  • 在幕后,Google会使用此代码,并且由于您使用的是授权代码流,因此会在 token 交换URL处将其交换为auth token 和刷新 token 。

    然后,每当用户使用您的操作时,它将向您的服务器发送一个auth token 以及其余的请求。

    Plz suggest the necessary package for OAuth2 configuration



    那我做不到。对于初学者-这完全取决于您的其他资源和要求。 (这就是为什么StackOverflow不喜欢人们征求此类建议的原因。)

    那里有可用于设置OAuth2服务器的软件包(您可以搜索它们)。我可以肯定有人在提供OAuth即服务,尽管我不知道有什么用处。最后,如上所述,您可以根据Google的指导编写最小的OAuth2服务器。

    尝试为Google的OAuth创建代理...可能... not as easy as it first seems ...可能不如任何人满意的那样安全...并且可能(但不一定是IANAL)违反 Google's Terms of Service

    can't we store the user's email address by this approach?



    好了,您可以将所需的任何内容存储在用户的帐户中。但这是您的操作的用户帐户。

    例如,您可以代表您的用户访问Google API,以获取其电子邮件地址或他们授权您与Google进行合作的其他任何方式。您拥有的用户帐户可能会存储用于访问Google服务器的OAuth token 。但是您应该在逻辑上将其与助手用于访问服务器的代码分开。

    关于node.js - GoogleActions帐户尚未链接但出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47112179/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com