API 距离矩阵 单独在 Javascript 中调用

所以我是一个非常初级的程序员,试图了解如何在纯 Javascript 中从 Google Distance Matrix API 调用/获取数据。


下面是我的代码


https = require('https')


function getDistance(app){


    console.log('testing1');

    let defaultPath = 'maps.googleapis.com/maps/api/distancematrix/json?units=metric';

    let APIKey = '&key=<API KEY HERE>';

    let origin = 'Tampines Avenue 1, Temasek Polytechnic';

    let destination = 'Tampines Central 5, Tampines Mall';

    let newPath = defaultPath+ '&origins=' + origin + '&destinations=' +destination + APIKey;


    console.log('https://'+ newPath); //this prints the correct path


https.get('https://'+ newPath, (res) =>{ //i assume the problem begins here?


  console.log('testing2')//doesnt print


  let body = ''; //no idea what this does. Copied from a school lab sheet


  res.on('data', (d) => { 

    console.log('testing3') //this doesn't print

    let response = JSON.parse(body);


    let distance = response.rows[0].elements.distance.text //are these correct?

    let travelTime = response.rows[0].elements.duration.text 


    console.log(distance) //doesnt print

    console.log(response.rows[0]) //doesnt print


    app.add('distance between is ' + distance + '. Time taken is ' + travelTime);

    console.log(response);

  });

});

}


我很确定 'https://'+ newPath 是正确的,因为它打印在 console.log 中


并将链接扔到浏览器中,我得到了这个结果

http://img2.mukewang.com/61d043f30001bceb07500443.jpg

所以有人可以向我解释我做错了什么吗?哦,还有,不知道这是否有必要,但我在 dialogflow.cloud.google.com 中这样做作为我任务的聊天机器人

这是我得到的错误

错误:没有为平台定义响应:未定义在 WebhookClient.send_ (/srv/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:428:13) at promise.then (/srv/node_modules/dialogflow-fulfillment/src /dialogflow-fulfillment.js:246:38) 在 process._tickDomainCallback (internal/process/next_tick.js:229:7)


MM们
浏览 148回答 2
2回答

哆啦的时光机

