Adds latency display and improves bot configuration

Adds millisecond latency property to gateway and client for more precise monitoring.

Enhances ping command to display gateway latency for better debugging.

Configures message content intent and mention replies for improved bot functionality.

Adds dotenv support for cleaner environment variable management.

Formats error classes for better code consistency and readability.
This commit is contained in:
Slipstream 2025-06-11 15:13:37 -06:00
parent a702c66603
commit 3c638d17ce
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD
6 changed files with 290 additions and 6 deletions

View File

@ -38,6 +38,8 @@ import os
import disagreement
from disagreement.ext import commands
from dotenv import load_dotenv
load_dotenv()
class Basics(commands.Cog):
@ -46,18 +48,17 @@ class Basics(commands.Cog):
@commands.command()
async def ping(self, ctx: commands.CommandContext) -> None:
await ctx.reply("Pong!")
await ctx.reply(f"Pong! Gateway Latency: {self.client.latency_ms} ms.") # type: ignore (latency is None during static analysis)
token = os.getenv("DISCORD_BOT_TOKEN")
if not token:
raise RuntimeError("DISCORD_BOT_TOKEN environment variable not set")
client = disagreement.Client(token=token, command_prefix="!")
client.add_cog(Basics(client))
intents = disagreement.GatewayIntent.default() | disagreement.GatewayIntent.MESSAGE_CONTENT
client = disagreement.Client(token=token, command_prefix="!", intents=intents, mention_replies=True)
async def main() -> None:
client.add_cog(Basics(client))
await client.run()

View File

@ -412,6 +412,13 @@ class Client:
return self._gateway.latency
return None
@property
def latency_ms(self) -> Optional[float]:
"""Returns the gateway latency in milliseconds, or ``None`` if unavailable."""
if self._gateway:
return self._gateway.latency_ms
return None
async def wait_until_ready(self) -> None:
"""|coro|
Waits until the client is fully connected to Discord and the initial state is processed.

File diff suppressed because it is too large Load Diff

View File

@ -621,6 +621,13 @@ class GatewayClient:
return None
return self._last_heartbeat_ack - self._last_heartbeat_sent
@property
def latency_ms(self) -> Optional[float]:
"""Returns the latency between heartbeat and ACK in milliseconds."""
if self._last_heartbeat_sent is None or self._last_heartbeat_ack is None:
return None
return (self._last_heartbeat_ack - self._last_heartbeat_sent) * 1000
@property
def last_heartbeat_sent(self) -> Optional[float]:
return self._last_heartbeat_sent

View File

@ -0,0 +1,41 @@
# Example from the README file of the disagreement library
# This example demonstrates a simple bot that responds to the "!ping" command with "Pong!".
import asyncio
import os
import disagreement
from disagreement.ext import commands
from dotenv import load_dotenv
load_dotenv()
class Basics(commands.Cog):
def __init__(self, client: disagreement.Client) -> None:
super().__init__(client)
@commands.command()
async def ping(self, ctx: commands.CommandContext) -> None:
await ctx.reply(f"Pong! Gateway Latency: {self.client.latency_ms} ms.") # type: ignore (latency is None during static analysis)
token = os.getenv("DISCORD_BOT_TOKEN")
if not token:
raise RuntimeError("DISCORD_BOT_TOKEN environment variable not set")
intents = (
disagreement.GatewayIntent.default() | disagreement.GatewayIntent.MESSAGE_CONTENT
)
client = disagreement.Client(
token=token, command_prefix="!", intents=intents, mention_replies=True
)
async def main() -> None:
client.add_cog(Basics(client))
await client.run()
if __name__ == "__main__":
asyncio.run(main())

View File

@ -19,6 +19,7 @@ def http_client():
# Using a real session and patching the request method is more robust
client = HTTPClient(token="fake_token")
yield client
# Cleanup: close the session after the test
# This requires making the fixture async or running this in an event loop
async def close_session():