【问题标题】:Twilio-node VoiceResponse error when returning twiml返回 twiml 时出现 Twilio 节点 VoiceResponse 错误
【发布时间】:2020-11-10 20:07:04
【问题描述】:

我编写了一个 twilio 函数,它会吐出一些 twiml 来读出用户当前的天气。然而,在我的代码之外的某个地方,twiml 生成失败了。

https://gist.github.com/machinshin/331efc2ab31277b98fcb343704d711e9

相关的代码位是第 77-79 行。

第 77 行的 console.log 将以下内容转储到标准输入:

    twiml: <?xml version="1.0" encoding="UTF-8"?><Response><Say voice="Polly.Joanna">Hi</Say><Say voice="Polly.Joanna">According to OpenWeatherMap the station nearest Berkeley is currently scattered clouds
          with a temperature ranging from 57.6 Fahrenheit to 60.01 degrees Fahrenheit and a relative humidity of
          43% with an average wind speed of: 5.82 miles per hour</Say></Response>

然后框架转储了一个 XML 转换错误,但据我所知,我做的一切都是正确的,有什么帮助/想法吗?

(node:20051) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'XMLDocument'
    |     property 'children' -> object with constructor 'Array'
    |     index 0 -> object with constructor 'XMLDeclaration'
    --- property 'parent' closes the circle
    at JSON.stringify (<anonymous>)
    at stringify (/Users/vat/.twilio-cli/node_modules/express/lib/response.js:1123:12)
    at ServerResponse.json (/Users/vat/.twilio-cli/node_modules/express/lib/response.js:260:14)
    at ServerResponse.send (/Users/vat/.twilio-cli/node_modules/express/lib/response.js:158:21)
    at handleSuccess (/Users/vat/.twilio-cli/node_modules/twilio-run/dist/runtime/route.js:116:9)
    at callback (/Users/vat/.twilio-cli/node_modules/twilio-run/dist/runtime/route.js:164:13)
    at exports.handler (/Users/vat/workspace/machinshin/projects/idwresearch/dist/functions/get_say_weather.protected.js:71:16)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:20051) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:20051) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

【问题讨论】:

    标签: twilio twilio-api twilio-twiml


    【解决方案1】:

    以下内容对我有用,没有错误:

    const axios = require('axios');
    const qs = require('querystring');
    
    const jsLog = (obj) => (JSON.stringify(obj, null, 2));
    
    const voice = 'Polly.Joanna';
    const OW_URL ='https://api.openweathermap.org/data/2.5/weather';
    
    async function getWeatherForZipcode (OW_APP_ID, zipcode, countryCode, units) {
    
      const zip = (`${zipcode},${countryCode}`).toLowerCase().trim();
      return axios.get(OW_URL, {
        params: {
          appid: OW_APP_ID,
          units: units || 'imperial',
          zip,
        }
      }).then((res) => {
        return res.data;
      }).catch((err) => {
        console.error(`getWeatherForZipcode: error: ${jsLog(err)}`);
        throw new Error(err);
      });
    }
    
    /** parseWeatherResponse
     * @param
     *
     **/
    function parseWeatherResponse(data) {
      return {
        current_conditions: data.weather[0].description,
        station_at: data.name,
        temp: data.main.temp,
        temp_max: data.main.temp_max,
        humidity: data.main.humidity,
        wind_speed: data.wind.speed,
      };
    }
    
    /** handler
     *  @param {Context} context
     *  @param {Event} event
     *  @param {ServerlessCallback} callback
     *  @returns {twiml.VoiceResponse}
     **/
    
    exports.handler = async function (context, event, callback) {
      try {
        context.callbackWaitsForEmptyEventLoop = false;
        console.log(`-------------------\n`);
        const OW_APP_ID = context.OW_APP_ID;
        const { units, zip, countryCode } = event;
        const z = zip.toLowerCase().trim();
        const cc =  countryCode.toLowerCase().trim();
        const uu = units.toLowerCase().trim();
    
        const response = await getWeatherForZipcode(OW_APP_ID, z, cc, uu);
        const toSay = parseWeatherResponse(response);
        
        // const twiml = new VoiceResponse();
        const twiml = new Twilio.twiml.VoiceResponse();
    
        const say = twiml.say({ voice: 'Polly.Joanna', }, 'Hi');
      
        twiml.say({voice}, `According to OpenWeatherMap the station nearest ${toSay.station_at} is currently ${toSay.current_conditions}
        with a temperature ranging from ${toSay.temp} Fahrenheit to ${toSay.temp_max} degrees Fahrenheit and a relative humidity of
        ${toSay.humidity}% with an average wind speed of: ${toSay.wind_speed} miles per hour`);
        
        console.log(`twiml: ${twiml.toString()}`);
        
        return callback(null, twiml);
      } catch (err) {
        throw err;
        console.log(`some error was thrown: ${jsLog(err)}`);
        return callback(`err: ${jsLog(err)}, event: ${jsLog(event)}`);
      }
    }
    

    【讨论】:

    • 谢谢!我看到了区别..您删除了“require('twilio')”,所以代码如何使用'内置'库版本..我想知道行为上的差异是什么..
    • 您可以更改内置的 Twilio Helper 库,方法是更新 Twilio 函数中的依赖项(在函数 V2 的依赖项下)指向更新的版本 github.com/twilio/twilio-node/blob/main/CHANGES.md。您可以使用:const client = context.getTwilioClient(); 实例化内置库,并且不需要它。
    • 附言。不错的代码,非常有条理且易于理解:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多