使用Google NodeJS客户端与DialogFlow实现OAuth2.0时遇两类错误求助
先来解决你遇到的第一个问题:TypeError: Cannot read property '0' of undefined(对应keys.redirect_uris[0]报错)
这个问题的根源是,你使用的是Web类型的OAuth凭证,但Google Node.js客户端的oauth2.js示例默认是针对installed类型凭证编写的。示例代码里大概率是从keys.installed.redirect_uris读取重定向地址,而你的凭证信息存在keys.web.redirect_uris下,自然找不到对应字段。
修复步骤:
- 打开
oauth2.js文件,找到加载凭证后获取重定向URI的代码段,比如原代码可能是:const redirectUrl = keys.installed.redirect_uris[0]; - 将其修改为从web对象读取:
const redirectUrl = keys.web.redirect_uris[0]; - 同时检查代码中其他引用
keys.installed的地方(比如client_id、client_secret),全部替换为keys.web.client_id和keys.web.client_secret,确保所有凭证字段都从正确的对象中读取。
再来看5月24日更新的TypeError: Cannot read property 'payload' of undefined错误:
这个问题的核心是你把Dialogflow Fulfillment服务和OAuth2回调服务放在了同一个ngrok根路径下。当Google OAuth完成登录后,回调请求会发送到https://xxxx.ngrok.io,但这个请求被Dialogflow的Fulfillment处理逻辑接收到了——而actions-on-google库只识别符合Dialogflow Webhook格式的请求,OAuth回调请求里根本没有它需要的payload字段,因此抛出错误。
解决办法是给两个服务分配不同的路径,让它们各司其职:
修改Dialogflow Fulfillment的路径:
在你的Fulfillment代码中,将Webhook的监听路径改为/webhook(或其他自定义路径),比如使用Express框架的话:app.post('/webhook', dialogflowFulfillmentHandler);然后前往Dialogflow控制台的Fulfillment设置,将Webhook URL更新为
https://xxxx.ngrok.io/webhook。修改OAuth2回调的路径:
在oauth2.js中,将回调路由改为/oauth2callback,示例代码如下:app.get('/oauth2callback', (req, res) => { // 处理OAuth回调的逻辑代码 });同时前往Google Cloud Console的OAuth2凭证设置页面,将重定向URI修改为
https://xxxx.ngrok.io/oauth2callback,确保与代码中的路径一致。确保两个服务共存:
如果你的OAuth服务和Dialogflow Fulfillment在同一个Node.js项目中,将两个路由挂载到同一个Express实例即可;如果是分开的项目,需确保两个服务使用不同端口,再通过ngrok分别映射(更推荐合并到同一项目,用路径区分请求)。
完成上述修改后,OAuth回调请求会被/oauth2callback路由处理,Dialogflow的Webhook请求会被/webhook路由处理,就不会再出现payload未定义的错误了。
内容的提问来源于stack exchange,提问作者aarontzk

