K. Rhoda
K. Rhoda

Reputation: 191

Enable CORS from a Node.JS Callback Function

I'm attempting to use Twilio Functions to handle token generation for my Twilio application. I previously was using a Node.js + Express Server to accomplish this, but I do not know how to figure out enable CORS in this type of environment.
My Client Code looks like this:

$('#new-twilio').click(function(){
        var toNum = this.value;
        if(token == undefined) {
            $.getJSON('https://my-twilio-function/endpoint').done(function(data){
                token = data.token;
                Twilio.Device.setup(token, {debug: true});
                Twilio.Device.ready(function(device){
                    Twilio.Device.connect({"PhoneNumber": toNum});  
                });
            }).fail(function(error){
                alert("Failure!");
                alert(JSON.stringify(error));
            });
        } else {
            Twilio.Device.connect({"PhoneNumber": toNum});
        }
    });


My function code looks like this:

exports.handler = function(context, event, callback) {
    const client = context.getTwilioClient();
    const ClientCapability = require('twilio').jwt.ClientCapability;
    const responseHeaders = {  
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST",
        "Access-Control-Allow-Headers": "content-type, accept",
        "Content-Type": "application/json"
    };
    let identity = "sampleIdentity";
    const capability = new ClientCapability({
      accountSid: context.ACCOUNT_SID,
      authToken: context.AUTH_TOKEN
    });
    capability.addScope(new ClientCapability.IncomingClientScope(identity));
    capability.addScope(new ClientCapability.OutgoingClientScope({
      applicationSid: context.TWILIO_TWIML_APP_SID
    }));
    console.log(capability.toJwt());
    callback(null, {headers: responseHeaders, identity: identity, token: capability.toJwt()});

};
Worth noting, the console.log proves that this function is returning the exact token I need, but I continue to get this error:

XMLHttpRequest cannot load https://my-twilio-function/endpoint. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.


Obviously, my twilio function is at a real URL. As much as I google, I cannot find how to allow access control to this type of node method.

Upvotes: 2

Views: 2551

Answers (3)

Stanislau Buzunko
Stanislau Buzunko

Reputation: 1831

In my case everything above didn't work because i had "Check for valid Twilio signature" checked in my fuction (by default) and made requests without signature.

After I unchecked it, answers above worked. So pay attention to whether you have this checked and if so whether your request has proper signature.

Upvotes: 0

philnash
philnash

Reputation: 73027

Twilio developer evangelist here.

I'm glad to see that K. Rhoda sorted out the issue. I just wanted to make obvious what made it work.

There is a custom response you can access from Twilio.Response within the Function. The response is initialized like:

const response = new Twilio.Response();

and then has the following useful methods:

// set the body of the response
response.setBody(body);

// set a header for the response
response.appendHeader(key, value);

// set all the headers for the response
response.setHeaders(obj);

// set the status code for the response
response.setStatusCode(200);

You can then send that response using the callback function, like so:

callback(null, response);

Upvotes: 2

K. Rhoda
K. Rhoda

Reputation: 191

This client code ended up working:

exports.handler = function(context, event, callback) {
  const client = context.getTwilioClient();
  const ClientCapability = require('twilio').jwt.ClientCapability;
  const response = new Twilio.Response();
  response.appendHeader('Access-Control-Allow-Origin', '*');
  response.appendHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  response.appendHeader('Access-Control-Allow-Headers', 'Content-Type');
  response.appendHeader('Content-Type', 'application/json');
  let identity = "sampleIdentity";
  const capability = new ClientCapability({
    accountSid: context.ACCOUNT_SID,
    authToken: context.AUTH_TOKEN
  });
  capability.addScope(new ClientCapability.IncomingClientScope(identity));
  capability.addScope(new ClientCapability.OutgoingClientScope({
    applicationSid: context.TWILIO_TWIML_APP_SID
  }));
  response.setBody({identity: identity, token: capability.toJwt()})
  console.log(capability.toJwt());
  callback(null, response);
};

Upvotes: 4

Related Questions