Skip to content

Latest commit

 

History

History
343 lines (254 loc) · 9.09 KB

File metadata and controls

343 lines (254 loc) · 9.09 KB

Discord RPC

A Python wrapper for the Discord RPC API that allows you to create your own custom Rich Presence.


Installation

pip install discord-rpc

Discord desktop app must be running on the same machine.


Getting Application ID

  1. Go to https://discord.com/developers/applications
  2. Click "New Application" if you don't have application
  3. Insert the name of your application
  4. Copy APPLICATION ID

Quick Start

Step-by-step making simple rich presence using Discord-RPC.

  1. Make sure Discord-RPC is installed.

  2. Import Discord-RPC

    import discordrpc
  3. Make rpc variable from discordrpc.RPC with your unique Application ID.

    rpc = discordrpc.RPC(app_id=1234)
  4. Customizing activity using rpc.set_activity().

    rpc.set_activity(
       state="A super simple rpc",
       details="simple RPC"
    )
  5. Creating loop for rpc so that it can keep running.

    rpc.run()
  6. Done! Run your file.


API Reference

RPC

class RPC:
    def __init__(...): -> None

RPC.__init__

Creates an IPC client and attempts to connect to the local Discord instance.

Parameters:

  • app_id (int) — Your Discord Application (Client) ID.
  • debug (bool, default: False) — If True, enables verbose logging (DEBUG).
  • output (bool, default: True) — If False, silences logger output.
  • exit_if_discord_close (bool, default: True) — If True, raises when Discord is not found or closed.
  • exit_on_disconnect (bool, default: True) — If True, exits the process when the socket disconnects.

Variables:

  • is_running (bool) — Whether the RPC successfully set an activity.
  • try_reconnecting (bool, default: True) — Whether to attempt reconnecting on disconnect.
  • User (cached_property) — Returns a User object populated after handshake (see User).
  • App (cached_property) — Returns an Application object fetched from Discord API (see App).

RPC.set_activity

def set_activity(...): -> Optional[bool]

Sets or updates the current Rich Presence. Returns True on success.

Parameters (all optional unless stated):

  • name (str) — Name of the activity. If not provided, Discord uses the application name by default.
  • details (str) — Upper line of the activity.
  • state (str) — Lower line of the activity.
  • act_type (Activity, default: Activity.Playing) — See Activity Types.
  • status_type (StatusDisplay, default: StatusDisplay.Name) — Which field is considered the status name for some clients.
  • large_image (str) — Key of an uploaded Rich Presence Asset, or an external direct URL.
  • large_text (str) — Tooltip when hovering the large image.
  • large_url (str) — Optional URL for the large image.
  • small_image (str) — Key of a small asset, or an external direct URL.
  • small_text (str) — Tooltip for the small image.
  • small_url (str) — Optional URL for the small image.
  • state_url, details_url (str) — Optional link targets when clicking the text.
  • ts_start, ts_end (int) — Unix timestamps (seconds). See Utils for helpers.
  • party_id (str) — ID to identify a party or session.
  • party_size (list[int, int]) — Current and max size, e.g. [2, 5].
  • join_secret, spectate_secret, match_secret (str) — Secrets for join/spectate/match.
  • buttons (list[dict]) — Up to 2 buttons created by button().
  • clear (bool) — If True, clears the activity.

Notes:

  • act_type must be a types.Activity member; otherwise InvalidActivityType is raised.
  • Activity.Streaming and Activity.Custom are disabled for Rich Presence updates and will raise ActivityTypeDisabled.
  • Images can be an uploaded asset key or an external direct URL (PNG, JPEG, WebP, GIF, AVIF).

RPC.run()

def run(update_every: int = 1, ping_every: int = 15): -> None

Keeps the RPC alive. Not required if another task is running on the same file.

Parameters:

  • update_every (int, default: 1) — Loop sleep interval.
  • ping_every (int, default: 15) — OP_PING heartbeat interval to prevent socket timeout.

RPC.clear()

def clear(): -> None

Clears the current activity without disconnecting.

RPC.disconnect()

def disconnect(): -> None

