Back

Quick Guide to Implementing Webhooks in Linear

Aug 13, 20247 minute read

Hey there, fellow JavaScript aficionado! Ready to supercharge your Linear integration with some webhook magic? Let's dive right in and get those real-time updates flowing.

Introduction

Webhooks are like the cool kids of API integrations - they don't wait around, they come to you. With Linear's webhook support, you can keep your app in sync with all the juicy updates happening in your Linear workspace. No more constant polling - it's time to level up!

Prerequisites

Before we start, make sure you've got:

  • A Linear API key (grab one from your account settings)
  • A webhook endpoint (ngrok is your best friend for local development)

Got 'em? Great! Let's roll.

Setting up a Webhook

First things first, let's create a webhook using the Linear API. It's easier than you might think:

const axios = require('axios'); async function createWebhook() { try { const response = await axios.post('https://api.linear.app/graphql', { query: ` mutation CreateWebhook($input: WebhookCreateInput!) { webhookCreate(input: $input) { success webhook { id url } } } `, variables: { input: { url: 'https://your-webhook-endpoint.com', resourceTypes: ['Issue', 'Comment'], }, }, }, { headers: { 'Authorization': 'Bearer YOUR_LINEAR_API_KEY', 'Content-Type': 'application/json', }, }); console.log('Webhook created:', response.data.data.webhookCreate.webhook); } catch (error) { console.error('Error creating webhook:', error); } } createWebhook();

Boom! You've just created a webhook. Linear will now start sending updates to your specified URL.

Handling Webhook Payloads

Now that Linear's sending data your way, let's catch it with a simple Express server:

const express = require('express'); const app = express(); app.use(express.json()); app.post('/webhook', (req, res) => { const payload = req.body; console.log('Received webhook:', payload); // Process the webhook payload here res.sendStatus(200); }); app.listen(3000, () => console.log('Webhook server running on port 3000'));

Easy peasy, right? This server will log incoming webhooks and respond with a 200 OK.

Verifying Webhook Signatures

Trust, but verify. Let's make sure these webhooks are legit:

const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret) { const hmac = crypto.createHmac('sha256', secret); const digest = hmac.update(JSON.stringify(payload)).digest('hex'); return signature === digest; } app.post('/webhook', (req, res) => { const signature = req.headers['linear-signature']; if (!verifyWebhookSignature(req.body, signature, 'YOUR_WEBHOOK_SECRET')) { return res.status(401).send('Invalid signature'); } // Process verified webhook res.sendStatus(200); });

Now you're cooking with gas! Only genuine Linear webhooks will make it through.

Responding to Webhook Events

Let's do something useful with these webhooks, shall we?

app.post('/webhook', (req, res) => { const { type, data } = req.body; switch (type) { case 'Issue': console.log(`New issue created: ${data.title}`); // Do something with the new issue break; case 'Comment': console.log(`New comment on issue ${data.issue.id}: ${data.body}`); // Handle the new comment break; default: console.log(`Unhandled event type: ${type}`); } res.sendStatus(200); });

Now you're responding to specific events like a pro!

Error Handling and Retries

Sometimes things go wrong. Let's be prepared:

app.post('/webhook', async (req, res) => { try { await processWebhook(req.body); res.sendStatus(200); } catch (error) { console.error('Error processing webhook:', error); res.status(500).send('Internal Server Error'); // Implement retry logic here } }); async function processWebhook(payload, retries = 3) { try { // Process webhook } catch (error) { if (retries > 0) { console.log(`Retrying... (${retries} attempts left)`); await new Promise(resolve => setTimeout(resolve, 1000)); return processWebhook(payload, retries - 1); } throw error; } }

Now you're handling errors like a champ and giving those webhooks a second (and third) chance!

Testing and Debugging

Linear's got your back with a webhook delivery history in their UI. Use it to replay events and debug to your heart's content. For local testing, ngrok is your secret weapon - it'll give you a public URL to use as your webhook endpoint.

Scaling Considerations

As your app grows, you might need to handle a tsunami of webhooks. Consider using a message queue like RabbitMQ or Redis to process webhooks asynchronously. Your server can quickly acknowledge the webhook and hand off processing to a background worker. Your users (and your server) will thank you!

Conclusion

And there you have it! You're now a Linear webhook wizard. Remember, with great power comes great responsibility - use these real-time updates wisely and build something awesome!

Keep coding, keep learning, and may your integrations be ever seamless!