Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to send xml response with serverless framework

I'm working with twilio in which when call comes to my twilio number it invokes webhook, I'm using lambda function as webhook,

twilio expects xml(formerly called twiml) response from webhook and i'm unable to send xml response from lambda function

I'm using serverless framework

here is my code function:

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'"

Response: enter image description here enter image description here

please let me know if I'm making some mistake in code also created an issue on github

Thanks, Inzamam Malik

like image 216
Inzamam Malik Avatar asked May 07 '17 08:05

Inzamam Malik


People also ask

Can Lambda return XML?

By default API Gateway and Lambda expect JSON data. It is definitely possible to return XML data, but depending on how you've configured your Lambda integration, it will require different configuration.

Can an REST API be serverless?

Use AWS Lambda to build a Serverless REST API, storing data in S3 and querying it with Athena. We're going to build a Serverless REST API and deploy it on AWS without setting up any server!

Does serverless framework create API gateway?

By default, Serverless creates automatically an API Gateway for each Serverless stack or service (i.e. serverless. yml ) you deploy.

Can Lambda call API gateway?

A Lambda integration maps a path and HTTP method combination to a Lambda function. You can configure API Gateway to pass the body of the HTTP request as-is (custom integration), or to encapsulate the request body in a document that includes all of the request information including headers, resource, path, and method.


2 Answers

You don't need to mess with serverless.yml so much. Here is the simple way:

In serverless.yml...

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

(response, headers, Content-Type, template, and statusCodes are not necessary)

Then you can just set the statusCode and Content-Type in your function.

So delete this part...

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

... and replace it with:

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

callback(null, response);

Lambda proxy integration (which is the default) assembles it into a proper response.

Personally I find this way simpler and more readable.

like image 197
humun Avatar answered Sep 22 '22 02:09

humun


you need your lambda to be a "proxy" type, so you set the body property. but just try to do

context.succeed(twiml.toString());

that will send the "string" as result directly

or use the callback param:

function(event, context, callback) {
   callback(null, twiml.toString())
}
like image 24
UXDart Avatar answered Sep 22 '22 02:09

UXDart