Cloudflare Worker Code


const SLACK_SIGNING_SECRET = "YOUR_APP_SECRET";
const N8N_WEBHOOK_URL = "YOUR_N8N_WEBHOOK_URL";

export default {
  async fetch(req, env, ctx) {
    const ts = req.headers.get("X-Slack-Request-Timestamp");
    const sig = req.headers.get("X-Slack-Signature");
    const body = await req.text();

    // verify
    const base = `v0:${ts}:${body}`;
    const key = await crypto.subtle.importKey(
      "raw", new TextEncoder().encode(SLACK_SIGNING_SECRET),
      { name: "HMAC", hash: "SHA-256" }, false, ["sign"]
    );
    const raw = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(base));
    const hex = [...new Uint8Array(raw)].map(b => b.toString(16).padStart(2,"0")).join("");
    if (`v0=${hex}` !== sig) return new Response("Bad signature", { status: 401 });

    // URL verification (Events API)
    if (req.headers.get("Content-Type")?.includes("application/json")) {
      const json = JSON.parse(body);
      if (json.type === "url_verification") {
        return new Response(JSON.stringify({ challenge: json.challenge }), {
          headers: { "Content-Type": "application/json" },
        });
      }
    }

    // normalize payload
    let payload;
    if (req.headers.get("Content-Type")?.includes("application/x-www-form-urlencoded")) {
      payload = Object.fromEntries(new URLSearchParams(body));
    } else {
      try { payload = JSON.parse(body); } catch { payload = { raw: body }; }
    }

    // reliably forward without blocking Slack
    ctx.waitUntil(fetch(N8N_WEBHOOK_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload)
    }));

    return new Response("", { status: 200 });
  }
}


AI Agent System Prompt


Generate a joke based on the user message