我在 GitHub 上发现了一个类似的问题:https : //github.com/dialogflow/dialogflow-fulfillment-nodejs/issues/22解决办法是好的,这就是我为使其正常工作所做的工作。我使用 request-promise-native 而不是 http 来进行 AJAX 调用。const rp = require('request-promise-native');我从 rp 返回的承诺的处理程序返回了一个承诺。return rp(options).then(data => { // Extract relevant details from data. // Add it to the agent. agent.add('Here's the data: ', JSON.stringify(data)); return Promise.resolve(agent); });完整的代码是'use strict';const express = require('express');const bodyParser = require('body-parser');const rp = require('request-promise-native');const { WebhookClient } = require('dialogflow-fulfillment');const { Card, Suggestion } = require('dialogflow-fulfillment');const { Carousel } = require('actions-on-google');process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statementsconst imageUrl = 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png';const imageUrl2 = 'https://lh3.googleusercontent.com/Nu3a6F80WfixUqf_ec_vgXy_c0-0r4VLJRXjVFF_X_CIilEu8B9fT35qyTEj_PEsKw';const linkUrl = 'https://assistant.google.com/';const API_KEY = 'YOUR-API-KEY-HERE';const server = express();server.use(&nbsp; bodyParser.urlencoded({&nbsp; &nbsp; extended: true&nbsp; }));server.use(bodyParser.json());server.post('/dialog-flow-fulfillment', (request, response) => {&nbsp; const agent = new WebhookClient({ request, response });&nbsp; function googleAssistantOther(agent) {&nbsp; &nbsp; let conv = agent.conv();&nbsp; &nbsp; conv.ask(`Sure! Details about ${agent.parameters.movie} coming your way!`);&nbsp; &nbsp; return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {&nbsp; &nbsp; &nbsp; conv.ask(`Okay! So there you go.`);&nbsp; &nbsp; &nbsp; conv.ask(new Card({&nbsp; &nbsp; &nbsp; &nbsp; title: `${movie.Title}(${movie.Year})`,&nbsp; &nbsp; &nbsp; &nbsp; imageUrl: movie.Poster,&nbsp; &nbsp; &nbsp; &nbsp; text: `${movie.Rated} | ${movie.Runtime} | ${movie.Genre} | ${movie.Released} (${movie.Country})`,&nbsp; &nbsp; &nbsp; &nbsp; buttonText: 'Website',&nbsp; &nbsp; &nbsp; &nbsp; buttonUrl: movie.Website || `https://www.imdb.com/title/${movie.imdbID}`&nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; &nbsp; conv.ask(new Suggestion(`More details`));&nbsp; &nbsp; &nbsp; conv.ask(new Suggestion(`Another movie`));&nbsp; &nbsp; &nbsp; agent.add(conv);&nbsp; &nbsp; &nbsp; return Promise.resolve(agent);&nbsp; &nbsp; });&nbsp; }&nbsp; function welcome(agent) {&nbsp; &nbsp; agent.add(`Welcome to my agent!`);&nbsp; }&nbsp; function fallback(agent) {&nbsp; &nbsp; agent.add(`I didn't understand`);&nbsp; &nbsp; agent.add(`I'm sorry, can you try again?`);&nbsp; }&nbsp; function getMovieDetailsOther(agent) {&nbsp; &nbsp; return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {&nbsp; &nbsp; &nbsp; // const responseDataToSend = `${movie.Title} is a ${&nbsp; &nbsp; &nbsp; //&nbsp; &nbsp;movie.Actors&nbsp; &nbsp; &nbsp; // } starer ${movie.Genre} movie, released in ${&nbsp; &nbsp; &nbsp; //&nbsp; &nbsp;movie.Year&nbsp; &nbsp; &nbsp; // }. It was directed by ${movie.Director}`;&nbsp; &nbsp; &nbsp; // console.log(`Generated response as ${responseDataToSend}`);&nbsp; &nbsp; &nbsp; // agent.add(responseDataToSend);&nbsp; &nbsp; &nbsp; agent.add(`Okay! So there you go.`);&nbsp; &nbsp; &nbsp; agent.add(new Card({&nbsp; &nbsp; &nbsp; &nbsp; title: `${movie.Title}(${movie.Year})`,&nbsp; &nbsp; &nbsp; &nbsp; imageUrl: movie.Poster,&nbsp; &nbsp; &nbsp; &nbsp; text: `${movie.Rated} | ${movie.Runtime} | ${movie.Genre} | ${movie.Released} (${movie.Country})`,&nbsp; &nbsp; &nbsp; &nbsp; buttonText: 'Website',&nbsp; &nbsp; &nbsp; &nbsp; buttonUrl: movie.Website || `https://www.imdb.com/title/${movie.imdbID}`&nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; &nbsp; agent.add(new Suggestion(`More details`));&nbsp; &nbsp; &nbsp; agent.add(new Suggestion(`Another movie`));&nbsp; &nbsp; &nbsp; return Promise.resolve(agent);&nbsp; &nbsp; }, error => {&nbsp; &nbsp; &nbsp; console.log(`Got an error as ${error}`);&nbsp; &nbsp; &nbsp; agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; })&nbsp; &nbsp; .catch(function (err) {&nbsp; &nbsp; &nbsp; console.log(`Caught an err as ${err}`);&nbsp; &nbsp; &nbsp; agent.add(err);&nbsp; &nbsp; });&nbsp; &nbsp; // agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);&nbsp; &nbsp; // const newCard = new Card({&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;title: `Title: this is a card title`,&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;imageUrl: imageUrl,&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;text: `This is the body text of a card.&nbsp; You can even use line\n&nbsp; breaks and emoji! 💁`,&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;buttonText: 'This is a button',&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;buttonUrl: linkUrl&nbsp; &nbsp; // });&nbsp; &nbsp; // // newCard.setPlatform('facebook');&nbsp; &nbsp; // agent.add(newCard);&nbsp; &nbsp; // agent.add(new Suggestion(`Quick Reply`));&nbsp; &nbsp; // agent.add(new Suggestion(`Suggestion`));&nbsp; &nbsp; // agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});&nbsp; }&nbsp; function moreDetailsOther(agent) {&nbsp; &nbsp; return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {&nbsp; &nbsp; &nbsp; agent.add(`Okay! I've got you covered on this too.`);&nbsp; &nbsp; &nbsp; agent.add(`So the ${movie.Actors} starer ${movie.Type} is produced by ${movie.Production}, is directed by ${movie.Director}`);&nbsp; &nbsp; &nbsp; agent.add(`It ${movie.Awards}. It's available in ${movie.Language}`);&nbsp; &nbsp; &nbsp; agent.add(`Written by ${movie.Writer}, it plots ${movie.Plot}`);&nbsp; &nbsp; &nbsp; agent.add(new Suggestion(`Stats on the movie`));&nbsp; &nbsp; &nbsp; agent.add(new Suggestion(`Another movie`));&nbsp; &nbsp; &nbsp; return Promise.resolve(agent);&nbsp; &nbsp; }, error => {&nbsp; &nbsp; &nbsp; console.log(`Got an error as ${error}`);&nbsp; &nbsp; &nbsp; agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; })&nbsp; &nbsp; .catch(function (err) {&nbsp; &nbsp; &nbsp; console.log(`Caught an err as ${err}`);&nbsp; &nbsp; &nbsp; agent.add(err);&nbsp; &nbsp; });&nbsp; }&nbsp; function movieStatsOther(agent) {&nbsp; &nbsp; return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {&nbsp; &nbsp; &nbsp; let ratingDetails = `${movie.Title} scored `;&nbsp; &nbsp; &nbsp; movie.Ratings.forEach(rating => {&nbsp; &nbsp; &nbsp; &nbsp; ratingDetails += `${rating.Value} on ${rating.Source} `&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; agent.add(`Sure! Here are the stats.`);&nbsp; &nbsp; &nbsp; agent.add(ratingDetails);&nbsp; &nbsp; &nbsp; agent.add(new Suggestion(`Another movie`));&nbsp; &nbsp; &nbsp; return Promise.resolve(agent);&nbsp; &nbsp; }, error => {&nbsp; &nbsp; &nbsp; console.log(`Got an error as ${error}`);&nbsp; &nbsp; &nbsp; agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`&nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; })&nbsp; &nbsp; .catch(function (err) {&nbsp; &nbsp; &nbsp; console.log(`Caught an err as ${err}`);&nbsp; &nbsp; &nbsp; agent.add(err);&nbsp; &nbsp; });&nbsp; }&nbsp; function getMovieDataFromOMDb(movieName) {&nbsp; &nbsp; const movieToSearch = movieName || 'The Godfather';&nbsp; &nbsp; const options = {&nbsp; &nbsp; &nbsp; uri: 'https://www.omdbapi.com/',&nbsp; &nbsp; &nbsp; json: true,&nbsp; &nbsp; &nbsp; qs: {&nbsp; &nbsp; &nbsp; &nbsp; t: movieToSearch,&nbsp; &nbsp; &nbsp; &nbsp; apikey: API_KEY&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };&nbsp; &nbsp; return rp(options);&nbsp; }&nbsp; // Run the proper handler based on the matched Dialogflow intent&nbsp; let intentMap = new Map();&nbsp; intentMap.set('Default Welcome Intent', welcome);&nbsp; intentMap.set('Default Fallback Intent', fallback);&nbsp; if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {&nbsp; &nbsp; intentMap.set(null, googleAssistantOther);&nbsp; &nbsp; // intentMap.set('More Details', googleAssistantMoreDetails);&nbsp; &nbsp; // intentMap.set('Movie Stats', googleAssistantMovieStats);&nbsp; } else {&nbsp; &nbsp; intentMap.set('Get Movie Details', getMovieDetailsOther);&nbsp; &nbsp; intentMap.set('More Details', moreDetailsOther);&nbsp; &nbsp; intentMap.set('Movie Stats', movieStatsOther);&nbsp; }&nbsp; agent.handleRequest(intentMap);});server.listen(process.env.PORT || 8000, () => {&nbsp; console.log('Server is up and running...');});代码笔:https ://codepen.io/siddajmera/pen/eraNLW ? editors = 0010

