Hey guys, so I posted on the blizz API forums asking for help and for some reason they deleted my topic there! No idea why and have ticketed the moderators there EDIT it's back up now... In the meantime I thought I'd ask if any of you guys can help - I know that a lot of you out there are developers of one sort or another! :smile:
Angsty rant about modern web development relevant to my plea for help
Basically I learned how to make websites when I was 16. I'm 28 now and coming back into the game after so long not working with websites has been a huge and very steep learning curve. Back then github didn't exist. We were still using CSS 2 and HTML 4. Stack Overflow wasn't even around and Bootstrap certainly wasn't either. phpBB2 was the main forum software alongside vBulletin. We didn't use command line or bower to install JS applications, and they weren't even called applications back then, they were called scripts. Everything has changed so much since then.
The terminology, technology and complexity of everything has increased exponentially and for someone like me who never studied web development professionally as a young man it's like coming back to your home and your family speak a different language. I literally have no idea what people are talking about most of the time. Honestly it's complete gibberish to me and finding very basic information is a huge ballache.
The most frustrating thing about it all? This new generation of developers have forgotten how to make proper documentation. It is rare that you find a script or project that is explained in detail with working examples. People assume that you know so much already - for someone like me trying to learn this stuff it's like decyphering heiroglyphics! Everything has dependencies, which have their own dependencies, which have more dependencies. I don't even know what a 'full stack' developer is but I think you need to be one to actually get anything done with modern frameworks.
This has just been my general experience with learning new things over the last year. Totally and utterly frustrating. When I ask simple questions elsewhere on the web I'm treated like an imbecile because I don't speak the lingo, or don't use git or whaever... so please, take it easy on me okay? :smile: Anyway, sorry - just wanted to vent a bit. I don't want to offend anyone here who possesses these skills and I am not in any way demeaning them in any form. In fact I'm asking for your help!
I'm going to explain to you step by step what I know so far and where I'm stuck. If I have said anything completely wrong please let me know. This is what I want to do (it seems easy but from what I've learned so far it's turning out to be the opposite), and for the sake of simplicity I will make it very specific:
I want to make a request every 15 minutes to the Blizzard API for the realm type of the US realm 'Medivh', and print the result on an HTML page.
I have read all of the official Blizzard API documentation and it is very basic and doesn't really tell you what you need to do. I have like maybe 50% of the knowledge I think I need to make this work so need help connecting the dots. Let's start from the beginning.
I learned from this document that the way to request the realm type of US server Medivh it is to make my 'app' (jQuery script running on a page on my website) make an AJAX request to this URL which has the correct syntax:
https://us.battle.net/api/wow/realm/status?realm=Medivh&jsonp
The bit at the end of the URL - '&jsonp' asks Blizzard's API server to return the results of my 'query' as a 'JSONP' file which my own script can then read or 'parse' - this information I learned from another guide.
I know that a JSONP file is basically like a text file which holds information - in this case - information about the realm US Medivh. Since I haven't actually got it working yet I've never seen this file, but I know from reading further into this doc about the response I would receive that it would probably look something like this:
{
"name":"Medhiv"
"slug":"medhiv",
"type":"PvE",
"type":"Whirlwind",
"status":true,
"queue":false,
"population":"High",
}
The bit I'm interested in retrieving using AJAX in my jQuery script then is the 'property' called "type", which has the data "PvE". However, due to a built-in security feature of AJAX calls like this, I cannot just make this request straight from Blizzard like that. I have to instead work around the issue by getting it, then making an AJAX call to it once it is on my server itself.
]
So the code below should do the trick. As you can see in the AJAX bit - it says 'go to this URL and get the JSONP file'. The bit on the end of it - 'foo' - turns this JSONP response into a jQuery object (this is the workaround I was talking about) which I can then finally print into the <div> node with the ID 'result' on my HTML page.
<script type="text/javascript">
function foo(data) {
$("#result").html(data.type);
}
$(document).ready(
function(){
$.ajax({
url: "https://us.battle.net/api/wow/realm/status?realm=Medivh&jsonp=foo",
type: 'GET',
dataType: 'jsonp'
});
});
</script>
So, this should work right? I run the script on page load or whatever and I should see 'PvE' on my page if the request is successful, right?
Nope
What I get instead is a response header with the code '401'. This is an access denied error - I am not authorised to request this data from the API.
And this my friends is where my troubles really begin.
The way things used to be was you had an API key. Like a secret code given to you by Blizzard, if you will, which you included with your AJAX request. It was pretty simple - you made the request to Blizzard giving them your API key, the Blizzard server says 'ah okay, this API key is correct and we trust you, we'll give you the data' and returned the data for you, which you could then parse and print on your page. Secure enough for a basic thing like getting the status of a realm which is public information, right?
No, that's not good enough apparently. In 2016 they went ham on the whole API and decided that in order to fetch even the most basic, public information from the blizz servers you would have to use a different security protocol called 'Oauth2'.
Oauth2 is very secure, to be sure, but god fucking DAMNIT it it's like a never ending rabbit hole. I have racked the web far and wide for an easy, step-by-step guide to installing AND using Oauth2 to talk to Blizzard servers. Nothing. Like I said in my modern web dev rant at the start, the documentation people have written is awful, scattered all over the place, and always assumes you have all the necessary dependencies and knowledge of those dependencies. Like two sentences in and I'm already like wtf is going on, what the hell is that, why do I need this and how do I get it etc.
I wish it was just a simple fucking API key like it was back then. This guy here made an actual good doc which explained how to do exactly what I want to do (fetch realm status using jQuery and an API key). It's as simple as that. Or should I say, was, because now this method doesn't work anymore due to the introduction of Oauth2.
Anyway - here's what I know so far about Oauth2 and what I need to do to finish this god forsaken API call, in kind-of-human-speak. Let me know if anything I have said is wrong:


