We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
Direct answer: To integrate Discord with OpenClaw you treat Discord like any external API-driven service: create a Discord application and bot (or OAuth2 app) on Discord, host a public webhook/interaction endpoint outside the agent (so Discord can reach it), verify incoming requests (Ed25519 signature), store bot tokens and OAuth credentials securely in ClawHub as environment secrets, configure an OpenClaw skill that calls Discord’s REST APIs (using the bot token or user OAuth token) for sending messages or performing actions, and keep stateful or long-running pieces (queues, DBs, schedulers) outside the OpenClaw runtime. Authenticate explicitly, respect scopes and intents, and debug by checking logs, API responses, and token scopes.
Node.js example using tweetnacl for signature verification:
// <b>//</b> npm install tweetnacl
const nacl = require('tweetnacl');
const { TextEncoder } = require('util');
// <b>//</b> raw request body as Buffer or string, and headers from incoming request
function verifyDiscordRequest(publicKeyHex, signatureHex, timestamp, body) {
const encoder = new TextEncoder();
const message = encoder.encode(timestamp + body);
const publicKey = Buffer.from(publicKeyHex, 'hex');
const signature = Buffer.from(signatureHex, 'hex');
return nacl.sign.detached.verify(new Uint8Array(message), new Uint8Array(signature), new Uint8Array(publicKey));
}
// <b>//</b> Usage inside your HTTP handler:
// <b>//</b> const verified = verifyDiscordRequest(PUBLIC_KEY_HEX, req.headers['x-signature-ed25519'], req.headers['x-signature-timestamp'], rawBody);
Python example using pynacl:
# <b>//</b> pip install pynacl
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError
def verify_discord_request(public_key_hex, signature_hex, timestamp, body):
verify_key = VerifyKey(bytes.fromhex(public_key_hex))
message = (timestamp + body).encode('utf-8')
try:
verify_key.verify(message, bytes.fromhex(signature_hex))
return True
except BadSignatureError:
return False
# <b>//</b> Usage:
# <b>//</b> verified = verify_discord_request(PUBLIC_KEY_HEX, signature_hex, req.headers['x-signature-ed25519'], req_text_body)
# <b>//</b> Replace CHANNEL_ID and BOT_TOKEN
curl -X POST "https://discord.com/api/v10/channels/CHANNEL_ID/messages" \
-H "Authorization: Bot BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"Hello from OpenClaw skill"}'
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
Create a publicly reachable HTTPS endpoint that receives Discord events, verify Discord's Ed25519 signatures on each request, register that URL in the Discord Developer Portal (Interactions/Webhooks), store the Discord public key as an environment variable, and configure your OpenClaw skill in ClawHub to accept and route those events to the agent runtime. Use a proxy (ngrok) for local testing and inspect logs to confirm delivery and skill activation.
Key steps:
// Express example: verify Discord Ed25519 signature
const nacl = require('tweetnacl');
app.post('/discord-webhook', express.raw({type:'application/json'}), (req, res)=>{
const signature = req.get('X-Signature-Ed25519');
const timestamp = req.get('X-Signature-Timestamp');
const body = req.body; // Buffer
const msg = Buffer.concat([Buffer.from(timestamp), body]);
const isValid = nacl.sign.detached.verify(msg, Buffer.from(signature,'hex'), Buffer.from(process.env.DISCORD_PUBLIC_KEY,'hex'));
if(!isValid) return res.status(401).end();
// dispatch to OpenClaw skill handler
res.status(200).end();
});
2
The bridge most often fails because of misconfiguration: incorrect EventBus URL or auth token, webhook signature validation mismatch, missing Discord permissions/intents (so messages aren’t delivered), or network/TLS/firewall blocking. Check bridge and EventBus logs and Discord delivery diagnostics to locate the failing step.
3
Use the OpenClaw Auth Adapter to translate Discord guild role IDs into OpenClaw permission groups during authentication: validate the user’s Discord identity, call the Discord API to read the user’s guild role IDs, consult a maintained mapping (env, config file, or DB) from role ID → group name, then emit those group names as the adapter’s permission claims so OpenClaw skills enforce them.
4
A common cause of Discord↔OpenClaw OAuth2 refresh errors (invalid_grant or 401) is a mismatch between what your adapter sends and Discord's token rules: wrong client_id/secret, wrong redirect_uri, refresh token rotation (token already used), revoked tokens, or clock skew. Fix by verifying credentials, using the correct token endpoint, sending form-encoded body or Basic auth, and logging full responses.
// <b>//</b> realistic Node.js refresh example using axios
const res = await axios.post('https://discord.com/api/oauth2/token',
new URLSearchParams({grant_type:'refresh_token', refresh_token, client_id, client_secret}),
{headers:{'Content-Type':'application/x-www-form-urlencoded'}})
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â