slack-to-slashwork
v1.4.0
Published
Simple pushing of new messages from Slack channels into Slashwork groups via Slack's Events API webhook.
Readme
slack-to-slashwork
A web request handler that pushes new messages from Slack channels into Slashwork groups. The request handler expects to be called by Slack's Event Subscriptions API, and uses Slashwork's GraphQL service to mirror new messages in designated Slack channels into Slashwork groups.
Installation
npm install slack-to-slashworkQuick Start
import { createSlackWebhook } from "slack-to-slashwork";
const handler = createSlackWebhook({
graphqlEndpoint: "https://yourcompany.slashwork.com/api/graphql",
bearerToken: process.env.SLASHWORK_API_TOKEN,
groupMappings: {
C01234567: "group-id-abc", // Slack channel ID -> Slashwork group ID
C89012345: "group-id-def",
},
});Usage with Express
import express from "express";
import { createSlackWebhook } from "slack-to-slashwork";
const app = express();
app.use(express.json());
const slackHandler = createSlackWebhook({
graphqlEndpoint: "https://yourcompany.slashwork.com/api/graphql",
bearerToken: process.env.SLASHWORK_API_TOKEN,
groupMappings: {
C01234567: "group-id-abc",
},
});
app.post("/slack/events", slackHandler);
app.listen(3000);Usage with Firebase Functions (v2)
import { onRequest } from "firebase-functions/v2/https";
import { createSlackWebhook } from "slack-to-slashwork";
const slackHandler = createSlackWebhook({
graphqlEndpoint: "https://yourcompany.slashwork.com/api/graphql",
bearerToken: process.env.SLASHWORK_API_TOKEN,
groupMappings: {
C01234567: "group-id-abc",
},
});
export const slackEvents = onRequest(slackHandler);Configuration
Required Options
| Option | Type | Description |
|--------|------|-------------|
| graphqlEndpoint | string | Your Slashwork GraphQL API endpoint |
| bearerToken | string | API token for authenticating with Slashwork |
| groupMappings | Record<string, string> | Map of Slack channel IDs to Slashwork group IDs |
Optional Options
| Option | Type | Description |
|--------|------|-------------|
| slackIdMap | SlackIdMap | Enable threaded conversation support (see below) |
| getSlackUsername | (userId: string) => string \| Promise<string> | Resolve user IDs to usernames for message prefacing |
Threaded Conversations
To mirror Slack threads as Slashwork comments, provide a slackIdMap implementation:
import { createSlackWebhook, SlackIdMap } from "slack-to-slashwork";
// Example: in-memory storage (use a database in production)
const idMappings = new Map<string, string>();
const slackIdMap: SlackIdMap = {
saveSlackId: (slackId, slashworkId) => {
idMappings.set(slackId, slashworkId);
},
findSlackIdMapping: (slackId) => {
return idMappings.get(slackId);
},
};
const handler = createSlackWebhook({
graphqlEndpoint: "https://yourcompany.slashwork.com/api/graphql",
bearerToken: process.env.SLASHWORK_API_TOKEN,
groupMappings: { C01234567: "group-id-abc" },
slackIdMap,
});When configured:
- Top-level Slack messages create Slashwork posts
- Threaded replies create comments on the corresponding post
Username Prefacing
To prefix messages with the sender's name (e.g., [Alice] Hello everyone!), provide a getSlackUsername function:
import { WebClient } from "@slack/web-api";
const slackClient = new WebClient(process.env.SLACK_BOT_TOKEN);
const handler = createSlackWebhook({
graphqlEndpoint: "https://yourcompany.slashwork.com/api/graphql",
bearerToken: process.env.SLASHWORK_API_TOKEN,
groupMappings: { C01234567: "group-id-abc" },
getSlackUsername: async (userId) => {
const result = await slackClient.users.info({ user: userId });
return result.user?.real_name || result.user?.name || "";
},
});Setting Up Slack
- Create a Slack App at api.slack.com/apps
- Enable Event Subscriptions and set your Request URL to your webhook endpoint
- Subscribe to the
message.channelsbot event (and/ormessage.groupsfor private channels) - Install the app to your workspace
- Note the channel IDs you want to mirror (visible in channel details or via the Slack API)
- Invite the app/bot into each channel you want to mirror
TypeScript
This package includes TypeScript definitions. Key exports:
import {
createSlackWebhook,
SlackWebhookConfig,
SlackWebhookHandler,
SlackWebhookRequest,
SlackWebhookResponse,
SlackIdMap,
SlackWebhookPayload,
SlackUrlVerification,
EnvelopedEvent,
SlackEvent,
} from "slack-to-slashwork";License
MIT
