#twilio #twilio-api #twilio-twiml
#twilio #twilio-api #twilio-twiml
Вопрос:
Я написал twilio-функцию, которая выдает немного twiml для считывания текущей погоды пользователя. Однако где-то за пределами моего кода происходит сбой генерации twiml.
https://gist.github.com/machinshin/331efc2ab31277b98fcb343704d711e9
соответствующими битами кода являются строки 77-79.
консоль.журнал в строке 77 сбрасывает следующее в stdin:
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.
Ответ №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)}`);
}
}
Комментарии:
1. Спасибо! Я вижу разницу.. вы удалили «require (‘twilio’)», так как код использует «встроенную» версию библиотеки.. Интересно, каковы различия в поведении..
2. Вы можете изменить встроенную вспомогательную библиотеку Twilio, обновив зависимость в функции Twilio (в разделе Зависимости для функций V2), чтобы указать на более новую версию, github.com/twilio/twilio-node/blob/main/CHANGES.md . Вы можете создать экземпляр встроенной библиотеки, используя:
const client = context.getTwilioClient();
, и нет необходимости требовать этого.3. Ps. Хороший код, очень организованный и простой в использовании 🙂