Build a Slack-to-Linear Bridge in 30 Minutes
Someone Slacks 'we need to fix the export bug.' Linear ticket appears with the right priority, the right team, and a sane description. Ship the integration today.
The build: in any Slack channel, reacting with a specific emoji on a message converts it to a Linear ticket with the right team, priority, and labels — auto-extracted from the message content.
Total build time: 30 minutes.
What you'll need
- -Slack workspace (admin access to add an app)
- -Linear with API access
- -n8n
- -AI API key
Step 1: Slack reaction trigger (8 min)
In Slack, create a custom app. Subscribe to `reaction_added` events. Point the webhook at n8n.
n8n Webhook trigger receives the event.
Filter: only act when the reaction is a specific emoji (I use :ticket: or :linear:).
Step 2: Fetch the original message (3 min)
The reaction event includes a reference to the original message. Add a Slack node to fetch the full message text + thread.
Step 3: AI extraction (10 min)
Add an AI node:
``` Convert this Slack message into a Linear ticket.
Message: {{ message_text }} Channel: {{ channel_name }} Thread context: {{ thread_text }}
Return JSON: { "title": "<crisp 6-10 word title, action-oriented>", "description": "<2-4 paragraphs explaining the issue, including context from thread>", "team": <one of {YOUR_TEAMS}>, "priority": <"urgent" / "high" / "medium" / "low">, "labels": [up to 3 labels from {LABEL_LIST}], "estimate": <1 / 2 / 3 / 5 / 8> }
Priority guidance: - urgent: production down, customer-blocking, security - high: significant friction, lots of users affected - medium: improvements, minor bugs - low: nice-to-have, cleanup
Be conservative on priority. Most things are medium. ```
Step 4: Create Linear ticket (5 min)
Add a Linear node. Action: create issue. Map all the fields from the AI response.
Add the Slack message permalink as a "source" field or to the description ("Original Slack message: <link>").
Step 5: Reply in Slack thread (3 min)
After creating the ticket, post a reply in the original Slack thread:
``` :ticket: Created Linear ticket: <{{ ticket_url }}|{{ ticket_id }}: {{ title }}> Priority: {{ priority }} | Team: {{ team }} ```
Step 6: Test (3 min)
In any channel, post a fake bug report. React with :ticket:. Verify the Linear ticket appears with reasonable extraction.
Common gotchas
- -Slack reaction events fire multiple times if the user toggles. Add idempotency check (have we created a ticket for this message_ts already?).
- -Linear API requires specific team IDs, not team names. Build a lookup table.
- -The AI's priority assessment will sometimes be too high. Add a one-line override in the Slack reply for triagers to adjust.
What I do with this
Anyone on the team can convert a Slack message to a Linear ticket with one click. Product, support, design, engineering. The ticket lands in the right team's queue with sane priority.
The previous workflow was: someone posts in Slack → someone else has to remember it → maybe someone makes a Linear ticket later → ticket is missing context.
The new workflow: one click. Ticket created. Context preserved. Source linked.
What to add next
- -Different emoji for different teams (`:eng-ticket:` for engineering, `:design-ticket:` for design)
- -Auto-assign based on who reacted
- -Create as draft instead of full ticket if message is too ambiguous
- -Weekly digest of all tickets created via this bridge
Start with the basic version. The other features earn their keep only after adoption is real.
Want the full guide? Check out our deep-dive page for more context, FAQs, and resources.
read the full guide