将录制的Twilio音频发送给Lex

时间:2018-08-17 15:49:05

标签: twilio amazon-lex

当前,我能够记录用户输入的内容,将记录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中编写此应用程序,如果有帮助,我可以添加更多代码。

1 个答案:

答案 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());
});