"""List all custom emojis available in a Discord server."""
from __future__ import annotations
import json
import logging
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from tool_context import ToolContext
logger = logging.getLogger(__name__)
TOOL_NAME = "list_server_emojis"
TOOL_DESCRIPTION = (
"Retrieve a JSON list of all custom emotes currently available in "
"a Discord server, including their names, IDs, text format strings, "
"and whether they are animated. Useful for discovering what custom "
"emotes exist so you can reference them by their text format."
)
TOOL_PARAMETERS = {
"type": "object",
"properties": {
"server_id": {
"type": "string",
"description": (
"The Discord server (guild) ID. If omitted, uses "
"the server the message was sent in."
),
},
},
"required": [],
}
[docs]
async def run(
server_id: str | None = None,
ctx: ToolContext | None = None,
) -> str:
"""Return all custom emojis for a guild as JSON.
Args:
server_id: Discord guild ID. Falls back to the context guild.
ctx: Tool execution context.
Returns:
JSON string with the emoji list.
"""
from tools._discord_helpers import require_discord_client
client = require_discord_client(ctx)
if isinstance(client, str):
return client
# Resolve guild
guild = None
if server_id:
try:
guild = client.get_guild(int(server_id))
except ValueError:
return f"Error: Invalid server ID: '{server_id}'."
elif ctx and ctx.server_id:
try:
guild = client.get_guild(int(ctx.server_id))
except (ValueError, TypeError):
pass
if guild is None:
return "Error: Could not resolve a server. Please provide a server_id."
emojis = []
for e in sorted(guild.emojis, key=lambda em: em.name.lower()):
prefix = "a" if e.animated else ""
text_format = f"<{prefix}:{e.name}:{e.id}>"
emojis.append({
"name": e.name,
"id": str(e.id),
"text_format": text_format,
"animated": e.animated,
"available": e.available,
})
return json.dumps({
"server": guild.name,
"server_id": str(guild.id),
"emoji_count": len(emojis),
"emojis": emojis,
}, indent=2)