Add CreateDiscordThreadBlock for creating Discord threads programmatically

Co-authored-by: bently.lee <bently.lee@agpt.co>
This commit is contained in:
Cursor Agent
2025-08-28 18:28:58 +00:00
parent 82618aede0
commit e10bcc3e02
3 changed files with 221 additions and 1 deletions

View File

@@ -1138,3 +1138,186 @@ class DiscordChannelInfoBlock(Block):
raise ValueError(f"Login error occurred: {login_err}")
except Exception as e:
raise ValueError(f"An error occurred: {e}")
class CreateDiscordThreadBlock(Block):
class Input(BlockSchema):
credentials: DiscordCredentials = DiscordCredentialsField()
channel_id: str = SchemaField(
description="The ID of the channel where the thread will be created"
)
thread_name: str = SchemaField(
description="The name of the thread to create (1-100 characters)"
)
thread_type: str = SchemaField(
description="The type of thread to create",
enum=["public", "private"],
default="public"
)
auto_archive_duration: int = SchemaField(
description="Minutes of inactivity before the thread is automatically archived",
enum=[60, 1440, 4320, 10080],
default=1440
)
initial_message: str = SchemaField(
description="The initial message to send in the thread (optional)",
default="",
advanced=True
)
server_id: str = SchemaField(
description="The ID of the server (guild) - optional, helps ensure correct channel",
default="",
advanced=True
)
class Output(BlockSchema):
status: str = SchemaField(
description="The status of the operation"
)
thread_id: str = SchemaField(
description="The ID of the created thread"
)
thread_name: str = SchemaField(
description="The name of the created thread"
)
channel_id: str = SchemaField(
description="The ID of the channel where the thread was created"
)
server_id: str = SchemaField(
description="The ID of the server where the thread was created"
)
def __init__(self):
super().__init__(
id="c9d5f1a2-7b8e-4c3d-9f2a-1b8e7c3d9f2a",
input_schema=CreateDiscordThreadBlock.Input,
output_schema=CreateDiscordThreadBlock.Output,
description="Creates a new thread in a Discord channel.",
categories={BlockCategory.SOCIAL},
test_input={
"channel_id": "987654321098765432",
"thread_name": "Test Thread",
"thread_type": "public",
"auto_archive_duration": 1440,
"initial_message": "This is the first message in the thread!",
"credentials": TEST_CREDENTIALS_INPUT,
},
test_output=[
("status", "Thread created successfully"),
("thread_id", "123456789012345678"),
("thread_name", "Test Thread"),
("channel_id", "987654321098765432"),
("server_id", "111222333444555666"),
],
test_mock={
"create_thread": lambda *args, **kwargs: {
"status": "Thread created successfully",
"thread_id": "123456789012345678",
"thread_name": "Test Thread",
"channel_id": "987654321098765432",
"server_id": "111222333444555666",
}
},
test_credentials=TEST_CREDENTIALS,
)
async def create_thread(
self,
token: str,
channel_id: str,
thread_name: str,
thread_type: str,
auto_archive_duration: int,
initial_message: str,
server_id: str = None
) -> dict:
intents = discord.Intents.default()
intents.guilds = True
intents.messages = True
client = discord.Client(intents=intents)
result = {}
@client.event
async def on_ready():
print(f"Logged in as {client.user}")
# Get the channel
try:
channel = await client.fetch_channel(int(channel_id))
except Exception as e:
result["status"] = f"Failed to fetch channel: {str(e)}"
await client.close()
return
# Verify it's a text channel
if not hasattr(channel, 'create_thread'):
result["status"] = "Channel does not support thread creation"
await client.close()
return
# Verify server ID if provided
if server_id and str(channel.guild.id) != server_id:
result["status"] = "Channel is not in the specified server"
await client.close()
return
# Create the thread
try:
thread_type_value = discord.ChannelType.public_thread if thread_type == "public" else discord.ChannelType.private_thread
thread = await channel.create_thread(
name=thread_name,
type=thread_type_value,
auto_archive_duration=auto_archive_duration
)
result["status"] = "Thread created successfully"
result["thread_id"] = str(thread.id)
result["thread_name"] = thread.name
result["channel_id"] = str(channel.id)
result["server_id"] = str(channel.guild.id)
# Send initial message if provided
if initial_message:
try:
await thread.send(initial_message)
result["status"] = "Thread created successfully with initial message"
except Exception as e:
result["status"] = f"Thread created but failed to send initial message: {str(e)}"
except Exception as e:
result["status"] = f"Failed to create thread: {str(e)}"
await client.close()
await client.start(token)
return result
async def run(
self, input_data: Input, *, credentials: APIKeyCredentials, **kwargs
) -> BlockOutput:
try:
result = await self.create_thread(
token=credentials.api_key.get_secret_value(),
channel_id=input_data.channel_id,
thread_name=input_data.thread_name,
thread_type=input_data.thread_type,
auto_archive_duration=input_data.auto_archive_duration,
initial_message=input_data.initial_message,
server_id=input_data.server_id if input_data.server_id else None
)
if result.get("status", "").startswith("Failed") or "error" in result.get("status", "").lower():
raise ValueError(result["status"])
yield "status", result["status"]
yield "thread_id", result["thread_id"]
yield "thread_name", result["thread_name"]
yield "channel_id", result["channel_id"]
yield "server_id", result["server_id"]
except discord.errors.LoginFailure as login_err:
raise ValueError(f"Login error occurred: {login_err}")
except Exception as e:
raise ValueError(f"An error occurred: {e}")

