2
votes

I am attempting to request access/refresh tokens from Spotify while using Parse Cloud Code and Xcode(swift).

var express = require("express"),
app = express(),
crypto = require('crypto'),
buffer = require('buffer'),
url = require('url');

var config = new Parse.Object("Config");
config.set("client_id", "");
config.set("client_secret", "");
config.set("callback_url", "");
config.set("endpoint", "https://accounts.spotify.com");

var AUTH_HEADER = "Basic " + new buffer.Buffer(config.get("client_id")+ ":" + config.get("client_secret")).toString("base64");

app.use(express.bodyParser());

Parse.Cloud.define("swap", function (req, res) {
if (!req.body || !req.body.hasOwnProperty("code")) {
    res.status(550).send("Permission Denied");
    return;
}

   var form_data = {
    "grant_type": "authorization_code",
    "redirect_uri": config.get("callback_url"),
    "code": req.body.code
};

   Parse.Cloud.httpRequest({
    method: "POST",
    url: url.resolve(config.get("endpoint"), "/api/token"),
    headers: {
        "Authorization": AUTH_HEADER,
        "Content-Type": "application/x-www-form-urlencoded"
    },
    body: form_data,
    success: function(httpResponse) {
        if (httpResponse.status != 200) {
            res.status(550).send("Permission Denied");
            return;
        }

        var token_data = JSON.parse(httpResponse.text);

        res.status(200).set({
            "Content-Type": "application/json"
        }).send(token_data);
    },
    error: function(httpResponse) {
        res.status(500).send("Internal Server Error");
        return;
    }
   });
});

Parse.Cloud.define("refresh", function (req, res) {
if (!req.body || !req.body.hasOwnProperty("refresh_token")) {
    res.status(550).send("Permission Denied");
    return;
}

   var refresh_token = req.body.refresh_token;

   var form_data = {
    "grant_type": "refresh_token",
    "refresh_token": refresh_token
   };

   Parse.Cloud.httpRequest({
    method: "POST",
    url: url.resolve(config.get("endpoint"), "/api/token"),
    headers: {
        "Authorization": AUTH_HEADER,
        "Content-Type": "application/x-www-form-urlencoded"
    },
    body: form_data,
    success: function(httpResponse) {
        if (httpResponse.status != 200) {
            res.status(550).send("Permission Denied");
            return;
        }

        res.status(httpResponse.status).set({
            "Content-Type": "application/json"
        }).send(httpResponse.text);

    },
    error: function(httpResponse) {
        res.status(500).send("Internal Server Error");
        return;
    }
   });

});

Parse.Cloud.define("api/token", function (req, res) {

   res.status(200).set({
    "Content-Type": "application/json"
   });

   switch (req.body.grant_type) {
    case "authorization_code": {
        res.status(200).set({
            "Content-Type": "application/json"
        }).send({
            "refresh_token": "REFRESH TOKEN"
        });
    } break;
    case "refresh_token": {
        res.status(200).set({
            "Content-Type": "application/json"
        }).send({
            "access_token": "ACCESS TOKEN"
        });
    } break;
    default: {
        res.status(550).set({
            "Content-Type": "text/html"
        }).send("<html><body><h1>Access Denied</h1></body></html>");
    } break;
   }
});

app.listen();

Called the function in Xcode with following:

   PFCloud.callFunctionInBackground("swap", withParameters: nil) { (results, error: NSError?) -> Void in
                if error != nil {
                    // Your error handling here
                    print(error)

                } else {
                    // Deal with your results (votes in your case) here.

                    print(results)

                }
            }

I receive the following error:

[Error]: TypeError: Object # has no method 'status' at main.js:29:13 (Code: 141, Version: 1.9.1) Optional(Error Domain=Parse Code=141 "TypeError: Object # has no method 'status' at main.js:29:13" UserInfo={code=141, temporary=0, error=TypeError: Object # has no method 'status' at main.js:29:13, NSLocalizedDescription=TypeError: Object # has no method 'status' at main.js:29:13})

Thanks!

1

1 Answers

1
votes

After dealing with this exact code and trying to get it to work, I finally realized that it is node.js code, not Parse cloud code. If you still want to use it, I suggest reading Parse's documentation on using node.js with Parse. Otherwise, you are better off doing something else like launching Spotify's provided ruby script on Heroku.

If you are feeling more adventurous, you could try and port the code to Parse Cloud code format, but that seemed to be rather difficult