Skip to main content
The Discord Poster module publishes the winning agent’s artifact to a Discord channel during the Dream Awakening phase. It uses Discord webhooks for simple, bot-free integration.

Overview

The module handles:
  • Posting formatted content to Discord channels
  • Automatic message splitting for long content (2000 char limit)
  • Custom webhook username and avatar
  • Winner announcements with header formatting
  • Rate limiting and error handling
No Discord bot required! Just create a webhook in your channel settings and add the URL to your environment.

Configuration

Environment Variables

DISCORD_WEBHOOK_URL
string
required
Your Discord webhook URL (format: https://discord.com/api/webhooks/...)

Setup Instructions

  1. Navigate to your Discord channel
  2. Click the gear icon (Edit Channel)
  3. Go to Integrations β†’ Webhooks
  4. Click New Webhook
  5. Copy the webhook URL
  6. Add to your .env file:
    DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN
    

Configuration Functions

"""Get Discord webhook URL from environment.

Returns:
    Optional[str]: Webhook URL if valid, None otherwise
"""

Core Functions

post_to_discord

Post raw content to Discord via webhook.
def post_to_discord(
    content: str,
    username: str = "Dream Foundry",
    avatar_url: Optional[str] = None,
) -> tuple[bool, str]:

Parameters

content
string
required
The message content to post. Supports Discord markdown formatting.Automatically splits into multiple messages if exceeds 2000 characters.
username
string
default:"Dream Foundry"
Display name shown for the webhook message
avatar_url
string
Optional URL for the webhook avatar image

Returns

success
boolean
True if all messages posted successfully, False otherwise
message
string
Success message with message count, or error description

Example

from src.discord_poster import post_to_discord

success, message = post_to_discord(
    content="πŸŽ‰ The Dream Foundry competition is complete!",
)

if success:
    print(message)  # "Posted to Discord (1 message)"
else:
    print(f"Error: {message}")

Message Splitting

Discord has a 2000 character limit per message. The function automatically:
  1. Splits long content by event blocks (marked with **Title**)
  2. Ensures each chunk is under 1900 characters (safety margin)
  3. Posts multiple messages with 0.5 second delay between them
  4. Maintains block integrity (doesn’t split mid-event)
# Long content (3500 chars)
long_content = "..." * 500

# Automatically split into 2 messages
success, msg = post_to_discord(long_content)
print(msg)  # "Posted to Discord (2 messages)"

post_winner_announcement

Post a formatted winner announcement with header and artifact content.
def post_winner_announcement(
    winner_id: str,
    winner_score: float,
    artifact_content: str,
    objective: str,
) -> tuple[bool, str]:

Parameters

winner_id
string
required
The winning agent ID: "alpha", "beta", "gamma", "delta", or "epsilon"
winner_score
float
required
The final winning score (0-100)
artifact_content
string
required
The Discord post markdown content generated by the winning agent
objective
string
required
The original objective from the Dreamcatcher phase

Returns

success
boolean
True if announcement posted successfully
message
string
Success confirmation or error description

Example

from src.discord_poster import post_winner_announcement

success, msg = post_winner_announcement(
    winner_id="gamma",
    winner_score=92.5,
    artifact_content="**AI Events This Week**\n...",
    objective="Weekly AI events for Discord",
)

if success:
    print("Winner announced to Discord!")

Header Format

The announcement includes an auto-generated header:
πŸ† **DREAM FOUNDRY - Winner Announcement** πŸ†

**Objective:** [objective]
**Winner:** [Agent Name (Nickname)]
**Score:** [score]/100

---

[artifact_content]

Agent Name Mapping

alpha
string
Agent Alpha (The Speed Demon)
beta
string
Agent Beta (The Perfectionist)
gamma
string
Agent Gamma (The Insider)
delta
string
Agent Delta (The Crasher)
epsilon
string
Agent Epsilon (The Hallucinator)

Error Handling

The module handles several error scenarios:
if not get_webhook_url():
    return (
        False,
        "Discord webhook URL not configured. Add DISCORD_WEBHOOK_URL to .env"
    )

Rate Limiting

The module implements basic rate limiting:
  • Delay Between Messages: 0.5 seconds
  • Request Timeout: 10 seconds per message
  • Automatic Retry: Not implemented (returns error on first failure)
Discord webhooks have rate limits. For high-volume posting, consider implementing exponential backoff or queuing.

Message Formatting

Supports full Discord markdown syntax:
**bold text**
*italic text*
__underline__
~~strikethrough~~

Testing

Test the Discord integration directly:
python -m src.discord_poster
This will:
  1. Load configuration from .env
  2. Check if webhook is configured
  3. Send a test message: ”πŸ§ͺ Test message from Dream Foundry!”

Best Practices

Keep Webhook Secret: Never commit your webhook URL to version control. Use environment variables.
Message Length: Aim for under 1900 characters per logical block to avoid mid-content splits.
Formatting Preview: Test markdown formatting in Discord before automating, as rendering may differ slightly.
Error Handling: Always check the success return value before assuming the message was posted.

Build docs developers (and LLMs) love