twilio-js icon indicating copy to clipboard operation
twilio-js copied to clipboard

creting accounts does not work

Open zimdo opened this issue 12 years ago • 1 comments

Hey,

I had to patch the to allow it to create accounts. I added the following method... kinda copied from your collectionsMethodsFor


var accountMethodsFor = function() {
    // Helper function for generating resource URI
    var uriFor = function(connect) {
        return util.format('https://%s:%s@%s/%s/Accounts.json', Twilio.AccountSid, Twilio.AuthToken, API_ENDPOINT, API_VERSION);
    };

    // Capitalise param names so use can idomatically pass in camelized
    // param names, e.g. 'fooBar' and have them converted to the format Twilio
    // requires, e.g. 'FooBar'
    var upcaseKeys = function(obj) {
        var dup = {};
        for(var key in obj) {
            if(obj.hasOwnProperty(key)) {
                dup[key.charAt(0).toUpperCase() + key.substring(1)] = obj[key];
            }
        }
        return dup;
    }

    // Generate a callback function and close over the fn variable, so we don't
    // have to deviate from the function signature requests expects while still
    // have the fn variable in scope.
    var callbackFactory = function(fn, list) {
        return function(e, r, body) {
            // Return if no callback function given. User doesn't care about response.
            if(!fn) return;
            // If a 2xx response, pass in response to callback
            body = JSON.parse(body);
            if(!e && Math.floor(r.statusCode / 100) == 2) {
                console.log(fn);
                fn(null, body);
            } else {
                // else pass in an error object
                fn(new Error(body.message), null);
            }
        }
    }

    var requestFactory = function(method, fn, params, list) {
        // remove accountSid and connect from params object
        var accountSid, connect;
        if(params) {
            accountSid = params.accountSid; delete params.accountSid;
            connect    = params.connect;    delete params.connect;
        }

        var opts = {
            uri: uriFor(connect),
            headers: { 'Accept' : 'application/json' }
        }

        // if we're POSTing. Upcase our params and set as form as Twilio expects
        if(method == 'post') opts['form'] = upcaseKeys(params);

        // if we're doing a GET and have params. upcase and append as querystring to uri property
        if(method == 'get' && params) {
            params = upcaseKeys(params)
            var arr = [];
            var qs  = require('querystring');

            for(var key in params) {
                if (params.hasOwnProperty(key)) {
                    arr.push(key + '=' + qs.escape(params[key]));
                }
            }

            // if arr not empty build query string with elements
            if(arr[0]) opts['uri'] = opts.uri + '?' + arr.join('&');
        }

        return request[method](opts, callbackFactory(fn, list));
    }


    return {
        create: function(params, fn) { requestFactory('post', fn, params) }
    }
};

And then when you export the methods you'll use it like.

Account:                 accountMethodsFor(),

I know it's not perfect but I couldn't see how the create accounts stuff would be working otherwise as the URLs don't conform to the scheme you have in collectionMethodsFor.

zimdo avatar Nov 01 '12 18:11 zimdo

Hi, sorry about that. I spotted this shortly after finishing my work on twilio-js. Unfortunately I didn't have time to fix it before leaving Twilio. I'll get to it soon, although it is not a high priority for me.

I don't think your solution is the right way to go; I think the right idea is to use the hyperlinks returned by the Twilio REST API rather than assuming the format. This will require a little bit of work.

stevegraham avatar Nov 03 '12 21:11 stevegraham