discord.py-self: Discord.utils throwing error: Info API Down

Summary

Info API Down

Reproduction Steps

opening main.py

Code

[2023-11-08 17:33:33] [INFO    ] discord.client: Logging in using static token.
[2023-11-08 17:33:38] [WARNING ] discord.utils: Info API down. Falling back to manual fetching...
Traceback (most recent call last):
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\main.py", line 12, in <module>
    bot.run('redacted')
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\client.py", line 938, in run
    asyncio.run(runner())
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 664, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\client.py", line 927, in runner
    await self.start(token, reconnect=reconnect)
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\client.py", line 857, in start
    await self.login(token)
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\client.py", line 698, in login
    data = await state.http.static_login(token.strip())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\http.py", line 991, in static_login
    await self.startup()
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\http.py", line 562, in startup
    self.super_properties, self.encoded_super_properties = sp, _ = await utils._get_info(session)
                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\utils.py", line 1446, in _get_info
    bn = await _get_build_number(session)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admin\Desktop\ADVERTISING BOT\discord.py-self\discord\utils.py", line 1478, in _get_build_number
    return int(build_file[build_index : build_index + 6])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'ER_V2_'

Expected Results

its meant to work

Actual Results

its failing idk what else to put here

System Information

  • Python v3.12.0-final
  • discord.py v2.3.2-final
  • aiohttp v3.9.0b0
  • system info: Windows 10 10.0.19045

Checklist

  • I have searched the open issues for duplicates.
  • I have shared the entire traceback.
  • I am using a user token (and it isn’t visible in the code).

Additional Information

No response

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Reactions: 15
  • Comments: 24 (1 by maintainers)

Most upvoted comments

FIX: for util.py

I did not send a pull request, anyone who are interested can do this

async def _get_build_number(session: ClientSession) -> int:
    """Fetches client build number"""
    try:
        login_page_request = await session.get('https://discord.com/login', timeout=7)
        login_page = await login_page_request.text()
        # Find all potential JavaScript files that could contain the build number
        js_files = re.findall(r'assets/([a-z0-9]+)\.js', login_page)
        # Check each JavaScript file for the build number
        for js_file in js_files:
            build_url = f'https://discord.com/assets/{js_file}.js'
            build_request = await session.get(build_url, timeout=7)
            build_file = await build_request.text()
            # Look for 'buildNumber' in the JS file
            build_index = build_file.find('buildNumber') + len('buildNumber') + 2  # Adjusting the offset to after "buildNumber": 
            # Try to extract a six-digit number, assuming that the build number is 6 digits
            possible_build_number = build_file[build_index: build_index + 6]
            # If we find a number, return it
            if possible_build_number.isdigit():
                return int(possible_build_number)
        # If no build number is found in any file, fall back to the hardcoded value
        _log.critical('Could not fetch client build number. Falling back to hardcoded value...')
        return 244594
    except asyncio.TimeoutError as e:
        _log.critical(f'Could not fetch client build number due to timeout: {e}')
        return 244594

Fixed in #596

Also add it to “Releases” and to “PyPi” so to those who install via PIP can use it, I am sure 99% people install via PIP

FIX: for util.py

I did not send a pull request, anyone who are interested can do this

async def _get_build_number(session: ClientSession) -> int:
    """Fetches client build number"""
    try:
        login_page_request = await session.get('https://discord.com/login', timeout=7)
        login_page = await login_page_request.text()
        # Find all potential JavaScript files that could contain the build number
        js_files = re.findall(r'assets/([a-z0-9]+)\.js', login_page)
        # Check each JavaScript file for the build number
        for js_file in js_files:
            build_url = f'https://discord.com/assets/{js_file}.js'
            build_request = await session.get(build_url, timeout=7)
            build_file = await build_request.text()
            # Look for 'buildNumber' in the JS file
            build_index = build_file.find('buildNumber') + len('buildNumber') + 2  # Adjusting the offset to after "buildNumber": 
            # Try to extract a six-digit number, assuming that the build number is 6 digits
            possible_build_number = build_file[build_index: build_index + 6]
            # If we find a number, return it
            if possible_build_number.isdigit():
                return int(possible_build_number)
        # If no build number is found in any file, fall back to the hardcoded value
        _log.critical('Could not fetch client build number. Falling back to hardcoded value...')
        return 244594
    except asyncio.TimeoutError as e:
        _log.critical(f'Could not fetch client build number due to timeout: {e}')
        return 244594

god!

I retraced the action that the utils.py is performing to pull the build number and Discord may have changed the content of the .js file its scraping it from. Here is the relevant snippet that the code is currently pulling which is the source of the error:

DEV_NOTICE_STAGING:"Staging {buildNumber}",NOTIF_CENTER_V2_VIEW_SUMMARY

Looking at the code itself on line 1474:

async def _get_build_number(session: ClientSession) -> int:  # Thank you Discord-S.C.U.M
    """Fetches client build number"""
    try:
        login_page_request = await session.get('https://discord.com/login', timeout=7)
        login_page = await login_page_request.text()
        build_url = 'https://discord.com/assets/' + re.compile(r'assets/+([a-z0-9]+)\.js').findall(login_page)[-2] + '.js'
        build_request = await session.get(build_url, timeout=7)
        build_file = await build_request.text()
        build_index = build_file.find('buildNumber') + 24
        return int(build_file[build_index : build_index + 6])
    except asyncio.TimeoutError:
        _log.critical('Could not fetch client build number. Falling back to hardcoded value...')
        return 9999

The exception handler is only catching asyncio.TimeoutError which means when the integer conversion fails, the whole thing fails.

Using the same .js file that is being evaluated, I found this line of code:

log("[BUILD INFO] Release Channel: ".concat(L,", Build Number: ").concat("244358",", Version Hash: ").concat("c189fc12370cb266be57cc968e278e86f7030f9b")),t.default.setTags({appContext:l.CURRENT_APP_CONTEXT}),S.default.initBasic(),N.default.init(),I.FocusRingManager.init(),O.init(),(0,R.cleanupTempFiles)()},599417:function(e,_,E){"use strict";E.r(_),E.d(_,{default:function(){return r}});var t=E("872717"),o=E("49111"),n=E("782340");class r extends t.default.V8APIError

The number 244358 does align with what Discord is telling me the build number is (and that number appears multiple times in that file near the text “Build Number”), so there are probably two fixes to be made, here:

  1. Extend the error handling to allow for other failures. If it can return a hardcoded value on timeout, why not always allow it?
  2. Add the necessary check to the function to account for both versions of the content: build_index = build_file.find('Build Number') + 25

where should I insert it

Just install the development version here is guide: https://github.com/dolfies/discord.py-self#installing

To install the development version, do the following:

$ git clone https://github.com/dolfies/discord.py-self
$ cd discord.py-self
$ python3 -m pip install -U .