"""Create a Discord server invite link."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from tool_context import ToolContext
logger = logging.getLogger(__name__)
TOOL_NAME = "discord_invite"
TOOL_DESCRIPTION = (
"Create an invite link for a Discord channel."
)
TOOL_PARAMETERS = {
"type": "object",
"properties": {
"channel_id": {
"type": "string",
"description": (
"Channel to create the invite for. Uses the "
"current channel if not specified."
),
},
"max_age": {
"type": "integer",
"description": (
"Invite duration in seconds. "
"0 = never expires. Default 86400 (24h)."
),
},
"max_uses": {
"type": "integer",
"description": (
"Max number of uses. 0 = unlimited. Default 0."
),
},
"temporary": {
"type": "boolean",
"description": (
"Grant temporary membership. Default false."
),
},
},
"required": [],
}
[docs]
async def run(
channel_id: str | None = None,
max_age: int = 86400,
max_uses: int = 0,
temporary: bool = False,
ctx: ToolContext | None = None,
) -> str:
"""Execute this tool and return the result.
Args:
channel_id (str | None): Discord/Matrix channel identifier.
max_age (int): The max age value.
max_uses (int): The max uses value.
temporary (bool): The temporary value.
ctx (ToolContext | None): Tool execution context providing access to bot internals.
Returns:
str: Result string.
"""
import discord
from tools._discord_helpers import (
require_discord_client,
get_channel,
)
client = require_discord_client(ctx)
if isinstance(client, str):
return client
cid = channel_id or (ctx.channel_id if ctx else "")
if not cid:
return "Error: No channel_id provided or available."
channel = await get_channel(client, cid)
if isinstance(channel, str):
return channel
if not hasattr(channel, "create_invite"):
return (
f"Error: Channel '{cid}' does not support invites."
)
try:
invite = await channel.create_invite(
max_age=max_age,
max_uses=max_uses,
temporary=temporary,
)
parts = [f"Invite created: {invite.url}"]
if max_age == 0:
parts.append("Expires: Never")
else:
h = max_age // 3600
m = (max_age % 3600) // 60
parts.append(f"Expires in: {h}h {m}m")
if max_uses == 0:
parts.append("Uses: Unlimited")
else:
parts.append(f"Max uses: {max_uses}")
return "\n".join(parts)
except discord.errors.Forbidden:
return "Error: No permission to create invites."
except Exception as exc:
return f"Error creating invite: {exc}"