Cloudflare Worker Code


/**
 * Discord slash command verification proxy
 * Uses your Discord application's PUBLIC_KEY
 * Forwards verified requests to your n8n webhook
 */

async function handleRequest(request) {
  const PUBLIC_KEY = "YOUR_APPLICATION_PUBLIC_KEY";
  const BOT_URL = "YOUR_N8N_URL"
  const encoder = new TextEncoder();

  const signature = request.headers.get("x-signature-ed25519");
  const timestamp = request.headers.get("x-signature-timestamp");
  const body = await request.text();

  // Verify signature
  const isValid = await verifyDiscordRequest(body, signature, timestamp, PUBLIC_KEY);

  if (!isValid) {
    return new Response("Invalid request signature", { status: 401 });
  }

  const json = JSON.parse(body);

  // Respond to Discord PING for endpoint verification
  if (json.type === 1) {
    return new Response(JSON.stringify({ type: 1 }), {
      headers: { "Content-Type": "application/json" },
    });
  }

  // Forward verified payload to your n8n webhook URL
  await fetch(BOT_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(json),
  });

  // Respond to Discord to acknowledge
  return new Response(JSON.stringify({ type: 5 }), {
    headers: { "Content-Type": "application/json" },
  });
}

// Helper: verify Discord request signature
async function verifyDiscordRequest(body, signature, timestamp, publicKey) {
  const cryptoKey = await crypto.subtle.importKey(
    "raw",
    hexToBytes(publicKey),
    { name: "Ed25519", namedCurve: "Ed25519" },
    false,
    ["verify"]
  );

  const message = concatUint8Arrays(
    new TextEncoder().encode(timestamp),
    new TextEncoder().encode(body)
  );

  return crypto.subtle.verify(
    "Ed25519",
    cryptoKey,
    hexToBytes(signature),
    message
  );
}

// Helper: hex to Uint8Array
function hexToBytes(hex) {
  const bytes = new Uint8Array(hex.length / 2);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
  }
  return bytes;
}

// Helper: concatenate two Uint8Arrays
function concatUint8Arrays(a, b) {
  const c = new Uint8Array(a.length + b.length);
  c.set(a, 0);
  c.set(b, a.length);
  return c;
}

export default {
  fetch: handleRequest
};


CURL Command for Creating a Slash Command on Discord


curl -X POST "https://discord.com/api/v10/applications/YOUR_APP_ID/commands" \
-H "Authorization: Bot YOUR_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "name": "joke",
  "type": 1,
  "description": "Get a joke for your topic",
  "options": [
    {
      "name": "query",
      "description": "Your query",
      "type": 3,
      "required": true
    }
  ]
}'


AI Agent System Prompt


You are a joke bot for discord. You reply with a joke based on the user input


Code Node


for (const item of $input.all()) {
  const text = item.json.output; // your joke string

  // Replace backslashes first to avoid double-escaping them
  let escaped = text.replace(/\\/g, '\\\\');

  // Then escape double quotes
  escaped = escaped.replace(/"/g, '\\"');

  item.json.escapedContent = escaped;
}

return $input.all();


Discord URL


https://discord.com/api/v10/webhooks/{{ $('Webhook').item.json.body.application_id }}/{{ $('Webhook').item.json.body.token }}