Documentation Index
Fetch the complete documentation index at: https://docs.corsair.dev/llms.txt
Use this file to discover all available pages before exploring further.
Workflows are event-driven automations built on Corsair’s webhook hooks. When something happens in one service, you trigger actions in another.
Pattern: event fires → webhook hook runs → you call any plugin API.
No separate workflow engine needed. It’s just TypeScript.
How it works
Every webhook event in Corsair supports an after hook — a function that runs after the event is saved to your database. Inside it, you have full access to corsair and can call any plugin API.
github({
webhookHooks: {
pullRequestOpened: {
after: async (ctx, result) => {
const pr = result?.data?.pull_request;
// Do anything here — call Slack, send email, create Linear issue
await corsair.slack.api.messages.post({
channel: 'C_ENG_CHANNEL',
text: `New PR: *${pr?.title}* by ${pr?.user?.login}\n${pr?.html_url}`,
});
},
},
},
})
That’s a workflow: GitHub PR opened → Slack message sent.
Common patterns
GitHub → Slack
Slack → GitHub
Multi-step
Notify Slack when a PR is merged:github({
webhookHooks: {
pullRequestClosed: {
after: async (ctx, result) => {
const pr = result.data.pull_request;
if (!pr.merged) return; // closed without merging
await corsair.slack.api.messages.post({
channel: 'C_RELEASES_CHANNEL',
text: `✅ Merged: *${pr.title}*\n${pr.html_url}`,
});
},
},
},
})
Alert on new stars:github({
webhookHooks: {
starCreated: {
after: async (ctx, result) => {
const { sender, repository } = result.data;
await corsair.slack.api.messages.post({
channel: 'C_GROWTH_CHANNEL',
text: `⭐ ${sender.login} starred ${repository.full_name} — now at ${repository.stargazers_count} stars`,
});
},
},
},
})
Create a GitHub issue when someone posts in #bugs:slack({
webhookHooks: {
messages: {
message: {
after: async (ctx, result) => {
// Only react to messages in the #bugs channel
if (result.data.channel !== 'C_BUGS_CHANNEL') return;
if (result.data.bot_id) return; // skip bots
await corsair.github.api.issues.create({
owner: 'your-org',
repo: 'your-repo',
title: `[Slack] ${result.data.text.slice(0, 80)}`,
body: `Reported via Slack by <@${result.data.user}>:\n\n${result.data.text}`,
labels: ['from-slack'],
});
},
},
},
},
})
PR merged → post Slack message → create Linear issue to track follow-up:github({
webhookHooks: {
pullRequestClosed: {
after: async (ctx, result) => {
const pr = result.data.pull_request;
if (!pr.merged) return;
// Step 1: Notify Slack
await corsair.slack.api.messages.post({
channel: 'C_ENG_CHANNEL',
text: `✅ Merged: *${pr.title}*`,
});
// Step 2: Create a Linear issue for post-merge follow-up
await corsair.linear.api.issues.create({
title: `Post-merge: ${pr.title}`,
description: `Follow up after merging ${pr.html_url}`,
teamId: process.env.LINEAR_TEAM_ID!,
labelIds: [process.env.LINEAR_POST_MERGE_LABEL!],
});
},
},
},
})
Filter with before hooks
Use before to reject events before they hit your database or after handler:
github({
webhookHooks: {
pullRequestOpened: {
before: async (ctx, payload) => {
// Ignore draft PRs entirely
if (payload.pull_request.draft) {
throw new Error('Skipping draft PR');
}
return { ctx, payload };
},
after: async (ctx, result) => {
// Only runs for non-draft PRs
await corsair.slack.api.messages.post({
channel: 'C_ENG_CHANNEL',
text: `PR ready for review: ${result.data.pull_request.title}`,
});
},
},
},
})
Throwing in before stops processing entirely — the event isn’t saved to your database.
Background jobs
For heavy processing (LLM calls, sending emails, generating reports), fire a background job instead of doing work inline:
github({
webhookHooks: {
pullRequestOpened: {
after: async (ctx, result) => {
// Send to your job queue — don't block the webhook response
await inngest.send({
name: 'github/pr-opened',
data: {
tenantId: ctx.tenantId,
pr: result.data.pull_request,
},
});
},
},
},
})
export const reviewPR = inngest.createFunction(
{ id: 'review-pr' },
{ event: 'github/pr-opened' },
async ({ event }) => {
const { pr } = event.data;
// Now you can do slow work: call an LLM, send emails, etc.
const review = await generateCodeReview(pr);
await corsair.github.api.issues.createComment({
owner: pr.base.repo.owner.login,
repo: pr.base.repo.name,
issue_number: pr.number,
body: review,
});
}
);
Webhook response stays fast. The work happens in the background.
What’s next
Webhooks Setup
Get ngrok running and register your first webhook endpoint.
GitHub Webhooks
All available GitHub events you can react to.
Slack Webhooks
All available Slack events you can react to.
Hooks Reference
Full before/after hook API and all available options.