Skip to content

Instantly share code, notes, and snippets.

@SaadBazaz
Created December 14, 2023 12:36
Show Gist options
  • Save SaadBazaz/cb141a188d36b6328a17589031ebe965 to your computer and use it in GitHub Desktop.
Save SaadBazaz/cb141a188d36b6328a17589031ebe965 to your computer and use it in GitHub Desktop.
Recipe: Connect Canny to Discord with NextJS API Route
// import { ironConfig } from '../../../your-iron-config'; // Provide your own Iron config
import { env } from '@/env.mjs'
import Iron from '@hapi/iron'
import { NextResponse } from 'next/server'
export async function POST(req) {
const {
'canny-timestamp': timestamp,
'canny-nonce': nonce,
'canny-signature': signature
} = req.headers
const APIKey = env.CANNY_BOARD_API_KEY // Replace with your Canny API key
const DiscordWebhookURL = env.DISCORD_CANNY_CHANNEL_WEBHOOK // Replace with your Discord webhook URL
// Verify the request signature
if (!(await verifySignature({ timestamp, nonce, signature }, APIKey))) {
return NextResponse.json(
{ message: 'Could not verify signature.' },
{
status: 401
}
)
}
// Parse the request body
const body = await req.json()
// Handle different event types
switch (body.type) {
case 'post.created':
await handlePostCreated(body, DiscordWebhookURL)
break
// Add more cases for other event types if needed
default:
break
}
// Acknowledge the message with Canny
// by sending a 200 HTTP status code
// The message here doesn't matter.
const res = new NextResponse(null, {
status: 200
})
return res
}
async function verifySignature({ timestamp, nonce, signature }, APIKey) {
const sealed = await Iron.seal({ nonce }, APIKey, Iron.defaults)
const calculated = await Iron.unseal(sealed, APIKey, Iron.defaults)
const calculatedNonce = calculated.nonce
return signature === calculatedNonce
}
async function handlePostCreated(body, DiscordWebhookURL) {
const { object } = body
const { title, details, url } = object
const discordMessage = {
content: `New Canny post created!\n**Title:** ${title}\n**Details:** ${details}\n**URL:** ${url}`
}
try {
// Send the message to Discord using fetch
await fetch(DiscordWebhookURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(discordMessage)
})
console.log('Discord message sent successfully')
} catch (error) {
console.error('Error sending Discord message:', error.message)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment