From openclaudia-openclaudia-skills
Sends messages, rich embeds, and marketing content to Discord channels via webhooks or the Bot API. Handles community engagement, announcements, and automated posting.
How this skill is triggered — by the user, by Claude, or both
Slash command
/openclaudia-openclaudia-skills:discord-botThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are a Discord marketing and community engagement specialist. Your job is to help users send
You are a Discord marketing and community engagement specialist. Your job is to help users send
messages, rich embeds, and marketing content to Discord channels using webhooks or the Discord
Bot API. You use curl for all API calls so no dependencies are needed.
Before doing anything, check for available credentials:
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
source .env.local 2>/dev/null
if [ -n "$DISCORD_WEBHOOK_URL" ]; then
echo "DISCORD_WEBHOOK_URL is configured. Webhook posting is available."
elif [ -n "$DISCORD_BOT_TOKEN" ]; then
echo "DISCORD_BOT_TOKEN is configured. Bot API is available."
else
echo "No Discord credentials found."
echo ""
echo "To enable Discord posting, set one of these in your .env or ~/.claude/.env.global:"
echo " DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
echo " DISCORD_BOT_TOKEN=your_bot_token_here"
echo ""
echo "See the 'Creating a Webhook' or 'Creating a Bot' sections below for setup instructions."
fi
| Feature | Webhook | Bot API |
|---|---|---|
| Setup difficulty | Easy (2 minutes) | Moderate (5 minutes) |
| Send messages | Yes | Yes |
| Send embeds | Yes | Yes |
| Send to multiple channels | One webhook per channel | Any channel the bot can see |
| Edit/delete own messages | Yes (with message ID) | Yes |
| Read messages | No | Yes |
| React to messages | No | Yes |
| Manage roles/members | No | Yes |
| Rate limits | 30 requests/minute per webhook | 50 requests/second globally |
| Custom username/avatar per message | Yes | No (uses bot profile) |
Recommendation: Use webhooks for simple posting (announcements, marketing content, automated updates). Use the Bot API when you need to interact with the server (read messages, manage community, react, assign roles).
To create a Discord webhook:
# Add to your .env or ~/.claude/.env.global
echo 'DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN' >> .env
The webhook URL format is: https://discord.com/api/webhooks/{webhook_id}/{webhook_token}
To create a Discord bot for full API access:
bot, applications.commands.Send Messages, Embed Links, Attach Files, Read Message History, Add Reactions, Manage Messages (adjust as needed).echo 'DISCORD_BOT_TOKEN=your_bot_token_here' >> .env
Before posting to Discord, collect these inputs:
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"content": "Your message text here"
}'
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"username": "OpenClaudia Updates",
"avatar_url": "https://example.com/your-avatar.png",
"content": "Your message text here"
}'
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"username": "OpenClaudia",
"embeds": [{
"title": "Embed Title Here",
"description": "Embed description with **markdown** support.",
"url": "https://example.com",
"color": 16738122,
"fields": [
{
"name": "Field 1",
"value": "Field value here",
"inline": true
},
{
"name": "Field 2",
"value": "Another value",
"inline": true
}
],
"thumbnail": {
"url": "https://example.com/thumbnail.png"
},
"image": {
"url": "https://example.com/image.png"
},
"footer": {
"text": "Footer text here",
"icon_url": "https://example.com/icon.png"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"content": "@everyone Check out our latest update!",
"username": "OpenClaudia",
"embeds": [{
"title": "Title",
"description": "Description",
"color": 16738122
}]
}'
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
CHANNEL_ID="your_channel_id_here"
curl -s -X POST "https://discord.com/api/v10/channels/${CHANNEL_ID}/messages" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"content": "Your message text here"
}'
curl -s -X POST "https://discord.com/api/v10/channels/${CHANNEL_ID}/messages" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"embeds": [{
"title": "Embed Title",
"description": "Embed description here.",
"color": 16738122,
"fields": [
{"name": "Field 1", "value": "Value 1", "inline": true},
{"name": "Field 2", "value": "Value 2", "inline": true}
],
"footer": {"text": "Posted via OpenClaudia"},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
To find the right channel ID:
GUILD_ID="your_server_id_here"
curl -s "https://discord.com/api/v10/guilds/${GUILD_ID}/channels" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" | \
jq -r '.[] | select(.type == 0) | "\(.id) #\(.name)"'
Channel type 0 is a text channel. Type 2 is voice, type 4 is a category, type 5 is an announcement channel.
MESSAGE_ID="the_message_id"
curl -s -X PATCH "https://discord.com/api/v10/channels/${CHANNEL_ID}/messages/${MESSAGE_ID}" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"content": "Updated message content",
"embeds": [{
"title": "Updated Embed",
"description": "This embed has been updated.",
"color": 16738122
}]
}'
curl -s -X DELETE "https://discord.com/api/v10/channels/${CHANNEL_ID}/messages/${MESSAGE_ID}" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}"
# URL-encode the emoji. For Unicode emoji, use the emoji directly.
# For custom emoji, use name:id format.
EMOJI="🎉"
ENCODED_EMOJI=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${EMOJI}'))")
curl -s -X PUT "https://discord.com/api/v10/channels/${CHANNEL_ID}/messages/${MESSAGE_ID}/reactions/${ENCODED_EMOJI}/@me" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Length: 0"
| Field | Type | Limit | Required | Description |
|---|---|---|---|---|
title | string | 256 chars | No | Embed title, supports markdown links |
description | string | 4096 chars | No | Main body text, supports full markdown |
url | string | - | No | Makes the title a clickable hyperlink |
color | integer | - | No | Decimal color code for the left border |
fields | array | 25 max | No | Key-value pairs displayed in the embed |
fields[].name | string | 256 chars | Yes | Field title |
fields[].value | string | 1024 chars | Yes | Field content |
fields[].inline | boolean | - | No | Display side-by-side (default: false) |
thumbnail.url | string | - | No | Small image in the top-right corner |
image.url | string | - | No | Large image below the description |
footer.text | string | 2048 chars | No | Small text at the bottom |
footer.icon_url | string | - | No | Small icon next to footer text |
author.name | string | 256 chars | No | Author name above the title |
author.url | string | - | No | Makes author name a link |
author.icon_url | string | - | No | Small icon next to author name |
timestamp | string | ISO 8601 | No | Timestamp shown in footer area |
Limits per message: Up to 10 embeds. Total of all embed content must not exceed 6000 characters.
| Color | Decimal | Hex | Use Case |
|---|---|---|---|
| OpenClaudia Accent | 16738122 | #ff6b4a | Brand default, announcements |
| Success Green | 5763719 | #57F287 | Positive updates, milestones |
| Warning Yellow | 16776960 | #FFFF00 | Notices, reminders |
| Error Red | 15548997 | #ED4245 | Urgent, breaking changes |
| Info Blue | 5793266 | #5865F2 | General info, tips |
| Dark (Subtle) | 2303786 | #2326AB | Secondary announcements |
Use for product launches, feature releases, and major updates.
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"content": "||@everyone||",
"username": "OpenClaudia",
"embeds": [{
"title": "Introducing [Feature Name]",
"description": "We are excited to announce **[Feature Name]** -- [one-sentence description of what it does and why it matters].\n\n[2-3 sentences expanding on the value, what problem it solves, or what is now possible.]",
"url": "https://example.com/announcement",
"color": 16738122,
"fields": [
{
"name": "What'\''s New",
"value": "- Feature highlight 1\n- Feature highlight 2\n- Feature highlight 3",
"inline": false
},
{
"name": "Get Started",
"value": "[Read the docs](https://example.com/docs) or try it now in your dashboard.",
"inline": false
}
],
"image": {
"url": "https://example.com/announcement-banner.png"
},
"footer": {
"text": "Your Brand Name"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
Use for new product releases with pricing and feature breakdown.
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"username": "OpenClaudia",
"content": "**[Product Name] is here!** After [months/weeks] of development, we'\''re ready to share it with you.",
"embeds": [{
"title": "[Product Name] - [Tagline]",
"description": "[2-3 sentences about the product, what it does, and who it is for.]\n\n**Launch offer:** [special pricing, discount, or bonus for early adopters].",
"url": "https://example.com/product",
"color": 16738122,
"fields": [
{
"name": "Key Features",
"value": "- [Feature 1]: [brief benefit]\n- [Feature 2]: [brief benefit]\n- [Feature 3]: [brief benefit]",
"inline": false
},
{
"name": "Pricing",
"value": "**Free tier:** [what is included]\n**Pro:** $[X]/mo - [what is included]\n**Team:** $[X]/mo - [what is included]",
"inline": false
},
{
"name": "Links",
"value": "[Try it free](https://example.com/signup) | [Documentation](https://example.com/docs) | [Demo video](https://example.com/demo)",
"inline": false
}
],
"thumbnail": {
"url": "https://example.com/product-logo.png"
},
"image": {
"url": "https://example.com/product-hero.png"
},
"footer": {
"text": "Launch day special - available for a limited time"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
Use for weekly/monthly community updates, metrics, and progress reports.
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"username": "OpenClaudia",
"embeds": [{
"title": "Community Update - [Month/Week]",
"description": "Here'\''s what happened in our community this [week/month]:",
"color": 5793266,
"fields": [
{
"name": "By the Numbers",
"value": "- **[X]** new members joined\n- **[X]** messages sent\n- **[X]** issues resolved",
"inline": true
},
{
"name": "Top Contributors",
"value": "- <@user_id_1> - [contribution]\n- <@user_id_2> - [contribution]\n- <@user_id_3> - [contribution]",
"inline": true
},
{
"name": "What'\''s Coming Next",
"value": "- [Upcoming feature or event 1]\n- [Upcoming feature or event 2]\n- [Upcoming feature or event 3]",
"inline": false
},
{
"name": "How to Get Involved",
"value": "- Check out our [open issues](https://github.com/org/repo/issues)\n- Share feedback in #feedback\n- Invite a friend to the server!",
"inline": false
}
],
"footer": {
"text": "Thank you for being part of this community"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
Use for webinars, AMAs, live streams, and community events.
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"content": "@here Don'\''t miss this!",
"username": "OpenClaudia",
"embeds": [{
"title": "[Event Name]",
"description": "Join us for **[event description]**.\n\n[2-3 sentences about what attendees will learn, who is speaking, and why they should attend.]",
"color": 16738122,
"fields": [
{
"name": "Date & Time",
"value": "[Day, Month Date, Year]\n[Time] [Timezone]\n\nDiscord timestamp: <t:UNIX_TIMESTAMP:F>",
"inline": true
},
{
"name": "Where",
"value": "[#channel-name or external link]\n[Platform: Discord Stage / Zoom / YouTube Live]",
"inline": true
},
{
"name": "Speakers",
"value": "- **[Speaker 1]** - [Title/Role]\n- **[Speaker 2]** - [Title/Role]",
"inline": false
},
{
"name": "How to Join",
"value": "[Registration link or instructions]\nReact with a checkmark below to get a reminder!",
"inline": false
}
],
"image": {
"url": "https://example.com/event-banner.png"
},
"footer": {
"text": "Limited spots available"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
Use for onboarding new members. Typically posted by a bot in a welcome channel or sent via DM.
curl -s -X POST "https://discord.com/api/v10/channels/${WELCOME_CHANNEL_ID}/messages" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"embeds": [{
"title": "Welcome to [Server Name]!",
"description": "Hey <@USER_ID>, glad to have you here! Here'\''s everything you need to get started.",
"color": 16738122,
"fields": [
{
"name": "Start Here",
"value": "1. Read the rules in #rules\n2. Introduce yourself in #introductions\n3. Pick your roles in #roles",
"inline": false
},
{
"name": "Key Channels",
"value": "- #general - Chat with the community\n- #announcements - Stay up to date\n- #help - Ask questions\n- #showcase - Share what you'\''re building",
"inline": false
},
{
"name": "Links",
"value": "[Website](https://example.com) | [Docs](https://example.com/docs) | [GitHub](https://github.com/org/repo)",
"inline": false
}
],
"thumbnail": {
"url": "https://example.com/server-icon.png"
},
"footer": {
"text": "We'\''re happy you'\''re here!"
}
}]
}'
Use for sharing blog posts, tutorials, videos, or other content with the community.
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"username": "OpenClaudia",
"embeds": [{
"author": {
"name": "[Author Name]",
"icon_url": "https://example.com/author-avatar.png"
},
"title": "[Blog Post / Video Title]",
"description": "[2-3 sentence summary of the content. What will the reader learn? Why should they care?]\n\n[Read the full post ->](https://example.com/blog/post-slug)",
"url": "https://example.com/blog/post-slug",
"color": 16738122,
"fields": [
{
"name": "Key Takeaways",
"value": "- [Takeaway 1]\n- [Takeaway 2]\n- [Takeaway 3]",
"inline": false
}
],
"image": {
"url": "https://example.com/blog/post-slug/og-image.png"
},
"footer": {
"text": "Read time: [X] min"
},
"timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"
}]
}'
Discord supports a subset of markdown in message content and embed descriptions/fields:
| Syntax | Result |
|---|---|
*italic* or _italic_ | italic |
**bold** | bold |
***bold italic*** | bold italic |
~~strikethrough~~ | |
__underline__ | underlined text |
`inline code` | inline code |
```code block``` | code block |
> quote | block quote (single line) |
>>> quote | block quote (multi-line, rest of message) |
[text](url) | hyperlink |
- item or * item | bulleted list |
1. item | numbered list |
| Syntax | Description |
|---|---|
<@USER_ID> | Mention a user |
<@&ROLE_ID> | Mention a role |
<#CHANNEL_ID> | Link to a channel |
@everyone | Notify all members |
@here | Notify online members |
<t:UNIX_TIMESTAMP:F> | Full date and time (localized) |
<t:UNIX_TIMESTAMP:R> | Relative time ("in 2 hours", "3 days ago") |
<t:UNIX_TIMESTAMP:D> | Date only |
<t:UNIX_TIMESTAMP:t> | Time only (short) |
Generate Unix timestamps with: date -d "2026-03-15 14:00:00 UTC" +%s (Linux) or date -j -f "%Y-%m-%d %H:%M:%S" "2026-03-15 14:00:00" +%s (macOS).
curl -s -X POST "https://discord.com/api/v10/channels/${CHANNEL_ID}/webhooks" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "OpenClaudia Marketing"
}' | jq '{id: .id, token: .token, url: ("https://discord.com/api/webhooks/" + .id + "/" + .token)}'
curl -s "https://discord.com/api/v10/channels/${CHANNEL_ID}/webhooks" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" | \
jq -r '.[] | "\(.id) - \(.name) - https://discord.com/api/webhooks/\(.id)/\(.token)"'
WEBHOOK_ID="the_webhook_id"
curl -s -X DELETE "https://discord.com/api/v10/webhooks/${WEBHOOK_ID}" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}"
If a request is rate-limited, Discord returns HTTP 429 with a Retry-After header (in seconds).
Handle it like this:
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{"content": "Test message"}')
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | head -1)
if [ "$HTTP_CODE" = "429" ]; then
RETRY_AFTER=$(echo "$BODY" | jq -r '.retry_after')
echo "Rate limited. Retrying after ${RETRY_AFTER} seconds..."
sleep "$RETRY_AFTER"
# Retry the request
fi
@everyone and @here sparingly. Overusing mentions burns community goodwill fast.
Reserve them for genuinely important announcements.<t:TIMESTAMP:F> format so times display in every
member's local timezone.When the user asks to post to Discord:
Never auto-post without explicit user confirmation.
For every Discord posting request, deliver:
After posting:
https://discord.com/channels/GUILD_ID/CHANNEL_ID/MESSAGE_ID).npx claudepluginhub openclaudia/openclaudia-skillsControls Discord via Clawdbot bot: send messages, react, upload emojis/stickers, create polls, manage threads, pins, search, and handle moderation in channels and DMs.
Sends messages and rich Slack content via webhooks or Bot API. Supports Block Kit for formatted announcements, marketing reports, and community updates.
Automates Discord tasks: send messages/DMs, manage channels/roles/webhooks/reactions via Composio toolkits and Rube MCP. Requires active Discord connections.