brawlhalla-api
Version:
Node.js wrapper for the Brawlhalla API.
238 lines (214 loc) • 7.85 kB
JavaScript
const request = require("request"),
parseXML = require("xml2js").parseString,
urlValidator = require("url-validator");
const legends = new Map();
const legendSummaries = new Map();
const weapons = [];
const BrawlhallaApi = function(api_key = null) {
/* Static Data */
this.legends = legends;
this.legendSummaries = legendSummaries;
this.weapons = weapons;
this.regions = {
"us-e": "atl",
"us-w": "cal",
"eu": "ams",
"sea": "sgp",
"aus": "aus",
"brz": "brs",
"jpn": "jpn"
};
/* API Calls */
this.callApi = function(call, params = {}) {
let self = this;
if (this.api_key) {
return new Promise(function(fulfill, reject) {
params.api_key = self.api_key;
let urlParams = Object.keys(params).map((key) => (encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))).join('&');
let url = "https://api.brawlhalla.com" + call + "?" + urlParams;
if (url) {
request({url: url, encoding: "utf8"}, function(error, response, body) {
if (!error && response && response.statusCode == 200) {
try {
body = JSON.parse(body);
if (body.error) {
console.log(`${call}: ${body.error.code} - ${body.error.message}`);
reject(body);
} else fulfill(body);
} catch(e) { console.error(`${call}: ${e}`); fulfill({}); }
} else if (response && [404, 503].includes(response.statusCode)) reject(JSON.parse(body));
else reject(error);
});
} else reject("Bad api call");
});
} else return Promise.reject("The API wrapper has not been initialized with an API key.");
};
this.getSteamId = function(profileUrl) {
return new Promise(function(fulfill, reject) {
//let test = /^((http(s?):\/\/)?(www\.)?steamcommunity\.com\/(id|profiles)\/(\S+))/i;
let test = /(steamcommunity\.com\/(id|profiles)\/([^\s\/]+))/i;
let match = test.exec(profileUrl);
if (match) {
let url = urlValidator("https://" + match[0] + "?xml=1");
if (url) {
request(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
parseXML(body, function(err, result) {
if (!err) {
if (result.profile && result.profile.steamID64) {
let steamId = {
name: result.profile.steamID[0],
id: result.profile.steamID64[0],
profile: "https://steamcommunity.com/profile/" + result.profile.steamID64
};
fulfill(steamId);
} else reject("Not a valid Steam profile.");
} else reject(err);
});
} else reject(error);
});
} else reject("Not a valid Steam profile.");
} else reject("Not a valid Steam profile.");
});
};
this.getBhidBySteamId = function(steamId) {
let self = this;
if (typeof steamId !== "string") return Promise.reject(new Error("Steam ID must be provided as a string."));
else return new Promise(function(fulfill, reject) {
let params = {};
params.steamid = steamId;
self.callApi("/search", params).then(function(response) {
if ((response.length > 0) || response.brawlhalla_id) {
response.profile = "https://steamcommunity.com/profiles/" + steamId;
response.steamId = steamId;
}
fulfill(response);
}, reject);
});
};
this.getBhidBySteamUrl = function(profileUrl) {
let self = this;
return new Promise(function(fulfill, reject) {
self.getSteamId(profileUrl).then((steamId) => {
let params = {};
params.steamid = steamId.id;
self.callApi("/search", params).then((response) => {
if (response.length > 0 || response.brawlhalla_id) {
response.profile = steamId.profile;
response.steamId = steamId.id;
};
fulfill(response);
}).catch(reject);
}).catch(reject);
});
};
this.getPlayerStats = function(bhid) {
let self = this;
if (!bhid) return Promise.reject(new Error("No Brawlhalla Id provided."));
else if (typeof bhid !== "string") return Promise.reject(new Error("Brawlhalla ID must be provided as a string."));
else {
// /player/{bhid}/stats
return new Promise(function(fulfill, reject) {
self.callApi(`/player/${encodeURIComponent(bhid)}/stats`).then(fulfill, reject);
});
};
};
this.getPlayerRanked = function(bhid) {
let self = this;
if (!bhid) return Promise.reject(new Error("No Brawlhalla Id provided."));
else if (typeof bhid !== "string") return Promise.reject(new Error("Brawlhalla ID must be provided as a string."));
else {
// /player/{bhid}/ranked
return new Promise(function(fulfill, reject) {
self.callApi(`/player/${encodeURIComponent(bhid)}/ranked`).then(fulfill, reject);
});
}
};
this.getLegendInfo = function(legendId) {
let self = this;
if (legendId) {
if (typeof(legendId) === "string") legendId = legendId.toLowerCase();
if (self.legends.has(legendId)) return Promise.resolve(self.legends.get(legendId));
else if (!self.legendSummaries.has(legendId)) return Promise.resolve(null);
else {
return new Promise(function(fulfill, reject) {
let id = self.legendSummaries.get(legendId).legend_id;
self.callApi(`/legend/${id}`).then((legend) => {
if (!Array.isArray(legend)) {
self.legends
.set(legend.legend_id, legend)
.set(legend.legend_name_key.toLowerCase(), legend)
.set(legend.bio_name.toLowerCase(), legend);
}
fulfill(legend);
}).catch(reject);
});
}
} else return Promise.reject("No Legend Id provided.");
};
this.getLegendByName = this.getLegendInfo;
this.getClanStats = function(clanId) {
let self = this;
// /clan/{clanid}
if (!clanId) return Promise.reject(new Error("No Clan Id provided."));
else if (typeof clanId !== "string") return Promise.reject(new Error("Clan ID must be provided as a string."));
else {
return new Promise(function(fulfill, reject) {
self.callApi(`/clan/${clanId}`).then(fulfill, reject);
});
}
};
this.getRankings = function(boards = {}) {
let self = this;
let options = {
"bracket": "1v1",
"region": "all",
"page": 1
};
for (x in boards) {
options[x] = boards[x];
}
let params = {};
if (options.name) { params.name = options.name; }
return new Promise(function(fulfill, reject) {
self.callApi(`/rankings/${encodeURIComponent(options.bracket)}/${encodeURIComponent(options.region)}/${encodeURIComponent(options.page)}`, params).then(fulfill, reject);
});
};
this.getBhidByName = function(name) {
let self = this;
if (name) {
return new Promise(function(fulfill, reject) {
self.callApi(`/rankings/1v1/all/1`, {name: name}).then((users) => {
let results = users.filter(u => decodeURIComponent(escape(u.name)).toLowerCase() == name.toLowerCase());
fulfill(results);
}, reject);
});
} else Promise.reject("No name provided.");
};
this.key = function(api_key) {
if (api_key && (api_key != this.api_key)) {
this.api_key = api_key;
this.updateLegends();
}
};
this.updateLegends = function() {
return new Promise(function(fulfill, reject) {
let self = this;
self.callApi("/legend/all").then(legends => {
self.legends.set("all", legends);
legends.forEach(legend => {
self.legendSummaries
.set(legend.legend_name_key, legend)
.set(legend.legend_id, legend)
.set(legend.bio_name, legend);
if (!self.weapons.includes(legend.weapon_one)) self.weapons.push(legend.weapon_one);
if (!self.weapons.includes(legend.weapon_two)) self.weapons.push(legend.weapon_two);
});
fulfill(self.legendSummaries);
}, reject);
});
};
this.key(api_key);
return this;
};
module.exports = BrawlhallaApi;