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

# Browser Fingerprint Spoofing in alterself Selfbots

> Understand how alterself's SpoofEngine synthesises a consistent browser fingerprint, manages build numbers, and mimics real Chrome client behaviour.

Discord's backend cross-references dozens of signals: user-agent strings, locale, timezone, installation UUIDs, client build numbers, and more, to distinguish legitimate browser sessions from automated ones. alterself's `SpoofEngine` generates a self-consistent fingerprint for every token and injects it into every gateway connection and HTTP request automatically. You rarely need to touch it directly, but understanding how it works helps you debug unexpected authentication failures and tailor the fingerprint when needed.

***

## How Identity Is Seeded

Rather than generating a random fingerprint on every run, `SpoofEngine` derives its values deterministically from a hash of your token. This seeded approach means the same token always produces the same locale, timezone, and installation UUIDs, making your sessions look like a stable, returning browser to Discord's systems.

<Steps>
  <Step title="Token hash">
    When you call `alterself.Client(token=...)`, the engine MD5-hashes your token and uses the digest as the seed for an internal RNG.
  </Step>

  <Step title="Profile generation">
    The seeded RNG picks a consistent locale (e.g. `en-US`), timezone (e.g. `America/New_York`), and a set of stable UUIDs for the installation and session identifiers.
  </Step>

  <Step title="READY rotation">
    When Discord dispatches the `READY` event, the engine rotates the session-level UUIDs while keeping the token-bound values (locale, timezone, installation ID) stable, matching how a real browser behaves across page refreshes.
  </Step>
</Steps>

<Note>
  The same token always produces the same fingerprint across restarts. If you switch tokens, you get a completely different but equally stable fingerprint for that token.
</Note>

***

## Chrome Version Resolution

alterself needs a realistic Chrome version string for the `User-Agent` header and `X-Super-Properties`. It resolves the version through a layered strategy:

1. **Live fetch** — queries Google's `versionhistory.googleapis.com` API for the latest stable Chrome release.
2. **Disk cache** — if the API is unreachable, reads a previously cached version from disk.
3. **Hardcoded fallback** — if both of the above fail, uses `"136"` as a safe default.

This means your bot always presents a plausible, up-to-date Chrome version without requiring you to maintain it manually.

***

## Build Number Resolution

Discord's `X-Super-Properties` header must contain the correct client build number or the gateway will reject the connection. alterself resolves it through its own layered strategy:

1. **Live scrape** — fetches Discord's login page and extracts the build number from the bundled JavaScript.
2. **Memory cache** — caches the scraped value in memory for one hour to avoid repeated scrapes.
3. **Disk cache** — persists the value to disk so it survives restarts.
4. **Hardcoded fallback** — if all of the above fail, uses `612808`.

### Manual Build Refresh

If you suspect the cached build number is stale (for example, after a Discord client update), you can force a fresh scrape:

```python theme={null}
bot._spoof.refresh_build()
```

Call this before `bot.run()` or inside an `on_ready` handler. The engine will scrape Discord's login page immediately and update both the memory and disk caches.

***

## X-Super-Properties

Every HTTP request and the gateway `IDENTIFY` payload includes an `X-Super-Properties` header. Discord uses it to verify that your client looks like a real browser. alterself constructs it automatically from the generated profile.

The header is a base-64-encoded JSON object containing fields such as:

| Field | Description |
| - | - |
| `os` | Operating system (e.g. `"Windows"`) |
| `browser` | Always `"Chrome"` |
| `device` | Empty string (desktop) |
| `system_locale` | Locale derived from token seed (e.g. `"en-US"`) |
| `has_client_mods` | Always `false` |
| `browser_user_agent` | Full Chrome UA string |
| `browser_version` | Resolved Chrome version |
| `os_version` | Windows build string |
| `referrer` | Simulated referrer URL |
| `referring_domain` | Simulated referring domain |
| `referrer_current` | Current-page referrer |
| `referring_domain_current` | Current-page referring domain |
| `release_channel` | `"stable"` |
| `client_build_number` | Resolved Discord build number |
| `client_event_source` | `null` |
| `client_launch_id` | Per-launch identifier UUID |
| `launch_signature` | Signature tied to the launch |
| `client_app_state` | `"focused"` or `"unfocused"` |
| `client_heartbeat_session_id` | Session-level heartbeat UUID |

You never need to set these fields manually. The engine serialises and encodes the header for every request.

***

## App State Tracking

Discord expects the client to report whether its window is currently focused. alterself tracks this with `set_state()`, which updates the `client_app_state` field sent in presence updates.

```python theme={null}
bot._spoof.set_state(focused=True)   # client_app_state = "focused"
bot._spoof.set_state(focused=False)  # client_app_state = "unfocused"
```

You might call this inside a command handler to simulate the user switching away from Discord while a long task runs.

***

## Spoof Info Command

This command prints the active fingerprint at runtime. It is useful for verifying that the engine is working correctly or for debugging authentication errors.

```python theme={null}
@bot.command(aliases=["whoami"])
async def spoof(ctx):
    s = ctx.client._spoof
    await ctx.reply(
        f"**Fingerprint**\n"
        f"UA: `{s.profile.user_agent}`\n"
        f"Locale: `{s.profile.locale}` / TZ: `{s.profile.tz}`\n"
        f"Build: `{s.build_number}`\n"
        f"Installation ID: `{s._installation_id}`"
    )
```

Invoke it with `.spoof` (or `.whoami`) to see the exact values being sent to Discord on every request.
