'How do I get mobile status for discord bot by directly modifying IDENTIFY packet?
Apparently, discord bots can have mobile status as opposed to the desktop (online) status that one gets by default.
After a bit of digging I found out that such a status is achieved by modifying the IDENTIFY packet in discord.gateway.DiscordWebSocket.identify modifying the value of $browser to Discord Android or Discord iOS should theoretically get us the mobile status.
After modifying code snippets I found online which does this, I end up with this :
def get_mobile():
"""
The Gateway's IDENTIFY packet contains a properties field, containing $os, $browser and $device fields.
Discord uses that information to know when your phone client and only your phone client has connected to Discord,
from there they send the extended presence object.
The exact field that is checked is the $browser field. If it's set to Discord Android on desktop,
the mobile indicator is is triggered by the desktop client. If it's set to Discord Client on mobile,
the mobile indicator is not triggered by the mobile client.
The specific values for the $os, $browser, and $device fields are can change from time to time.
"""
import ast
import inspect
import re
import discord
def source(o):
s = inspect.getsource(o).split("\n")
indent = len(s[0]) - len(s[0].lstrip())
return "\n".join(i[indent:] for i in s)
source_ = source(discord.gateway.DiscordWebSocket.identify)
patched = re.sub(
r'([\'"]\$browser[\'"]:\s?[\'"]).+([\'"])',
r"\1Discord Android\2",
source_,
)
loc = {}
exec(compile(ast.parse(patched), "<string>", "exec"), discord.gateway.__dict__, loc)
return loc["identify"]
Now all there is left to do is overwrite the discord.gateway.DiscordWebSocket.identify during runtime in the main file, something like this :
import discord
import os
from discord.ext import commands
import mobile_status
discord.gateway.DiscordWebSocket.identify = mobile_status.get_mobile()
bot = commands.Bot(command_prefix="?")
@bot.event
async def on_ready():
print(f"Sucessfully logged in as {bot.user}")
bot.run(os.getenv("DISCORD_TOKEN"))
And we do get the mobile status successfully 
But here's the problem, I wanted to directly modify the file (which held the function) rather than monkey-patching it during runtime. So I cloned the dpy lib locally and edited the file on my machine, it ended up looking like this :
async def identify(self):
"""Sends the IDENTIFY packet."""
payload = {
'op': self.IDENTIFY,
'd': {
'token': self.token,
'properties': {
'$os': sys.platform,
'$browser': 'Discord Android',
'$device': 'Discord Android',
'$referrer': '',
'$referring_domain': ''
},
'compress': True,
'large_threshold': 250,
'v': 3
}
}
# ...
(edited both $browser and $device to Discord Android just to be safe)
But this does not work and just gives me the regular desktop online icon.
So the next thing I did is to inspect the identify function after it has been monkey-patched, so I could just look at the source code and see what went wrong earlier, but due to hard luck I got this error :
Traceback (most recent call last):
File "c:\Users\Achxy\Desktop\fresh\file.py", line 8, in <module>
print(inspect.getsource(discord.gateway.DiscordWebSocket.identify))
File "C:\Users\Achxy\AppData\Local\Programs\Python\Python39\lib\inspect.py", line 1024, in getsource
lines, lnum = getsourcelines(object)
File "C:\Users\Achxy\AppData\Local\Programs\Python\Python39\lib\inspect.py", line 1006, in getsourcelines
lines, lnum = findsource(object)
File "C:\Users\Achxy\AppData\Local\Programs\Python\Python39\lib\inspect.py", line 835, in findsource
raise OSError('could not get source code')
OSError: could not get source code
Code :
import discord
import os
from discord.ext import commands
import mobile_status
import inspect
discord.gateway.DiscordWebSocket.identify = mobile_status.get_mobile()
print(inspect.getsource(discord.gateway.DiscordWebSocket.identify))
bot = commands.Bot(command_prefix="?")
@bot.event
async def on_ready():
print(f"Sucessfully logged in as {bot.user}")
bot.run(os.getenv("DISCORD_TOKEN"))
Since this same behavior was exhibited for every patched function (aforementioned one and the loc["identify"]) I could no longer use inspect.getsource(...) and then relied upon dis.dis which lead to much more disappointing results
The disassembled data looks exactly identical to the monkey-patched working version, so the directly modified version simply does not work despite function content being the exact same. (In regards to disassembled data)
Notes: Doing Discord iOS directly does not work either, changing the $device to some other value but keeping $browser does not work, I have tried all combinations, none of them work.
TL;DR: How to get mobile status for discord bot without monkey-patching it during runtime?
Solution 1:[1]
DiscordWebSocket.identify is non-trivial and there is no supported way to override those fields.
A more maintainable alternative to copy-pasting 35* lines of code to modify 2 lines, is to subclass and then override DiscordWebSocket.send_as_json (4 lines of custom code), and patch the classmethod DiscordWebSocket.from_client to instantiate the subclass:
import os
from discord.ext import commands
from discord.gateway import DiscordWebSocket
class MyDiscordWebSocket(DiscordWebSocket):
async def send_as_json(self, data):
if data.get('op') == self.IDENTIFY:
if data.get('d', {}).get('properties', {}).get('$browser') is not None:
data['d']['properties']['$browser'] = 'Discord Android'
data['d']['properties']['$device'] = 'Discord Android'
await super().send_as_json(data)
DiscordWebSocket.from_client = MyDiscordWebSocket.from_client
bot = commands.Bot(command_prefix="?")
@bot.event
async def on_ready():
print(f"Sucessfully logged in as {bot.user}")
bot.run(os.getenv("DISCORD_TOKEN"))
*39 lines in Pycord 1.7.3. By overriding, you get future updates usually without additional effort.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

