2 min read
Discord recipe
Two ways: native Discord integration (no code) or a generic webhook to a Discord channel webhook URL.
Option A — Native Discord integration
- In Discord: Channel settings → Integrations → Webhooks → New webhook. Name it, copy the URL.
- In Formspring: Webhooks → Add integration → Discord.
- Paste the URL. Save.
We render submissions as a Discord embed: form name as title, key fields as embed fields, a small footer with the timestamp and a link back to the submission in your dashboard.
Channel mentions: prefix the form name with @here or @channel-id and we'll respect the mention in the embed's content. Use sparingly.
Option B — Generic webhook through your own handler
Use this when you want to format embeds yourself, route to different channels by field value, or filter what gets posted.
- In Discord, create a channel webhook. Copy the URL.
- In Formspring, Webhooks → Add webhook → Generic. Use your handler's URL. Save the signing secret.
- In your handler: verify, transform, POST to Discord.
// Cloudflare Worker / Lambda / etc.
import { createHmac, timingSafeEqual } from 'node:crypto';
export default {
async fetch(req, env) {
const sig = req.headers.get('x-formspring-signature') ?? '';
const raw = await req.text();
const expected = createHmac('sha256', env.FORMSPRING_SECRET)
.update(raw)
.digest('hex');
if (
sig.length !== expected.length ||
!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
) {
return new Response('unauthorized', { status: 401 });
}
const body = JSON.parse(raw);
const fields = Object.entries(body.payload).map(([name, value]) => ({
name,
value: String(value).slice(0, 1024),
inline: name.length < 16,
}));
await fetch(env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'Formspring',
embeds: [
{
title: `New submission — ${body.form_name}`,
url: `https://app.formspring.io/submissions/${body.submission_id}`,
color: 0x5865f2,
fields,
footer: { text: body.submission_id },
timestamp: body.received_at,
},
],
}),
});
return new Response('ok');
},
};
Notes
- Discord's embed limits: 25 fields, 1024 chars per field value, 6000 chars total. Truncate generously.
- Replies don't loop back to Formspring — Discord webhooks are one-way.
- Rotate the Discord webhook URL if it leaks; Discord treats it as a secret.