Security News
Supply Chain Attack Detected in @solana/web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
kindred-api
Advanced tools
Kindred is a thin Node.js wrapper on top of Riot Games API for League of Legends
Kindred is a thin Node.js wrapper (with an optional rate limiter) on top of Riot Games API for League of Legends.
Hopefully there aren't too many bugs! I'm a noob after all, so use this library at your own risk. I'm currently working on adding namespaced functions. In addition, I'm heavily focusing on refactoring the code now. The docs are not fully updated yet.
My goal is to make a wrapper that is simple, sensible, and consistent. This project is heavily inspired by psuedonym117's Python wrapper. Look at the Usage Section to see what I mean.
This is my first try at making an API wrapper. I am open to any advice and help!
March 28, 2017
I'm pretty proud of the end result. The rate limiting isn't the best, but it does work and is enforced per region! Also, the method names are kinda iffy (minor inconsistencies), but it works really well for my other project and for when I need a quick script. I'll try to improve this library over the next few weeks.
yarn add kindred-api
// or npm install kindred-api
Make sure to check the official Riot Documentation to see what query parameters you can pass in to each endpoint (through the options parameter)!
Note: All region
parameters are OPTIONAL. All options
parameters are OPTIONAL unless stated otherwise.
var KindredAPI = require('kindred-api')
// var RIOT_API_KEY = require('whatever')
// or if you're using something like dotenv..
require('dotenv').config()
var RIOT_API_KEY = process.env.RIOT_API_KEY
var REGIONS = KindredAPI.REGIONS
/*
Default region for every method call is NA,
but you can set it during initialization as shown below.
You can also change it with 'setRegion(region)' as well.
To NOT use the built-in rate limiter, do NOT pass in anything
into limits.
*/
var k = new KindredAPI.Kindred({
key: RIOT_API_KEY,
defaultRegion: REGIONS.NORTH_AMERICA,
debug: true, // shows status code, urls, and relevant headers
limits: [ [10, 10], [500, 600] ] // user key
// 10 requests per 10 seconds, 500 requests per 10 minutes
// You can just pass in 'dev' or 'prod' instead though.
})
function rprint(err, data) { console.log(data) }
/*
NOTE: Making any form of parameter error will inform you
what parameters you can pass in!
*/
k.getSummoner(rprint)
// getSummoners request FAILED; required params `ids` (array of ints), `id` (int), `names` (array of strings), or `name` (string) not passed in
k.getSummoner(rprint)
// getSummoner request FAILED; required params `id` (int) or `name` (string) not passed in
k.getTopChamps(rprint)
// getTopChamps request FAILED; required params `id` (int) or `playerID` (int) not passed in
k.getChampMastery(rprint)
// getChampMastery request FAILED; required params `playerID` (int) AND `championID` (int) not passed in
/*
Notice the OR and the AND!!
Note: getChampMastery is the only method that can't take in an 'id' parameter,
because it requires both a 'playerID' and a 'championID'!
*/
/*
The first parameter of all endpoint methods will ALWAYS be an object.
However, when the parameters are satisfied by default parameters and/or
only have optional parameters, you can simply pass your callback in.
*/
k.getChallengers(rprint) // default region, default solo queue mode, valid
k.getRuneList(rprint) // only optional arguments & not passing in any optional arguments, valid
/*
getSummoners & getSummoner target both the by-name and by-id endpoints.
In the case of the summoner endpoints, it made a lot more sense for the two
functions to target both the by-name and by-id summoner endpoints.
The example above targets the by-name endpoint, while
the example below targets the by-id endpoint.
*/
k.getSummoner({ id: 354959 }, rprint)
/*
The 'id', 'ids', 'name', and 'names' parameters
stay consistent throughout the API but for the one
exception above. However, I do have aliases for them.
For example, for summoners, you have summonerID, summonerIDs,
playerID, and playerIDs.
Plural parameters can take in both arrays and singular values.
Single parameters, however, can only take singular values.
*/
k.getSummoner({ summonerID: 354959 }, rprint)
k.getSummoner({ summonerID: 354959 })
.then(json => console.log(json))
.catch(err => console.log(err))
k.getSummoners({ summonerIDs: [354959, 21542029] }, rprint)
k.getMatch({ id: 2459973154 }, rprint)
k.getMatch({ matchID: 2459973154 }, rprint)
var names = ['beautifulkorean', 'c9gun', 'caaaaaaaaarIa']
k.getSummoners({ names: names }, rprint)
k.getSummoners({ names: 'caaaaaaaaaria' }, rprint)
k.getSummoners({ name: 'caaaaaaaaaria' }, rprint)
/* Every method has an optional 'region' parameter. */
var options = { name: 'sktt1peanut', region: REGIONS.KOREA }
k.getSummoner(options, rprint) // peanut's data
/* Changing the default region! */
k.setRegion(REGIONS.KOREA)
/* Note that you can use spaces in the name. */
var fakerIgn = { name: 'hide on bush' }
var fakerId
k.getSummoner(fakerIgn, function (err, data) {
/*
But you should sanitize the name if you want to access the dictionary.
{ hideonbush:
{ id: 4460427,
name: 'Hide on bush',
profileIconId: 6,
revisionDate: 1490355284000,
summonerLevel: 30 } }
*/
fakerId = data[fakerIgn.name.replace(/\s/g, '').toLowerCase()].id
console.log('fakerId:', fakerId)
}) // faker's data
/*
Note that the player runes endpoint only accepts
a comma-separated list of integers.
*/
k.setRegion(REGIONS.NORTH_AMERICA)
k.getRunes({ ids: [354959, 21542029] }, rprint)
k.getRunes({ id: 354959 }, rprint)
k.getRunes({ ids: 354959 }, rprint)
k.getRunes({ id: 354959 })
.then(json => console.log(json))
.catch(err => console.error(err))
/*
But what if you want to quickly get the rune pages given
that you have a list of names?
You'd chain it like in many other clients:
Get the ids from the names, get the runes from the ids.
*/
var names2 = ['Richelle', 'Grigne']
k.getSummoners({ names: names2 }, function (err, data) {
var args = []
for (var name of names2)
args.push(data[name.replace(/\s/g, '').toLowerCase()].id)
k.getRunes({ ids: args }, rprint)
})
/* I find that inconvenient, and so I just chain it for you in my code. */
// all methods that target endpoints that only accept ids
k.getRunes({ names: ['Richelle', 'Grigne'] }, rprint)
k.getRunes({ name: 'Richelle' }, rprint)
k.getRecentGames({ name: 'Richelle' }, rprint)
k.getLeagues({ names: ['Richelle', 'Grigne'] }, rprint)
/* Note: I handle that platform id stuffs. */
k.getCurrentGame({ name: 'Fràe', region: REGIONS.OCEANIA }, rprint)
/*
Currently promises are bugged for these type of chained requests
since I don't fully understand them yet. You'll have to chain for promises
still.
*/
var ctzName = 'contractz'
k.getSummoner({ name: ctzName })
.then(json => k.getMasteries({ id: json[ctzName].id }))
.then(json => console.log(json))
/*
Functions will have an options parameter that you can pass in query
strings when applicable. Values of options should match the
endpoint's 'Query Parameters'. Check the methods to see which methods
you can pass in options to.
Some are required, and some are not. I often take care of the ones
that are required by using the most sensible defaults.
For example, the required parameter for many methods is 'type' (of queue).
I made it so that the default is 'RANKED_SOLO_5x5' if 'type' is not passed
in.
*/
k.getChallengers({ region: 'na' }, rprint) // get challengers from ranked solo queue ladder
k.getChallengers({ region: 'na', options: {
type: 'RANKED_FLEX_SR'
}}, rprint) // get challengers from ranked flex ladder
k.getMatch({ id: 2459973154 }, rprint) // includes timeline by default
k.getMatch({ id: 2459973154, options: { includeTimeline: false } }, rprint)
/*
However, for getMatchList, the endpoint uses an optional
'rankedQueues' instead of 'type' to allow multiple options.
I still set the default to RANKED_SOLO_5x5 though.
*/
var name = 'caaaaaaaaaria'
k.getSummoners({ region: 'na', names: name }, function (err, data) {
if (data) {
k.getMatchList({ region: 'na', id: data[name].id, options: {
/*
According to Riot API, query parameters that can accept multiple values
must be a comma separated list (or a single value), which is why I do the above 'join'.
You can also simply do 'RANKED_SOLO_5x5, RANKED_FLEX_SR'.
*/
rankedQueues: ['RANKED_SOLO_5x5', 'RANKED_FLEX_SR'].join(),
championIds: '67' // '267,67' or ['267', '67'].join(',')
} }, rprint)
}
})
var furyMasteryId = 6111
k.getMastery({ id: furyMasteryId }, rprint)
var msRuneId = 10002
k.getRune({ id: msRuneId }, rprint)
Feel free to make a PR regarding anything (even the smallest typo or inconsistency).
There are a few inconsistencies and weird things within this libary that I don't know how to address since this is my first API wrapper and I'm still quite a big newbie.
For example, the two methods getChamp() and getChampion() are actually different.
getChamp() targets the champ endpoint
getChampion() targets the static endpoint
I didn't want to attach getChampion() with 'static' in any way or form since I thought it looked kind of annoying because then I would want to attach static to the other static methods as well (maybe that's better?).
Right now, the code is also quite messy and there is a lot of repeated code. Function definitions are quite long because I include many aliases as well. I haven't thought of an elegant way to make a magic function that manages to work for every single endpoint request yet.
Any help and/or advice is appreciated!
FAQs
Node.js League of Legends v3 API wrapper with built-in rate-limiting (enforced per region, burst/spread, follows retry headers, app/method rate-limiting), caching (in-memory, Redis), automatic retries, and parameter checking.
The npm package kindred-api receives a total of 32 weekly downloads. As such, kindred-api popularity was classified as not popular.
We found that kindred-api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.