Check if a username leads to a valid Twitch user using TwitchIO

140 Views Asked by At

I have a function that receives a string argument, and want to check whether or not the string relates to a valid Twitch user (preferably within the Twitch channel) using the TwitchIO library.

I'll admit, I'm not very familiar with using Python APIs.

Here are the appropriate snippets of code:

async def fight(self, ctx: commands.Context, arg = None):
        if arg == None:
            await ctx.send(f"CHOOSE YOUR OPPONENT! ")
            return

        fighter = "@" + ctx.author.name.lower()
        versus = str(arg).lower()

        valid_contender = self._validate_contender(versus.lstrip("@"))
        print(valid_contender)

...

def _validate_contender(self, versus):
        # return versus if versus is valid twitch user

I've tried several methods to achieve this:

  • TwitchIO allows for searching and storing individual users when starting my bot, but the process of receiving the usernames takes several seconds to a couple of minutes and requires I store them in an array and cross-reference the string argument w/ the array. I may also be using TwitchIO's event_join method incorrectly, since hypothetically I should receive usernames as soon as I start my bot.
  • The closest I've come to achieving a singular validity check w/ a string is declaring my arg as a type User, i.e. def validate(self, arg: User), and responding to the error. While this works to individually check a valid Twitch user, I cannot handle the error using TwitchIO's event_command_error method for some reason. This is either because I am using the wrong method, or checks aren't allowed in the function because the check is performed immediately after evoking.
  • Side-checking using the Helix API to gather information on the user using an HTTP request, which TwitchIO uses. However, it seems like overkill given that TwitchIO already uses the Helix API and I can't help but feel there's an easier way.
  • Using typical commands within TwitchIO, i.e. twitchio.ext.commands.Context.get_user(username), also require I wait a certain number of seconds before receiving appropriate information.

How should I go about verifying the Twitch user via their username, preferably within the chat?

1

There are 1 best solutions below

0
Chris On

Despite being stuck on this for a week, I found the answer a few hours after posting the question.

While using the arg:User technique, which checks for the valid user type, I noticed the error given back was due to a method named 'convert_User' which made use of an in-house 'fetch_users' method. I retrofitted the method within my existing function, and returned the appropriate message instead of the BadError I previously received.

Here's my usable code:

fighter = "@" + ctx.author.name.lower()
versus = str(arg).lower()

user = await ctx.bot.fetch_users(names=[versus.lstrip("@")])
if not user:
    await ctx.send(f"PLEASE CHOOSE VALID CONTENDER! ")
    return

Here's the libraries existing convert_User method:

async def convert_User(ctx: Context, arg: str) -> User:
    """
    Similar to convert_Chatter, but fetches from the twitch API instead,
    returning a :class:`twitchio.User` instead of a :class:`twitchio.Chatter`.
    To use this, you most have a valid client id and API token or client secret
    """
    arg = arg.lstrip("@")
    user = await ctx.bot.fetch_users(names=[arg])
    if not user:
        raise BadArgument(f"User '{arg}' was not found.")
    return user[0]