慕桂英4014372

您没有显示所有代码,但看起来getDistance()是您在未显示的代码中注册的 Intent Handler 函数。如果是这样,并且如果您对 API 进行异步调用,则需要返回一个 Promise 以指示您在发送结果之前正在等待 HTTP 调用完成。如果没有 Promise,函数会在调用 with 后立即完成http.get(),但没有为 with 响应设置任何内容app.add()。虽然可以将基于事件的调用(您现在正在做的事情)转换为 Promise,但如果您不熟悉它并没有那么容易,并且有更好的解决方案。使用诸如request-promise 之类的包(更可能是 request-promise-native - 它使用相同的语法,但 request-promise 有文档)要容易得多。有了这个,您将返回由 http 调用生成的 Promise,并且在then()它的子句中,您将调用app.add().我还没有测试过,但它可能看起来像这样:const rp = require('request-promise-native');function getDistance(app){&nbsp; &nbsp; console.log('testing1');&nbsp; &nbsp; let defaultPath = 'maps.googleapis.com/maps/api/distancematrix/json?units=metric';&nbsp; &nbsp; let APIKey = '&key=<API KEY HERE>';&nbsp; &nbsp; let origin = 'Tampines Avenue 1, Temasek Polytechnic';&nbsp; &nbsp; let destination = 'Tampines Central 5, Tampines Mall';&nbsp; &nbsp; let newPath = defaultPath+ '&origins=' + origin + '&destinations=' +destination + APIKey;&nbsp; &nbsp; let url = 'https://'+newPath;&nbsp; &nbsp; console.log(url);&nbsp; &nbsp; rp.get(url)&nbsp; &nbsp; &nbsp; .then( response => {&nbsp; &nbsp; &nbsp; &nbsp; console.log(response);&nbsp; &nbsp; &nbsp; &nbsp; let distance = response.rows[0].elements.distance.text&nbsp; &nbsp; &nbsp; &nbsp; let travelTime = response.rows[0].elements.duration.text&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; app.add('distance between is ' + distance + '. Time taken is ' + travelTime);&nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; .catch( err => {&nbsp; &nbsp; &nbsp; &nbsp; console.log( err );&nbsp; &nbsp; &nbsp; &nbsp; app.add('Something went wrong.');&nbsp; &nbsp; &nbsp; });};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript