无法使用无服务器框架发送xml响应

时间:2017-05-07 08:49:19

标签: twilio aws-lambda aws-api-gateway serverless-framework twiml

我正在使用twilio,当调用我的twilio号码时,它会调用webhook,我使用lambda函数作为webhook,

twilio期待来自webhook的xml(以前称为twiml)响应,我无法从lambda函数发送xml响应

我使用无服务器框架

这是我的代码 的功能

module.exports.voice = (event, context, callback) => {

  console.log("event", JSON.stringify(event))
  var twiml = new VoiceResponse();

  twiml.say({ voice: 'alice' }, 'Hello, What type of podcast would you like to listen? ');
  twiml.say({ voice: 'alice' }, 'Please record your response after the beep. Press any key to finish.');

  twiml.record({
    transcribe: true,
    transcribeCallback: '/voice/transcribe',
    maxLength: 10
  });

  console.log("xml: ", twiml.toString())

  context.succeed({
    body: twiml.toString()
  });
};

YML:

service: aws-nodejs

provider:
  name: aws
  runtime: nodejs6.10
  timeout: 10

iamRoleStatements:
    - Effect: "Allow"
      Action: "*"
      Resource: "*"

functions:
  voice:
    handler: handler.voice
    events:
      - http:
          path: voice
          method: post
          integration: lambda
          response:
            headers:
              Content-Type: "'application/xml'"
          template: $input.path("$")
          statusCodes:
                200:
                    pattern: '.*' # JSON response
                    template:
                      application/xml: $input.path("$.body") # XML return object
                    headers:
                      Content-Type: "'application/xml'"

响应: enter image description here enter image description here

如果我在代码中犯了一些错误,请告诉我 还在github上创建了一个issue

谢谢, Inzamam Malik

7 个答案:

答案 0 :(得分:2)

你不需要乱用serverless.yml。这是一个简单的方法:

在serverless.yml ...

functions:
  voice:
    handler: handler.voice
    events:
      - http:
          path: voice
          method: post

(不需要响应,标题,内容类型,模板和状态代码)

然后你可以在你的函数中设置statusCode和Content-Type。

所以删除这部分......

context.succeed({
    body: twiml.toString()
  });

...并将其替换为:

const response = {
    statusCode: 200,
    headers: {
      'Content-Type': 'text/xml',
    },
    body: twiml.toString(),
};

callback(null, response);

Lambda代理集成(默认情况下)将其组合成一个正确的响应。

我个人觉得这种方式更简单,更易读。

答案 1 :(得分:1)

您需要将lambda作为“代理”类型,因此您需要设置body属性。 但只是尝试做

context.succeed(twiml.toString());

将直接发送“string”作为结果

或使用回调参数:

function(event, context, callback) {
   callback(null, twiml.toString())
}

答案 2 :(得分:0)

如@UXDart所述,您无法使用标准集成来执行此操作。您应该像这里一样设置与Lambda的代理集成 - http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html#api-gateway-proxy-integration-lambda-function-nodejs

这样可以更好地处理您要执行的操作,通过api网关返回xml。

答案 3 :(得分:0)

将您的serverless.yml更改为:

service: aws-nodejs

provider:
  name: aws
  runtime: nodejs6.10
  timeout: 10

iamRoleStatements:
    - Effect: "Allow"
      Action: "*"
      Resource: "*"

functions:
  voice:
    handler: handler.voice
    events:
      - http:
          path: voice
          method: post
          integration: lambda
          response:
            headers:
              Content-Type: "'application/xml'"
            template: $input.path("$")
            statusCodes:
                200:
                    pattern: '' # Default response method
                    template:
                      # Your script returns json, so match it here
                      application/json: $input.path("$.body")
                    headers:
                      Content-Type: "'application/xml'"

答案 4 :(得分:0)

让我的工作。

events:
      - http:
          path: call/receive
          method: post
          integration: lambda
          response:
            headers: 
              Content-Type: "'application/xml'"
            template: $input.path("$")
            statusCodes:
              200:
                pattern: ''
                template: 
                  application/json: $input.path("$")
                headers:
                  Content-Type: "'application/xml'"

callback(null, twiml.toString());

答案 5 :(得分:0)

它对我有用。

webhook:
    handler: webhook.webhook
    events:
      - http:
          path: webhook
          method: get
          cors: true
          integration: lambda
          response:
            headers:
              Content-Type: "'application/xml'"
            template: $input.path("$")
            statusCodes:
                200:
                    pattern: '' # Default response method
                    template:
                      # Your script returns json, so match it here
                      application/json: $input.path("$.body")
                    headers:
                      Content-Type: "'application/xml'"

答案 6 :(得分:-2)