> ## Documentation Index
> Fetch the complete documentation index at: https://docs.guilt.icu/llms.txt
> Use this file to discover all available pages before exploring further.

# Setting Discord Rich Presence and Activities in alterself

> Set playing, listening, watching, streaming, and custom statuses on your Discord account using alterself's activity helpers and change_presence.

Discord presence lets other users see what you are doing at a glance, whether you are playing a game, listening to music, or streaming live. alterself exposes a `bot.change_presence()` coroutine that accepts a status string and a list of `Activity` objects. Pair it with the built-in activity helper functions and you can build everything from a simple "Playing Chess" status to a fully cycling presence carousel without touching raw JSON.

***

## Status Options

The `status` parameter of `change_presence()` controls the coloured indicator shown next to your avatar. The four accepted values map directly to Discord's own status names.

| Value | Indicator |
| - | - |
| `"online"` | Green dot |
| `"idle"` | Yellow crescent moon |
| `"dnd"` | Red circle (Do Not Disturb) |
| `"invisible"` | Grey dot (appears offline) |

```python theme={null}
# Online
await bot.change_presence(status="online")

# Idle
await bot.change_presence(status="idle")

# Do Not Disturb
await bot.change_presence(status="dnd")

# Invisible (appear offline to others)
await bot.change_presence(status="invisible")
```

***

## Activity Helpers

alterself ships with a set of convenience functions that each return a pre-configured `Activity` object. You pass the result straight into the `activities` list of `change_presence()`.

### Playing

```python theme={null}
await bot.change_presence(activities=[alterself.playing("Chess")])
```

### Streaming

The `url` parameter must be a valid Twitch or YouTube URL for Discord to render the live badge.

```python theme={null}
await bot.change_presence(
    activities=[alterself.streaming("Coding", url="https://twitch.tv/me")]
)
```

### Listening

```python theme={null}
await bot.change_presence(activities=[alterself.listening("Lo-fi beats")])
```

### Watching

```python theme={null}
await bot.change_presence(activities=[alterself.watching("YouTube")])
```

### Competing

```python theme={null}
await bot.change_presence(activities=[alterself.competing("a Hackathon")])
```

### Custom Status

Custom statuses appear below your username and support emoji.

```python theme={null}
await bot.change_presence(activities=[alterself.custom_status("Busy 🔧")])
```

### Fake Spotify

`alterself.spotify()` synthesises a Spotify-style listening activity complete with track progress. Pass Unix millisecond timestamps for `start` and `end` to drive the seek bar.

```python theme={null}
import time

now   = int(time.time() * 1000)
end   = now + 3 * 60 * 1000   # 3 minutes from now

await bot.change_presence(
    activities=[
        alterself.spotify(
            title  = "Midnight City",
            artist = "M83",
            album  = "Hurry Up, We're Dreaming",
            start  = now,
            end    = end,
        )
    ]
)
```

***

## Manual Activity Object

When you need full control over every Rich Presence field (custom artwork keys, match state strings, or a precise start timestamp), construct an `Activity` directly.

```python theme={null}
act = alterself.Activity(
    name        = "My Game",
    kind        = alterself.ActivityKind.PLAYING,
    details     = "In a match",
    state       = "3 kills",
    large_image = "game-logo",
    large_text  = "My Game v2.0",
    small_image = "rank-gold",
    small_text  = "Gold rank",
    start       = 1700000000000,   # Unix ms
)
await bot.change_presence(activities=[act])
```

### ActivityKind values

| Constant | Discord type |
| - | - |
| `ActivityKind.PLAYING` | 0 |
| `ActivityKind.STREAMING` | 1 |
| `ActivityKind.LISTENING` | 2 |
| `ActivityKind.WATCHING` | 3 |
| `ActivityKind.CUSTOM` | 4 |
| `ActivityKind.COMPETING` | 5 |

<Note>
  `large_image` and `small_image` must match the asset keys you uploaded in the Discord Developer Portal for the application ID you registered the Rich Presence under, or be valid `mp:` media-proxy URLs.
</Note>

***

## Presence Cycling

You can rotate through a list of activities on a timed interval by running an `asyncio` background task. The example below cycles through four activities, updating every 60 seconds.

```python theme={null}
import alterself
import asyncio

bot = alterself.Client(token="TOKEN", prefix=".")

ACTIVITIES = [
    alterself.playing("Chess"),
    alterself.listening("Lo-fi beats"),
    alterself.watching("YouTube"),
    alterself.custom_status("Busy 🔧"),
]

async def cycle_presence():
    index = 0
    while True:
        activity = ACTIVITIES[index % len(ACTIVITIES)]
        await bot.change_presence(status="online", activities=[activity])
        index += 1
        await asyncio.sleep(60)

@bot.on_event
async def on_ready():
    print(f"Ready: {bot.me.username}")
    asyncio.create_task(cycle_presence())

bot.run()
```

<Tip>
  Keep the sleep interval at 60 seconds or longer. Updating presence too rapidly can cause Discord to silently drop updates or rate-limit your gateway connection.
</Tip>
