I am trying to make a bot that will display when a user plays a game for the first time. I am relatively new to Python and especially Discord.py. Instead of doing that though it just displays the status of the user which means it fails when a user has a custom status.
import discord
from discord.abc import GuildChannel
intents = discord.Intents.default()
intents.message_content = True
intents.presences = True
intents.members = True
client = discord.Client(intents=intents)
gameCheck = True
@client.event
async def on_ready():
print(f'We have logged in as {client.user}')
@client.event
async def on_presence_update(before, after):
if after.activity is not None and after.activity.type == discord.ActivityType.playing:
game_name = after.activity.name
print(str(before.name) + " is now playing " + game_name)
system_channel = client.guilds[0].system_channel
if system_channel is not None:
await system_channel.send(str(before.name) + " is now playing " + game_name)
@client.event
async def on_message(message):
global gameCheck
if message.author == client.user:
return
if message.content.startswith('$toggle'):
gameCheck = False if gameCheck == True else True
await message.channel.send('Game check toggled to ' + str(gameCheck))
client.run('TOKEN')
I have tried checking just baseline for the activity type and that doesn't seem to work. It filters out the messages when they update to go online and similar stuff like that but if they have a custom status it just shows that instead of the game. For example, if a user logs on to for say Minecraft but they have a custom status it will read "(User) is now playing (Status)" rather than "(User) is playing (Game)."
I believe the problem is in your on_presence_update event handler. The after.activity might be picking up the first activity in the list, which could be the custom status instead of the game. To fix this issue, you should iterate through all activities in after.activities and check each one to see if it's the wanted type (discord.ActivityType.playing). This way, you can detect when a user starts playing a game, even if they have a custom status.
Here is a quick example of what I would do :
@client.event
async def on_presence_update(before, after):
for activity in after.activities:
if activity.type == discord.ActivityType.playing:
game_name = activity.name
print(f"{before.name} is now playing {game_name}")
system_channel = client.guilds[0].system_channel
if system_channel is not None:
await system_channel.send(f"{before.name} is now playing {game_name}")
break