And yeah, that's me done I suppose. I am stuck and any help would be appreciated. It's just so complicated. Let's remind ourselves again of what I am trying to achieve here - it's very humble indeed:
I want to make a request every 15 minutes to the Blizzard API for the realm type of the US realm 'Medivh', and print the result on an HTML page.
Why is this so difficult?
Teeb
SentientGypsy Henhouse and anyone else who think they could help.
Unfortunately I don't have experience with Oauth. I'm just simple ASP.NET developer but in your case, I would work around the issue. I'd write a simple web crawler that would collect data from https://worldofwarcraft.com/en-gb/game/status and then store them wherever you want (in some db). Such webcrawler is easy to write in Java and could work in certain time intervals.
That could definitely work - SentientGypsy has already written a few scrapers for barrens.chat with Python and I’m sure this wouldn’t be too hard.
That said, I’d like to be able to make calls to the blizz API directly so I can at some point in the future add more rich features to the site like pulling people’s characters, auction house values etc. I see this as a like way of starting out with something simple.
We use Oauth with Facebook at work, seems it was quick to implement there. I spent a few min on the https://github.com/benweier/blizzard.js what part do you get stuck on? Some dependency problem? If you get the "npm install" part going , step 1 and 2 looks pretty straight forward.
We use Oauth with Facebook at work, seems it was quick to implement there. I spent a few min on the https://github.com/benweier/blizzard.js what part do you get stuck on? Some dependency problem? If you get the "npm install" part going , step 1 and 2 looks pretty straight forward.
Thanks for the response 5bx.
EDIT: I've tried to install it from command line but I get various errors: what do these mean?
teebling$ npm install blizzard.js --save
npm WARN saveError ENOENT: no such file or directory, open '/Users/teebling/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/Users/teebling/package.json'
npm WARN teebling No description
npm WARN teebling No repository field.
npm WARN teebling No README data
npm WARN teebling No license field.
+ blizzard.js@3.0.0
added 8 packages from 12 contributors and audited 8 packages in 3.619s
found 0 vulnerabilities
Also, from their document:
Step 1: require() and initialize() Blizzard.js within your application:const blizzard = require('blizzard.js').initialize({
key: BLIZZARD_CLIENT_ID,
secret: BLIZZARD_CLIENT_SECRET,
});
By putting my client ID and secret in a .JS file surely that would be compromising the security of it since the file is accessible by anyone with a path to it?
The WARN seems to come from the lack of 'npm init' - see https://github.com/visionmedia/debug/issues/261 One user solved it with "Indeed what it wants is a package.json file, obtained by typing npm init. Then I was able to do an npm install with success."
I'll get back to the next question later. :)
The WARN seems to come from the lack of 'npm init' - see https://github.com/visionmedia/debug/issues/261 One user solved it with "Indeed what it wants is a package.json file, obtained by typing npm init. Then I was able to do an npm install with success."
I'll get back to the next question later. :)
Hey,
I typed in npm init and I get this:Teebling:~ teebling$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (teebling) npm install blizzard.js --save
Sorry, name can only contain URL-friendly characters.
I don't really know what this tool wants me to do, nor do I know what a package.json file is for.
I'll get back to the next question later. :)
From the blizz forums:
You don't want to have a jQuery or any kind of javascript doing the request to the API directly. You just can't do that without exposing the API token to the user browser. You have to implement some kind of endpoint on your server to proxy those requests.
Will this js framework (if I ever manage to get it installed lol) create an endpoint to proxy the requests? Or is that something else I'll have to do later?
Have you checked this page - https://develop.battle.net/documentation/guides/getting-started ? See section "Making API requests" there is an example how to retrieve token with a simple curl request, and then making the request - that's usually how I start playing with stuff like this. Then you can quickly see if you can get the responses you're looking for.
About the security aspect and the endpoint I have no idea - I guess you just have to dig into the documentation. But you can save the blizzard.js stuff until later and start with the curl requests first to get started quicker.
Have you checked this page - https://develop.battle.net/documentation/guides/getting-started ? See section "Making API requests" there is an example how to retrieve token with a simple curl request, and then making the request - that's usually how I start playing with stuff like this. Then you can quickly see if you can get the responses you're looking for.
I just tried it with curl in the command line and successfully got a response. It went like this:
Requested an access token
Received access token
Added that access token to the end of my query
Received data I wanted from the server
So that's a start. However, I need this to work on my website, not from me typing into the command line! Hoping this .JS framework will do this for me.
At least you know that you can achieve what you want, that's good. Maybe there's more examples on the blizz dev site - I guess you need to dive in there and try to find something useful.
Few notes that might help:
There are two oauth flows that I see for blizzard APIs:
Authorization Code Flow - Involves setting the redirect uri and is not what you want. I usually think of this as sort of like "login with battle.net" where the authorization is actually passed to the resource provider (Blizzard). The user then gets a notice on oauth.battle.net or whatever it is (the user temporarily leaves your site) saying "hey an application is trying to access your username, wow characters and etc., do you want to allow this? If so go ahead and login and we will send the application back a code they can use to get this info". This is where the redirect uri comes in, battle.net has to know where to send the user (and authorization code) back to on your website. This isn't what you want: its UI driven.
Client Credentials Flow - This is what you want since you aren't looking for any protected endpoints (personal account data etc.). Luckily this is quite simple, you simply tell battle.net you are an authorized application developer using your client id and client secret and then will immediately get back an access token which you send as a header:
Authorization: Bearer {access_token}
to your endpoint:
https://us.api.blizzard.com/wow/realm/status
You should be able to then do this with two ajax requests, the first to get the access token from
https://us.battle.net/oauth/token
and the second to the realm status using the access token. Big problem there though is that your client id and client secret will be visible. So that is a long-winded response only to ask:
Have you considered making a simple PHP wrapper which handles fetching the data and then just spits it out? Just like https://api.barrens.chat/realms which takes care of all of the oauth silliness and then you can just simply request it using ajax?
Here is an example or you could use a fancy oauth library :smile: :
<?php
define ('CLIENT_ID', '');
define ('CLIENT_SECRET', '');
define ('BNET_TOKEN_ENDPOINT', 'https://us.battle.net/oauth/token?grant_type=client_credentials');
define ('BNET_REALMS_ENDPOINT', 'https://us.api.blizzard.com/wow/realm/status');
function request ($url, $headers = []) {
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
$res = curl_exec ($ch);
if (!$res) {
return NULL;
}
return json_decode ($res, true);
}
$credentials = request (BNET_TOKEN_ENDPOINT, [
'Authorization: Basic ' . base64_encode (CLIENT_ID . ':' . CLIENT_SECRET)
]);
$realmsEndpoint = BNET_REALMS_ENDPOINT . '?' . http_build_query ([
'access_token' => $credentials ['access_token']
]);
$realms = request ($realmsEndpoint, [
'Accept: application/json'
]);
var_dump ($realms);
die ();
?>
array(1) {
["realms"]=>
array(246) {
[0]=>
array(10) {
["type"]=>
string(6) "normal"
["population"]=>
string(3) "n/a"
["queue"]=>
bool(false)
["status"]=>
bool(true)
["name"]=>
string(7) "Aegwynn"
["slug"]=>
string(7) "aegwynn"
["battlegroup"]=>
string(9) "Vengeance"
["locale"]=>
string(5) "en_US"
["timezone"]=>
string(15) "America/Chicago"
["connected_realms"]=>
array(5) {
[0]=>
string(11) "daggerspine"
[1]=>
string(10) "bonechewer"
[2]=>
string(9) "gurubashi"
[3]=>
string(6) "hakkar"
[4]=>
string(7) "aegwynn"
}
}
[1]=>
array(10) {
["type"]=>
string(6) "normal"
["population"]=>
string(4) "high"
["queue"]=>
bool(false)
["status"]=>
bool(true)
["name"]=>
string(10) "Aerie Peak"
["slug"]=>
string(10) "aerie-peak"
["battlegroup"]=>
string(11) "Vindication"
["locale"]=>
string(5) "en_US"
["timezone"]=>
string(19) "America/Los_Angeles"
["connected_realms"]=>
array(1) {
[0]=>
string(10) "aerie-peak"
}
}, ...
}
}
Hey teebling, so, I totally understand your frustration. I was also a kid that got started back in the CSS2 days and upon returning to the fray about 5 years ago the amount of tooling and things that had changed was absolutely insane. It's also largely why I sort of left the frontend world. :razz: Technology changes incredibly fast, and the JS world is basically a new universe every year due to how fast it's changing and breaking things. REST has been around a while, but the ways in which people interface with APIs has changed. Cookies, OAuth2, JWT tokens, etc. It changes based on flavors of the month and what people are familiar with.
So Node.js is not a library, it's a runtime built on the V8 engine. To make that easier to understand: you know what PHP does? Nodejs does that -- but uses JavaScript as its language of understanding and compiles that into machine code, whereas PHP goes into C++ and then machine code in order to accomplish what it is doing. You also don't need apache2/nginx to run on top of that like you do for PHP, though many still do for the great benefits of web servers like nginx, but you can in theory just route all your traffic using Node frameworks like Express.
npm is Node Package Manager -- it's like composer is in PHP. So you can't install something with it and use it on a webpage normally -- it goes into the whole Node thing. Since you're using phpBB there's pretty much zero chance you're going to be utilizing Node.js in any way here. This concept took me a while to wrap my head around too when I was just learning this stuff. I couldn't understand how JavaScript was a backend language now... but well... it is, lol. I really dislike it, but some love it.
So, like Anders kindly explained, you can try to accomplish this within phpBB if you have enough experience writing extensions or modifying phpBB a lot -- but I honestly am not sure that's the best idea. That goes a bit outside of the realm of what the forum software should be doing, in my opinion. The best bet is to actually write you own personal API whether in JavaScript, PHP, or Go! and make a simple way to interface it from here with a super simple request. Cache the data in the API to internally update every 15 minutes or so to prevent each request spamming Blizzard. You can then also build upon this and extend it with new features that are then super easy to crunch numbers, do calculations or other misc. stuff and have simple ways to grab it with ajax requests on the forums.
However, it seems that that may go a bit outside what you're familiar with? If you'd like, despite me being a bit busy, I totally don't mind building this for you. I am a backend developer that has a ton of experience building APIs and making integration with 3rd party ones. I would enjoy doing this, and have been looking for an excuse to work with the Blizzard API.
Anders you may be on to something here!
I've been working at this all day and found out some new stuff. Like you say, and I've had some help from other people on this too, the JS option just doesn't work due to the ID/Secret being visible etc. Also my web host don't support node.js (which all the oauth frameworks are dependent on now). So PHP seems like the better option.
I'm going to give your PHP script a try - would be awesome if this worked. Will report back soon :smile: thanks so much for the help so far.
Awesome, as Henhouse said if you want to get more stuff in the future you will need something quite a bit more robust, public api.barrens.chat github??!?! :razz: