当前,我能够记录用户输入的内容,将记录URL传递给所需的功能,并在本地下载音频文件。我正在尝试对音频文件进行处理,要么获取它的缓冲区以发送给Lex,要么将其转换为Lex需要的格式。
根据AWS文档,输入流参数值接受以下值:
var params = {
botAlias: 'STRING_VALUE', /* required */
botName: 'STRING_VALUE', /* required */
contentType: 'STRING_VALUE', /* required */
inputStream: new Buffer('...') || 'STRING_VALUE' || streamObject, /*required */
userId: 'STRING_VALUE', /* required */
accept: 'STRING_VALUE',
requestAttributes: any /* This value will be JSON encoded on your behalf with JSON.stringify() */,
sessionAttributes: any /* This value will be JSON encoded on your behalf with JSON.stringify() */
};
lexruntime.postContent(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
根据twilio文档,音频文件看起来非常灵活...
默认情况下,对RecordingUrl的请求将以二进制WAV音频格式返回记录。要请求MP3格式的录制,请在RecordingUrl后面附加“ .mp3”。
我需要怎么做才能以Lex正确的格式获取twilio录制的音频?这仅仅是建立正确的Lex参数集的问题,还是我需要事先进行一些音频转换?如果有帮助,我将在node js中编写此应用程序,如果有帮助,我可以添加更多代码。
答案 0 :(得分:0)
我可以通过从Twilio作为PCM下载文件并稍微更改参数来解决这个问题。同样,由于Twilio处理记录动词的方式,我需要在等待recordStatusCallback POST的同时将呼叫转移到保持状态。我还将发给Lex的最终状态的短信给来电者。
我用来下载文件的代码:
app.post('/processRecording', (request, response) => {
var https = require('https');
var fs = require('fs');
let callSID = request.body.CallSid;
let url = request.body.RecordingUrl;
var saveFile = new Promise(function(resolve, reject) {
let fileName = callSID+ ".pcm";
var file = fs.createWriteStream(fileName);
var request = https.get(url, function(response) {
response.pipe(file);
resolve();
});
});
});
const accountSid = 'YOUR ACCOUNT SID';
const authToken = 'YOUR AUTH TOKEN';
const client = require('twilio')(accountSid, authToken);
//Once the file is downloaded, I then fetch the call from the hold state using this code:
saveFile.then(function(){
client.calls(callSID)
.update({method: 'POST', url: '/updateCall'})
.then(call => console.log(call.to))
.done();
});
我的updateCall端点如下所示:
app.post('/updateCall', (request, response) => {
let lexruntime = new AWS.LexRuntime();
let recordedFileName = request.body.CallSid + '.pcm';
let toNumber = request.body.To;
let fromNumber = request.body.From;
let twiml = new Twilio.twiml.VoiceResponse();
let lexFileStream = fs.createReadStream(recordedFileName);
let sid = request.body.CallSid;
var params = {
botAlias: 'prod', /* required */
botName: 'OrderFlowers', /* required */
contentType: 'audio/lpcm; sample-rate=8000; sample-size-bits=16; channel-count=1; is-big-endian=false',
accept: 'text/plain; charset=utf-8',
userId: sid /* required */
};
params.inputStream = lexFileStream;
lexruntime.postContent(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
if (data.dialogState == "ElicitSlot" || data.dialogState == "ConfirmIntent" || data.dialogState == "ElicitIntent" ){
twiml.say(data.message);
twiml.redirect({
method: 'POST'
}, '/recordVoice');
response.type('text/xml');
response.send(twiml.toString());
}
else if (data.dialogState == "Fulfilled" ){
twiml.say(data.message);
response.type('text/xml');
response.send(twiml.toString());
client.messages.create({
to: toNumber,
from: fromNumber,
body: data.message
}).then(msg => {
}).catch(err => console.log(err));
}
else{
twiml.say(data.message);
response.type('text/xml');
response.send(twiml.toString());
}
});
});
recordVoice端点实际上是一个Twilio无服务器功能,但我认为这是一个表达端点:
app.post('/recordVoice', (request, response) => {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.record({
action: '/deadAir',
recordingStatusCallback: '/processRecording',
trim: true,
maxLength: 10,
finishOnKey: '*'
});
twiml.say('I did not receive a recording');
response.type('text/xml');
response.send(twiml.toString());
});
/ deadAir终结点也是Twilio无服务器功能,但这是它的样子:
app.post('/deadAir', (request, response) => {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.pause({
length: 60
});
response.type('text/xml');
response.send(twiml.toString());
});