为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

MM们 2022-01-01 20:06:55
所以我是一个非常初级的程序员,试图了解如何在纯 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 pathhttps.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 中并将链接扔到浏览器中,我得到了这个结果所以有人可以向我解释我做错了什么吗?哦,还有,不知道这是否有必要,但我在 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)
查看完整描述

2 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

我在 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 statements


const 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(

  bodyParser.urlencoded({

    extended: true

  })

);

server.use(bodyParser.json());


server.post('/dialog-flow-fulfillment', (request, response) => {

  const agent = new WebhookClient({ request, response });


  function googleAssistantOther(agent) {

    let conv = agent.conv();

    conv.ask(`Sure! Details about ${agent.parameters.movie} coming your way!`);

    return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {

      conv.ask(`Okay! So there you go.`);

      conv.ask(new Card({

        title: `${movie.Title}(${movie.Year})`,

        imageUrl: movie.Poster,

        text: `${movie.Rated} | ${movie.Runtime} | ${movie.Genre} | ${movie.Released} (${movie.Country})`,

        buttonText: 'Website',

        buttonUrl: movie.Website || `https://www.imdb.com/title/${movie.imdbID}`

      }));

      conv.ask(new Suggestion(`More details`));

      conv.ask(new Suggestion(`Another movie`));

      agent.add(conv);

      return Promise.resolve(agent);

    });

  }


  function welcome(agent) {

    agent.add(`Welcome to my agent!`);

  }


  function fallback(agent) {

    agent.add(`I didn't understand`);

    agent.add(`I'm sorry, can you try again?`);

  }


  function getMovieDetailsOther(agent) {

    return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {

      // const responseDataToSend = `${movie.Title} is a ${

      //   movie.Actors

      // } starer ${movie.Genre} movie, released in ${

      //   movie.Year

      // }. It was directed by ${movie.Director}`;

      // console.log(`Generated response as ${responseDataToSend}`);

      // agent.add(responseDataToSend);


      agent.add(`Okay! So there you go.`);

      agent.add(new Card({

        title: `${movie.Title}(${movie.Year})`,

        imageUrl: movie.Poster,

        text: `${movie.Rated} | ${movie.Runtime} | ${movie.Genre} | ${movie.Released} (${movie.Country})`,

        buttonText: 'Website',

        buttonUrl: movie.Website || `https://www.imdb.com/title/${movie.imdbID}`

      }));

      agent.add(new Suggestion(`More details`));

      agent.add(new Suggestion(`Another movie`));

      return Promise.resolve(agent);

    }, error => {

      console.log(`Got an error as ${error}`);

      agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`

      );

    })

    .catch(function (err) {

      console.log(`Caught an err as ${err}`);

      agent.add(err);

    });


    // agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);

    // const newCard = new Card({

    //     title: `Title: this is a card title`,

    //     imageUrl: imageUrl,

    //     text: `This is the body text of a card.  You can even use line\n  breaks and emoji! 💁`,

    //     buttonText: 'This is a button',

    //     buttonUrl: linkUrl

    // });

    // // newCard.setPlatform('facebook');

    // agent.add(newCard);

    // agent.add(new Suggestion(`Quick Reply`));

    // agent.add(new Suggestion(`Suggestion`));

    // agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});

  }


  function moreDetailsOther(agent) {

    return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {

      agent.add(`Okay! I've got you covered on this too.`);

      agent.add(`So the ${movie.Actors} starer ${movie.Type} is produced by ${movie.Production}, is directed by ${movie.Director}`);

      agent.add(`It ${movie.Awards}. It's available in ${movie.Language}`);

      agent.add(`Written by ${movie.Writer}, it plots ${movie.Plot}`);

      agent.add(new Suggestion(`Stats on the movie`));

      agent.add(new Suggestion(`Another movie`));

      return Promise.resolve(agent);

    }, error => {

      console.log(`Got an error as ${error}`);

      agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`

      );

    })

    .catch(function (err) {

      console.log(`Caught an err as ${err}`);

      agent.add(err);

    });

  }


  function movieStatsOther(agent) {

    return getMovieDataFromOMDb(agent.parameters.movie).then(movie => {

      let ratingDetails = `${movie.Title} scored `;

      movie.Ratings.forEach(rating => {

        ratingDetails += `${rating.Value} on ${rating.Source} `

      });

      agent.add(`Sure! Here are the stats.`);

      agent.add(ratingDetails);

      agent.add(new Suggestion(`Another movie`));

      return Promise.resolve(agent);

    }, error => {

      console.log(`Got an error as ${error}`);

      agent.add(`Sorry bout that! An error prevented getting data for: ${agent.parameters.movie || 'the requested movie'}`

      );

    })

    .catch(function (err) {

      console.log(`Caught an err as ${err}`);

      agent.add(err);

    });

  }


  function getMovieDataFromOMDb(movieName) {

    const movieToSearch = movieName || 'The Godfather';

    const options = {

      uri: 'https://www.omdbapi.com/',

      json: true,

      qs: {

        t: movieToSearch,

        apikey: API_KEY

      }

    };

    return rp(options);

  }


  // Run the proper handler based on the matched Dialogflow intent

  let intentMap = new Map();

  intentMap.set('Default Welcome Intent', welcome);

  intentMap.set('Default Fallback Intent', fallback);

  if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {

    intentMap.set(null, googleAssistantOther);

    // intentMap.set('More Details', googleAssistantMoreDetails);

    // intentMap.set('Movie Stats', googleAssistantMovieStats);

  } else {

    intentMap.set('Get Movie Details', getMovieDetailsOther);

    intentMap.set('More Details', moreDetailsOther);

    intentMap.set('Movie Stats', movieStatsOther);

  }

  agent.handleRequest(intentMap);

});


server.listen(process.env.PORT || 8000, () => {

  console.log('Server is up and running...');

});

代码笔:https ://codepen.io/siddajmera/pen/eraNLW ? editors = 0010


查看完整回答
反对 回复 2022-01-01
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

您没有显示所有代码,但看起来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){


    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;

    let url = 'https://'+newPath;


    console.log(url);


    rp.get(url)

      .then( response => {

        console.log(response);

        let distance = response.rows[0].elements.distance.text

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


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

      })

      .catch( err => {

        console.log( err );

        app.add('Something went wrong.');

      });


};


查看完整回答
反对 回复 2022-01-01
  • 2 回答
  • 0 关注
  • 147 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信