Search code examples
pythonpython-3.xdiscorddiscord.pybots

How to show what a user is playing rather than what their status is?


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)."


Solution

  • 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