Skip to main content

Webhooks

It's often the case you need to call from your app an external webhook or receive a webhook from an other products and take actions from it.

Trigger a Webhook

Say you built a complex AI flow using Stack AI or Wordware that takes a prompt and output something and you want to trigger the flow when a user clicks on a button in your app.

You could do a simple fetch(webhookurl) in your front-end, but doing that would expose your webhook URL and everyone would be able to trigger.

So you need to add an endpoint in your server to trigger the wehhook.

1. Define a new route in the server router

/src/server/routers/triggerWebhook.ts

import { z } from 'zod'
import { Trpc } from '@/core/trpc/server'

export const TriggerWebhookRouter = Trpc.createRouter({
wordware: Trpc.procedure
.input(z.object({ prompt: z.string() }))
.mutation(async ({ ctx, input }) => {
const response = await axios.post(
'https://.../', // your webhook URL
{
prompt: input?.prompt,
},
)
return response.data
}),
})

2. Export your newly created router

src/server/index.tsx

  Trpc.createRouter({
auth: AuthenticationRouter,
...
triggerWebhook: TriggerWebhookRouter
}),

3. Use it in the front-end

...

const { mutateAsync: triggerWebhook } =
Api.triggerWebhook.wordware.useMutation()

const generateOutput = async () => {
await triggerWebhook({ prompt: 'A awesome picture of marbles' })
}

return (
<>
<Button onClick={generateOutput}>Generate Output</Button>
</>
)

Receive a Webhook

Let's say you set-up a system on Zapier where everytime it processes a document, it needs to send you a request (with the document ID) so you can update your document to 'processed' status in your app.

Create a new file in src/app/api/webhook/document/route.ts.

Your webhook will be live at yourapp.com/api/webhook/document. This will be the production URL to give Zapier.

import { Database } from '@/core/database'
import { headers } from 'next/headers'
import { NextRequest, NextResponse } from 'next/server'

export async function POST(req: NextRequest, res: NextResponse) {
try {
console.log('Webhook received')

const database = await Database.getUnprotected()

const body = await req.json()

// do something with the webhook body

await database.document.update({
where: {
id: body?.id,
},
data: {
status: 'processed',
},
})

return new NextResponse(`Webhook successful`, {
status: 200,
})
} catch (error: any) {
console.error('Could not handle webhook')
console.error(error)
return new NextResponse(`Unknown error: ${error.message}`, {
status: 500,
})
}
}

If you would like to test your webhook in the workspace, use the endpoint found on your project overview page as the base url for the callback.

info

If you're looking to receive a webhook to stripe, check out this guide.