0
\$\begingroup\$

I'm writing a Discord bot that sometimes requires a Minecraft account UUID to be looked up so this is the function (and MWE) I have written to do this.

'use strict';

const axios = require('axios');

const EDITION = {
    JAVA: 0,
    BEDROCK: 1,
};

async function getUuid(username, edition) {
    try {
        const result = (edition === EDITION.JAVA)
            ? await axios.get(`https://playerdb.co/api/player/minecraft/${username}`)
            : await axios.get(`https://playerdb.co/api/player/xbox/${username}`);

        const player = result.data.data.player;
        if (player !== undefined) {
            return (edition === EDITION.JAVA)
                ? player.id
                : parseInt(player.id)
                    .toString(16)
                    .padStart(32, '0')
                    .replace(/(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/, '$1-$2-$3-$4-$5');
        }
        return null;
    }
    catch (error) {
        console.error(`Failed to lookup UUID. Reason: ${error.message}`);
        return null;
    }
}

(async () => {
    console.log(await getUuid('somename', EDITION.JAVA));
    console.log(await getUuid('somename1234', EDITION.BEDROCK));
})();

My concern is with the way that I return a Bedrock UUID using str.replace(regexp, newSubstr) I feel like a more efficient RegEx could be used here but I'm unsure how to write it.

Of course, if there's anything else wrong this code, I'd like to know, I'm still rather new to using Node.js.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ It's not generating any new UUIDs, it's looking up existing ones. The only ones that are 'generated' per se are when I convert an Xbox account ID to a UUID. \$\endgroup\$
    – Jake
    Jun 18 at 20:52

1 Answer 1

1
\$\begingroup\$

A general rule to follow when it comes to conditionals is to pull out the one thing that's actually different. In your case, it's really just a segment of the URL. The rest remained the same. So instead, ternary that instead.

const service = edition === EDITION.JAVA ? 'minecraft' : 'xbox'
const result = await axios.get(`https://playerdb.co/api/player/${service}/${username}`)

Same applies to your UUID logic. Splinter off the UUID generating piece into its own function. That way, should this piece of code change implementation, you're not touching the rest of your code. This simplifies your ternary into something like the following:

const player = result.data.data.player
return player === undefined 
  ? null
  : edition === EDITION.JAVA
    ? player.id
    : getUuidFromPlayerId(player.id)

// Then outside getUuid(), define this function.
const getUuidFromPlayerId = id => parseInt(id)
  .toString(16)
  .padStart(32, '0')
  .replace(/(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/, '$1-$2-$3-$4-$5')

I wouldn't worry too much about the regex performance. At this scale, HTTP request latency is probably the bigger concern here, both between your bot and playerdb, and between your bot and Discord. Also watch out for rate limits, services may throttle or outright block your requests if you do them too fast. Make sure your code handles this gracefully.

Also, if you have Node.js 18, native fetch() is available, which removes the need for axios to do HTTP requests.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.