Hooks
React hooks for Corsair
Hooks let you "hook into" the lifecycle of API calls and webhook processing. Use them to add custom logic — logging, validation, transformations — without modifying your core application code.
slack({
authType: "api_key",
credentials: { botToken: "xoxb-..." },
hooks: {
channels: {
create: {
before: (ctx, args) => {
console.log("Creating channel:", args.name);
return { ctx, args };
},
},
},
},
})Before Hooks
Before hooks run before an operation executes. Use them to:
- Log or audit actions
- Validate or modify input
- Add default values
- Short-circuit operations
Modify Arguments
Transform the arguments before the API call is made.
slack({
hooks: {
channels: {
create: {
before: (ctx, args) => {
// Prefix all channel names
return {
ctx,
args: {
...args,
name: `team-${args.name}`,
},
};
},
},
},
},
})Validate Input
Check conditions before proceeding.
slack({
hooks: {
messages: {
post: {
before: (ctx, args) => {
if (args.text && args.text.length > 4000) {
throw new Error("Message too long");
}
return { ctx, args };
},
},
},
},
})Log Actions
Track every API call for debugging or auditing.
slack({
hooks: {
channels: {
create: {
before: (ctx, args) => {
console.log(`[Slack] Creating channel: ${args.name}`);
return { ctx, args };
},
},
},
},
})After Hooks
After hooks run after an operation completes. Use them to:
- Log results
- Trigger side effects
- Transform responses
- Send notifications
Send Notifications
Notify your team when something happens.
slack({
hooks: {
channels: {
create: {
after: async (ctx, result) => {
await sendSlackNotification({
channel: "#ops",
text: `New channel created: #${result.name}`,
});
},
},
},
},
})Log Results
Track successful operations.
slack({
hooks: {
messages: {
post: {
after: (ctx, result) => {
console.log(`Message sent: ${result.ts} in ${result.channel}`);
},
},
},
},
})API Hooks
API hooks are defined under hooks in your plugin configuration. They follow the structure: hooks.[resource].[action].before/after.
slack({
authType: "api_key",
credentials: { botToken: "xoxb-..." },
hooks: {
// Resource: channels
channels: {
// Action: create
create: {
before: (ctx, args) => {
return { ctx, args };
},
after: (ctx, result) => {
console.log("Channel created:", result.id);
},
},
// Action: archive
archive: {
before: (ctx, args) => {
console.log("Archiving:", args.channel);
return { ctx, args };
},
},
},
// Resource: messages
messages: {
post: {
after: (ctx, result) => {
console.log("Message posted:", result.ts);
},
},
},
},
})Webhook Hooks
Webhook hooks are defined under webhookHooks. They guarantee your logic runs every time a webhook is processed — even if Corsair handles the database update automatically.
slack({
authType: "api_key",
credentials: { botToken: "xoxb-..." },
webhookHooks: {
messages: {
message: {
before: async (ctx, payload) => {
console.log("Incoming message from:", payload.user);
return { ctx, payload };
},
after: async (ctx, result) => {
// Sync to your analytics
await analytics.track("slack_message_received", {
channel: result.channel,
user: result.user,
});
},
},
},
reactions: {
added: {
after: async (ctx, result) => {
console.log(`Reaction ${result.reaction} added`);
},
},
},
},
})See Webhooks for more on webhook processing.
Context Object
Both before and after hooks receive a ctx object with useful properties:
ctx.options— Plugin configuration optionsctx.db— Database service clients for this pluginctx.endpoints— Bound API endpoints (call other APIs within hooks)
before: (ctx, args) => {
// Access plugin options
console.log(ctx.options.credentials);
// Query the database
const existing = await ctx.db.channels.findByResourceId(args.channel);
return { ctx, args };
}Hook Order
When both plugin-level and operation-level hooks exist:
- Before hooks run in order: plugin → operation
- The operation executes
- After hooks run in order: operation → plugin
This lets you add global logging at the plugin level while keeping operation-specific logic separate.