View File

@@ -56,6 +56,7 @@ Below is a comprehensive list of all available blocks, categorized by their prim
| [Publish to Medium](medium.md#publish-to-medium) | Publishes content directly to Medium |
| [Read Discord Messages](discord.md#read-discord-messages) | Retrieves messages from Discord channels |
| [Send Discord Message](discord.md#send-discord-message) | Sends messages to Discord channels |
| [Create Discord Thread](discord.md#create-discord-thread) | Creates threads in Discord channels |
## Search and Information Retrieval
| Block Name | Description |

View File

@@ -51,4 +51,40 @@ The block uses a Discord bot to log into a server, locate the specified channel,
| Status | A string indicating the result of the operation (e.g., "Message sent" or "Channel not found") |
### Possible use case
This block could be used as part of an automated notification system. For example, it could send alerts to a Discord channel when certain events occur in another system, such as when a new user signs up or when a critical error is detected.
This block could be used as part of an automated notification system. For example, it could send alerts to a Discord channel when certain events occur in another system, such as when a new user signs up or when a critical error is detected.
---
## Create Discord Thread
### What it is
A block that creates threads in Discord channels using a bot token.
### What it does
This block connects to Discord using a bot token and creates a new thread in a specified channel. It can create both public and private threads with customizable settings.
### How it works
The block uses a Discord bot to authenticate with Discord, find the specified channel, and create a new thread with the provided settings. It can optionally send an initial message to the newly created thread.
### Inputs
| Input | Description |
|-------|-------------|
| Discord Bot Token | A secret token used to authenticate the bot with Discord |
| Channel ID | The ID of the channel where the thread will be created |
| Thread Name | The name of the thread to create (1-100 characters) |
| Thread Type | The type of thread to create (public or private) |
| Auto Archive Duration | Minutes of inactivity before the thread is automatically archived (60, 1440, 4320, or 10080) |
| Initial Message | An optional initial message to send in the thread |
| Server ID | The ID of the server (optional, helps ensure correct channel) |
### Outputs
| Output | Description |
|--------|-------------|
| Status | The status of the operation |
| Thread ID | The ID of the created thread |
| Thread Name | The name of the created thread |
| Channel ID | The ID of the channel where the thread was created |
| Server ID | The ID of the server where the thread was created |
### Possible use case
This block could be used to automatically create discussion threads for specific topics, organize conversations around support tickets, or set up dedicated spaces for project collaborations. For example, when a new project is initiated, the system could automatically create a dedicated thread for team discussions.