Discord Notifications for License Activations
When a customer activates your software on a new machine, your Discord server can know about it in seconds. Here's how to wire Keymint's device.activated outbound webhook to a Discord channel.
How It Works
- Customer's app calls
POST /key/activateto validate their license - Keymint emits a
device.activatedwebhook event - Your handler receives it, verifies the HMAC-SHA256 signature
- Your handler posts an embed to a Discord channel via incoming webhook
Setup
Discord: Server Settings → Integrations → Webhooks → New Webhook. Copy the URL.
Keymint: Dashboard → Developer → Webhooks → Create Endpoint. Subscribe to device.activated and device.deactivated. Save the signing secret.
The Handler
The key part is verifying Keymint's signature before acting on the payload:
function verifySignature(payload: string, header: string, secret: string) {
const [tPart, v1Part] = header.split(',');
const t = tPart?.substring(2);
const v1 = v1Part?.substring(3);
if (Math.abs(Date.now() / 1000 - parseInt(t)) > 300) return false;
const expected = crypto.createHmac('sha256', secret)
.update(t + '.' + payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(v1),
);
}When event.type === 'device.activated', POST a Discord embed:
await fetch(process.env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
embeds: [{
title: '🟢 License Activated',
color: 0x22c55e,
fields: [
{ name: 'Product', value: event.data.license.productId, inline: true },
{ name: 'Host ID', value: event.data.activation.hostId, inline: true },
{ name: 'Device', value: event.data.activation.deviceTag || 'N/A', inline: true },
{ name: 'Customer', value: event.data.license.customerEmail || 'N/A', inline: true },
{ name: 'Activations', value: `${event.data.license.activations}/${event.data.license.maxActivations || '∞'}`, inline: true },
],
footer: { text: event.type },
}],
}),
});Variations
- Deactivations: Subscribe to
device.deactivated, use red embed (0xef4444) - Floating sessions: Subscribe to
floating_session.checked_out,floating_session.checked_in, andfloating_session.limit_hit - Filter by product: Check
event.data?.license?.productIdbefore posting
Security
Keymint sends Keymint-Signature: t=<unix>,v1=<hmac_sha256_hex>. Always verify the HMAC. Reject timestamps older than 5 minutes. Raw license keys are never sent in webhook payloads — they're redacted at source.
Full webhook docs: keymint.dev/docs/topics/webhooks
Prefer Slack? See our Slack notifications guide for the same pattern with license revocations.