Convex Slack

Sync Slack workspaces, channels, messages, and reactions into Convex reactively, and drive messaging, modals, slash commands, and file uploads from Convex funct

Installation

npm install convex-slack

About Convex Slack

convex-slack syncs Slack workspaces, channels, messages, reactions, and users into isolated Convex tables via the Slack Events API, enabling reactive queries that update as conversations happen. It handles the full OAuth v2 multi-workspace install flow, cryptographically verifies inbound webhooks, and exposes actions for messaging, Block Kit modals, slash commands, file uploads, and interactivity payloads. Token rotation is handled transparently without additional application code.

Benefits

Use cases

how to sync Slack messages into a database reactively

convex-slack registers HTTP action handlers for Slack's Events API that automatically write incoming message, message_changed, message_deleted, reaction_added, and reaction_removed events into isolated Convex tables. Your React app can then call useQuery against listMessagesByChannel and re-render in real time as the conversation happens, with no polling required.

how to send a Slack message from a Convex function

Instantiate the Slack client with your credentials and call slack.postMessage(ctx, { teamId, channel, text }) from a Convex action. The method resolves the stored bot token for that workspace, retries on 429 and 5xx responses with exponential backoff, and honors Slack's Retry-After header automatically.

how to handle Slack slash commands in a backend

convex-slack exposes a commandsHandler HTTP action that verifies the HMAC-SHA256 signature and records each invocation, including the trigger_id, to a commands table. Your own action can then read from that table and call slack.openView within the 3-second trigger_id window to open a Block Kit modal in response.

multi-workspace Slack OAuth install with token rotation

convex-slack implements the full OAuth v2 authorization-code flow via getAuthorizationUrl and exchangeCode, storing one bot token per team_id. If token rotation is enabled on your Slack app, resolveToken automatically refreshes and persists the rotated token pair before expiry, requiring no extra code in your application.

Frequently asked questions

Does convex-slack require me to manage Slack bot tokens manually?

No. convex-slack stores one bot token per workspace after the OAuth install flow completes. If your Slack app has token rotation enabled, the resolveToken method refreshes and persists the rotated token automatically before it expires. Apps without rotation enabled return the stored token as-is.

Which Slack tables does convex-slack add to my Convex deployment?

convex-slack creates its own isolated schema with these tables: installations, channels, users, messages, reactions, interactions, commands, files, scheduledMessages, and webhookEvents. These tables are not part of your app's schema and are only accessible through the functions the component exposes.

How does convex-slack verify that inbound Slack requests are authentic?

Every Events API, Interactivity, and Slash Command request is verified using Slack's v0=HMAC-SHA256(signingSecret, 'v0:{timestamp}:{body}') scheme before any data is recorded. A 5-minute replay window is enforced to prevent replay attacks. Requests that fail verification are rejected before they reach your handlers.

Which Slack data is synced automatically versus populated on demand?

Messages, reactions, user_change and team_join events, channel create/rename/archive events, and app uninstall or token revocation are all synced automatically as Slack delivers them via the Events API. Channel lists and user records are populated lazily the first time your app calls listConversationsFromSlack, getConversationInfo, getUserInfo, or listUsersFromSlack.

Can convex-slack handle file uploads to Slack?

Yes. convex-slack exposes an uploadFile method that drives the current Slack file upload sequence: files.getUploadURLExternal, uploading the binary content, then files.completeUploadExternal. The deprecated files.upload endpoint is never used. You pass a teamId, filename, Uint8Array content, channelId, and optional initialComment.

Links

Components

Open-source building blocks for your Convex app

Browse components in this category.

Loading components