Hello,
I’m trying to create a follow button, and I’m having some issues getting my PUT request to succeed. I’m pretty sure that I’m incorrectly setting headers, but I haven’t been able to find where I’m going wrong. I’m sending an asynchronous request, and I’m pretty sure I’m handling that properly, but my code fails upon checking for readystate === 4 && status === 200. I also wanted to note that I included information about Content-Length based on this post: Link to Post. Hopefully someone can point out what I’m doing wrong? I really appreciate it.
P.S. I have tried to send this request with the sdk, but ran into issues. I didn’t want to make this post too long. If that is the simplest way of doing this, I can talk about issues I’m having with that method in a response to this original post.
Here’s my follow function:
function follow(channel)
{
var success = function()
{
// Change color of button to green and change 'Follow' to 'Followed'
document.getElementById("follow-button").innerHTML = "Followed";
document.getElementById("follow-button").className = "btn btn-success btn-lg btn-block";
document.getElementById("follow-button").removeAttribute("onclick");
}
var failure = function(step)
{
// Popup saying 'Something broke, make sure you're logged into twitch.'
//var token = Twitch.getToken();
window.alert("Something went wrong at step: " + step);
}
Twitch.getStatus(function(error, status)
{
if(error) return failure("1");
if(!status.authenticated) return failure("-1");
Twitch.api({method: 'user'}, function(error, user)
{
if(error) return failure("2");
var xmlHttp = new XMLHttpRequest();
var url = "https://api.twitch.tv/kraken/users/" + user.name + "/follows/channels/" + channel;
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState === 4 && xmlHttp.status === 200)
{
success();
}
else
{
failure("3"); // This is the step that my code fails at currently.
}
};
xmlHttp.open('PUT', url, true);
xmlHttp.setRequestHeader("Content-Type", "application/json");
xmlHttp.setRequestHeader("Accept", "application/vnd.twitchtv.v3+json");
xmlHttp.setRequestHeader("Authorization", "OAuth " + Twitch.getToken());
xmlHttp.setRequestHeader("Content-Length", "0");
xmlHttp.send();
});
});
}
I don’t think I’m qualified to answer this, but would this work?
{
if (xmlHttp.readyState==4)
{
var check=xmlHttp.status;
alert(check);
if (check.toString()=="200")
{
success();
}
}
else
{
failure("3"); // This is the step that my code fails at currently.
}
};
Ok so actually thanks for that, readyState eventually hits 4, so when I grab the status I actually get a 401 error, which I think means that I’ve only sent a GET request? I’m thinking that the request is just checking if the user is following that channel, and is returning null or something since the user is not.
Putting .open before onreadystatechange still doesn’t fix the issue (I think that’s the only other thing I needed to try changing from your code?
I saw someplace that
The correct order of calls is:
new XMLHttpRequest
xhr.open()
xhr.onreadystatechange = …
xhr.send()
Ok. I did change that in my code and left it, because I think that actually is the proper way of doing it. I’m pretty sure it’s something to do with my headers.
Apparently a 401 error has to do with me being unauthorized, but that confuses me because I check if I’m authenticated with my code before calling Twitch.api, and I’ve run code to print out the results of Twitch.getToken() to check if I’m getting a valid token.
I have seen some posts about people having issues with the OAuth in the headers(or the other way around), perhaps try dropping it in the URL?
var url = “https://api.twitch.tv/kraken/users/” + user.name + “/follows/channels/” + channel"?oauth_token=["+ Twitch.getToken() + “]”;
See if that works.
This is how you’d do it with the JS SDK. Just make sure you’re using the version on github and not the CDN hosted one.
Twitch.api({
method: 'users/' + user.name + '/follows/channels/' + channel,
verb: 'PUT'
}, function (error, data) {
// ...
});
Hah! See…
3ventic with a good solution.
This is a stupid question but this is the CDN version right?
<script src="https://ttv-api.s3.amazonaws.com/twitch.min.js"></script>
I’ve downloaded the Twitch SDK straight off of github from the repository, but using this downloaded version of twitch.min.js with the same code, I actually am logged out of my authenticated session with twitch and have to re-connect/re-authenticate on my webpage.
Looking at the Makefile, it seems that everything is already built. I don’t have to make the project myself do I? I do have docco & UglifyJS installed on my computer but like I said, it looks like everything’s good to go.
Here’s my code just for reference:
function follow(channel)
{
var success = function()
{
// Change color of button to green and change 'Follow' to 'Followed'
document.getElementById("follow-button").innerHTML = "Followed";
document.getElementById("follow-button").className = "btn btn-success btn-lg btn-block";
document.getElementById("follow-button").removeAttribute("onclick");
}
var failure = function(step)
{
// Popup saying 'Something broke, make sure you're logged into twitch.'
var token = Twitch.getToken();
window.alert("Something went wrong at step: " + token);
}
Twitch.getStatus(function(error, status)
{
if(error) return failure("1");
if(!status.authenticated) return failure("-1");
Twitch.api({method: 'user'}, function(error, user)
{
if(error) return failure("2");
Twitch.api({method: '/users/' + user.name + '/follows/channels/' + channel, verb: 'PUT'}, function(error, response)
{
if(error) return failure(user.name);
success();
});
});
});
}
Oh. My. God. Guys.
I am so sorry for waisting your time. It turns out that I didn’t include ‘user_follows_edit’ in my scope. Seems to be working now.
I really appreciate the help and the time.
I’m glad it’s all sorted out!