Closes the IPC socket and marks the client as disconnected.


User

rpc.User  # cached_property, populated after handshake

A lightweight User model.

Attributes:

  • id (int) — Discord user ID.
  • username (str) — Username.
  • name (str) — Global display name.
  • avatar (str) — CDN URL (animated GIF detection supported).
  • bot (bool) — Whether the user is a bot.
  • premium_type (int) — Discord Nitro tier.

Example

import discordrpc
rpc = discordrpc.RPC(app_id=123456789)
print(rpc.User.name)
print(f"@{rpc.User.username}")
rpc.run()

App

rpc.App  # cached_property, lazy-loaded from Discord API

An Application model. The HTTP request is lazy-loaded on first access.

Attributes:

  • id (int) — Application ID.
  • name (str) — Application name.
  • description (str) — Application description.
  • icon (str) — CDN URL to the application icon.
  • verified (bool) — Whether the application is verified.
  • public (bool) — Whether the bot is public.

Buttons

from discordrpc import button
button(text: str, url: str) -> dict

Creates a Discord-compatible button payload (max 2 buttons).

Parameters:

  • text (str) — Button label.
  • url (str) — Must start with http:// or https://. Raises InvalidURL otherwise.

Example

import discordrpc
from discordrpc import button

rpc = discordrpc.RPC(app_id=123456789)
rpc.set_activity(
    state="Made by Senophyx",
    details="Discord-RPC",
    buttons=[
        button("Repository", "https://github.com/Senophyx/discord-rpc"),
        button("Discord", "https://discord.gg/qpT2AeYZRN"),
    ]
)
rpc.run()

Utils

from discordrpc import utils

utils.timestamp

timestamp -> int

Returns the current time in epoch timestamp.

utils.date_to_timestamp

def date_to_timestamp(date: str) -> int

Converts %d/%m/%Y-%H:%M:%S format to epoch timestamp.

utils.use_local_time

def use_local_time() -> dict

Returns a ts_start payload starting from midnight today.

utils.progress_bar

def progress_bar(current: int, duration: int) -> dict

Returns ts_start and ts_end based on progress. Raises ProgressbarError if current > duration.

utils.get_app_info

def get_app_info(app_id: int) -> dict

Fetch application info from Discord API without initializing RPC.


Activity Types

from discordrpc import Activity
  • Activity.Playing (0)
  • Activity.Streaming (1) — disabled for RPC
  • Activity.Listening (2)
  • Activity.Watching (3)
  • Activity.Custom (4) — disabled for RPC
  • Activity.Competing (5)

Status Display Types

from discordrpc import StatusDisplay
  • StatusDisplay.Name (0)
  • StatusDisplay.State (1)
  • StatusDisplay.Details (2)

Exceptions

All exceptions extend RPCException.

Exception Description
RPCException Base exception
Error(message) Generic user error
DiscordNotOpened() Discord not found/running
ActivityError() Invalid activity payload
InvalidURL() URL not starting with http/https
InvalidID() Invalid Application ID
ButtonError(message) Button limit exceeded
ProgressbarError(message) Invalid progress values
InvalidActivityType(message) act_type not a valid Activity
ActivityTypeDisabled() Streaming/Custom blocked by Discord

Troubleshooting

  • "Discord is closed" — Ensure desktop app is running. On Linux, check $XDG_RUNTIME_DIR / tmp/discord-ipc-*.
  • ActivityTypeDisabled — Use Playing, Listening, Watching, or Competing instead.
  • Buttons don't show — Max 2 buttons, URLs must start with http:// or https://.
  • No images appear — Upload assets to Discord Developer Portal Art Assets section.
  • App exits on disconnect — Set exit_on_disconnect=False.
  • Silence logs — Pass output=False.

FAQ

Q: Do I need a bot token?
A: No. Only an Application ID.

Q: Can I update presence from a server?
A: No. This is client-side IPC, Discord must run on the same machine.

Q: Can I use Streaming or Custom activity?
A: No, those types are disabled and raise ActivityTypeDisabled.


Links

Licence

MIT License
Copyright (c) 2021-2025 Senophyx