tmijs / tmi.js

đŸ’¬ Javascript library for the Twitch Messaging Interface. (Twitch.tv)
https://tmijs.com
MIT License
1.56k stars 212 forks source link

Twitch 'userstate' object refactoring? #220

Open nathantowell opened 7 years ago

nathantowell commented 7 years ago

In the Twitch userstate object, there's a few keys that contain dashes. These keys cannot be directly referenced in JavaScript because variables and object keys cannot contain the - char.

I propose refactoring the userstate object to use underscores where twitch uses dashes.

I know we can use them as userstate['user-id'], but that's not as clean as userstate.user_id (Both styles could even be included)

{
    badges: { broadcaster: '1', warcraft: 'horde' },
    color: '#FFFFFF',
    display_name: 'Schmoopiie',
    emotes: { '25': [ '0-4' ] },
    mod: true,
    room_id: '58355428',
    subscriber: false,
    turbo: true,
    user_id: '58355428',
    user_type: 'mod',
    emotes_raw: '25:0-4',
    badges_raw: 'broadcaster/1,warcraft/horde',
    username: 'schmoopiie',
    message_type: 'action'
}

This is probably more important now since Twitch has allowed users to change their usernames and we're about to come across the first batch of username releases.

if (userstate.user_id === someStoredUserID) {
  // TODO: Do something if the user's id is the same as the stored id...
}

I would also like to add a broadcaster: Boolean key to the userstate object, derived from the user's badges. This would make it easier to tell if the user is a broadcaster or a moderator of the channel. It would also mean that you can also easily make commands broadcaster only and mod only without all the extra logic:

if (userstate.mod || userstate.broadcaster) {
  // TODO: Allow access to function where the user needs to be a mod or broadcaster to use...
}
// OR
if (userstate.broadcaster) {
  // TODO: Allow access to function where the user needs to be the broadcaster to use...
}

This is a bit of a long shot, but I'd be happy to add these changes and submit a PR myself, but to be honest, I don't really care if this is changed or not... I already have these changes implemented on my own program, it's more of a QoL change than anything else.

AlcaDesign commented 7 years ago

I use a bit of code to change kebab-case to camelCase using lodash:

const _ = require('lodash');
function userObj(user) {
    return _.mapKeys(user, n => _.camelCase(n));
}

client.on('message', (channel, _userstate, message, self) => {
    let userstate = userObj(_userstate);
    /*
        userstate.userId
        userstate.roomId
    */
});

And if you want to roll your own, camelCase would look like:

'user-id'.split('-').reduce((p, n) => p + n[0].toUpperCase() + n.slice(1));
// userId

snake_case:

'user-id'.split('-').join('_');
'user-id'.replace(/-/g, '_');
// user_id
nathantowell commented 7 years ago

I already do something similar to this @AlcaDesign. I just was suggesting that we could have TMI do this for us automatically without having to put in the refactoring code every time we use an event handler. Like I said, it's fine if nobody wants this included into the package.

Schmoopiie commented 7 years ago

Will do something about it but only in v2.0.0. No ETA of course.

gempir commented 6 years ago

2 additional fields could be useful here aswell. The id (for the message) and the tmi-sent-ts for the Timestamp of the message.

Documentation: https://dev.twitch.tv/docs/irc/#privmsg-twitch-tags