Skip to content

Instantly share code, notes, and snippets.

@omkelderman
Last active November 22, 2022 04:49
Show Gist options
  • Save omkelderman/037342ca6612140197d0bb6f19328884 to your computer and use it in GitHub Desktop.
Save omkelderman/037342ca6612140197d0bb6f19328884 to your computer and use it in GitHub Desktop.
osu! api fetch stuff for google scripts
// some sample code, you can change whatever you want starting from here till where it says to not change anything
var ACTIVE_SHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("name of sheet here");
// run this function to trigger all the things
// this sampe code assumes you have a list of user-ids in A2:A and a list of beatmap ids in H2:H
// basically how it works you tell what property of the user or beatmap object you want in which column
function RUN_ALL_THE_THINGS() {
setUserDataOnSheet(ACTIVE_SHEET, 'A2:A', {
username: 'B',
pp_rank: 'C',
country: 'D',
pp_raw: 'E',
playcount: 'F',
});
setBeatmapDataOnSheet(ACTIVE_SHEET, 'H2:H', {
title: 'I',
artist: 'J',
version: 'K',
artist_title: 'L',
artist_title_version: 'M',
});
}
// === set osu! api key here
var OSU_API_KEY = 'API KEY HERE'; // replace with ur own api key
// ===== DO NOT CHANGE ANYTHING BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING!!!!!!!!! ======
var DEFAULT_MAP_SPECIALS = {
artist_title: function(obj) { return obj.artist + ' - ' + obj.title; },
artist_title_version: function(obj) { return obj.artist + ' - ' + obj.title + ' [' + obj.version + ']'; },
};
var DEFAULT_USER_SPECIALS = {
// havent tought of one yet, not sure if you even could think of one that makes sense
};
// helper function to do a http request, expecting an array back (as almost all osu api request do) and returning the first object
function JSONArrayRequestGetFirst(url) {
var response = UrlFetchApp.fetch(url).getContentText('UTF8');
var json = JSON.parse(response);
return json[0];
}
// get user by ID
function osuApiGetUser(userId) {
var url = 'https://osu.ppy.sh/api/get_user?k=' + OSU_API_KEY + '&type=id&u=' + userId;
return JSONArrayRequestGetFirst(url);
}
// get beatmap by ID
function osuApiGetBeatmap(beatmapId) {
var url = 'https://osu.ppy.sh/api/get_beatmaps?k=' + OSU_API_KEY + '&b=' + beatmapId;
return JSONArrayRequestGetFirst(url);
}
/**
* main function for setting user-data on the sheet
* params:
* - sheet: reference to the sheet (duh)
* - userIdRange: a1notation of the input-range containing user-ids (example 'A2:A')
* - output: a javascript object containing which user-api-object-property to map to which column, example:
* {
* 'username': 'B',
* 'pp_rank': 'C'
* }
* this will put the username in column B and the rank in column C.
* for available properties, go to https://osu.ppy.sh/api/get_user?k=APIKEY&type=id&u=USERID in ur browser and take a look at what exists
*/
function setUserDataOnSheet(sheet, userIdRange, output, specials) {
setApiDataOnSheet(sheet, userIdRange, output, Object.assign({}, DEFAULT_USER_SPECIALS, specials), osuApiGetUser);
}
/**
* main function for setting beatmap-data on the sheet
* params:
* - sheet: reference to the sheet (duh)
* - beatmapIdRange: a1notation of the input-range containing beatmap-ids (example 'A2:A')
* - output: a javascript object containing which beatmap-api-object-property to map to which column, example:
* {
* 'title': 'B',
* 'artist': 'C',
* 'version': 'D'
* }
* this will put the username in column B and the rank in column C.
* for available properties, go to https://osu.ppy.sh/api/get_beatmaps?k=APIKEY&b=BEATMAPID in ur browser and take a look at what exists
*/
function setBeatmapDataOnSheet(sheet, beatmapIdRange, output, specials) {
setApiDataOnSheet(sheet, beatmapIdRange, output, Object.assign({}, DEFAULT_MAP_SPECIALS, specials), osuApiGetBeatmap);
}
function getProperyFromObjectOrSpecial(obj, propName, specials) {
if(obj) {
if(obj[propName]) return obj[propName];
if(specials) {
var specialFn = specials[propName];
if(specialFn) return specialFn(obj);
}
}
return undefined;
}
function setApiDataOnSheet(sheet, inputRange, output, specials, apiGetFunction) {
var range = sheet.getRange(inputRange);
var inputValues = range.getValues();
var rowStart = range.getRow();
var outputKeys = Object.keys(output);
if(outputKeys.length == 0) return;
for(var i=0; i<inputValues.length; ++i) {
var currentRow = rowStart + i;
var inputValue = inputValues[i][0];
var id = inputValue ? parseInt(inputValue, 10) : undefined;
if(id) {
try {
var apiObj = apiGetFunction(id);
for(var j=0; j<outputKeys.length; ++j) {
var outputKey = outputKeys[j];
var outputCol = output[outputKey];
var outputValue = getProperyFromObjectOrSpecial(apiObj, outputKey, specials);
sheet.getRange(outputCol + currentRow).setValue(outputValue || '');
}
} catch(e) {
// api error :(
Logger.log('osu api error:')
Logger.log(e);
for(var j=0; j<outputKeys.length; ++j) {
var outputKey = outputKeys[j];
var outputCol = output[outputKey];
sheet.getRange(outputCol + currentRow).setValue('OSU-API-ERROR');
}
}
} else {
// input was either empty or invalid, lets just empty out the output cells
for(var j=0; j<outputKeys.length; ++j) {
var outputKey = outputKeys[j];
var outputCol = output[outputKey];
sheet.getRange(outputCol + currentRow).setValue('');
}
}
}
}
// Object.assign polyfill
if (typeof Object.assign !== 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target === null || target === undefined) {
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource !== null && nextSource !== undefined) {
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment