Create Slack Feed
User Intent
"I want to sync Slack channels into Graphlit for search and AI interactions"
Operation
SDK Method:
graphlit.createFeed()with Slack configurationGraphQL:
createFeedmutationEntity Type: Feed
Common Use Cases: Slack channel sync, team communication search, chat history RAG
TypeScript (Canonical)
import { Graphlit } from 'graphlit-client';
import {
ContentTypes,
FeedInput,
FeedListingTypes,
FeedTypes,
SearchTypes,
} from 'graphlit-client/dist/generated/graphql-types';
const graphlit = new Graphlit();
// Step 1: Query available Slack channels (requires OAuth token)
const channelsResponse = await graphlit.querySlackChannels({
token: process.env.SLACK_BOT_TOKEN!,
});
console.log(`Found ${channelsResponse.slackChannels.length} channels`);
// Step 2: Create Slack feed for specific channels
const feedInput: FeedInput = {
name: 'Engineering Slack',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channel: 'engineering',
token: process.env.SLACK_BOT_TOKEN!,
readMessages: true,
readThreads: true,
readLimit: 100,
includeAttachments: true,
},
};
const response = await graphlit.createFeed(feedInput);
const feedId = response.createFeed.id;
console.log(`Slack feed created: ${feedId}`);
// Step 3: Poll for feed completion
while (true) {
const status = await graphlit.isFeedDone(feedId);
if (status.isFeedDone.result) {
break;
}
console.log('Still syncing Slack messages...');
await new Promise((resolve) => setTimeout(resolve, 10_000));
}
console.log('Slack feed sync complete!');Parameters
FeedInput (Required)
name(string): Display name for the feedtype(FeedTypes): Must beSLACKslack(SlackFeedPropertiesInput): Slack-specific configuration
SlackFeedPropertiesInput (Required)
type(FeedServiceTypes):SLACK_CONVERSATIONfor channelstoken(string): Slack OAuth tokenRequires
channels:read,channels:history,groups:read,groups:historyscopesBot token format:
xoxb-...
channels(SlackChannelInput[]): Channels to syncGet channel IDs from
querySlackChannels()
readMessages(boolean): Sync channel messages (recommended: true)readThreads(boolean): Sync message threads (recommended: true)
Optional
correlationId(string): For tracking in productioncollections(EntityReferenceInput[]): Auto-add synced messages to collectionsworkflow(EntityReferenceInput): Apply workflow to messages
Response
{
createFeed: {
id: string; // Feed ID
name: string; // Feed name
state: EntityState; // ENABLED
type: FeedTypes.Slack; // SLACK
slack: {
channels: SlackChannel[];
readMessages: boolean;
readThreads: boolean;
}
}
}Developer Hints
OAuth Token Requirements
Slack OAuth Scopes Needed:
channels:read- List public channelschannels:history- Read public channel messagesgroups:read- List private channels (if needed)groups:history- Read private channel messages (if needed)users:read- Get user information
Getting a Slack Token:
Create Slack App at https://api.slack.com/apps
Add OAuth scopes under "OAuth & Permissions"
Install app to workspace
Copy Bot User OAuth Token (starts with
xoxb-)
Feed is Continuous Sync
// Feed continuously monitors for new messages
const feed = await graphlit.createFeed(feedInput);
// New messages appear automatically as content
// No need to manually trigger syncImportant: Feeds run continuously. To stop syncing, disable or delete the feed.
Polling for Initial Sync
// After creating feed, wait for initial sync
const feedId = response.createFeed.id;
let isDone = false;
while (!isDone) {
const status = await graphlit.isFeedDone(feedId);
isDone = status.isFeedDone.result || false;
if (!isDone) {
await new Promise(resolve => setTimeout(resolve, 10000));
}
}
// Now query synced messages
const messages = await graphlit.queryContents({
feeds: [{ id: feedId }],
types: [ContentTypes.Message]
});
console.log(`Synced ${messages.contents.results.length} messages`);Channel Discovery
// List all channels user has access to
const channels = await graphlit.querySlackChannels({
token: slackToken
});
// Filter to specific channels
const engineeringChannels = channels.slackChannels.filter(ch =>
ch.name.includes('eng-') || ch.name.includes('dev-')
);
// Create feed with filtered channels
const feedInput: FeedInput = {
name: 'Engineering Channels',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channels: engineeringChannels.map(ch => ({
id: ch.id,
name: ch.name
})),
readMessages: true,
readThreads: true,
token: slackToken
}
};Variations
1. Sync Specific Channels Only
Target specific channels by ID:
const feedInput: FeedInput = {
name: 'Support Channel',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channels: [
{ id: 'C1234567890', name: '#customer-support' }
],
readMessages: true,
readThreads: true,
token: slackToken
}
};2. Sync with Auto-Collection
Automatically add messages to a collection:
// Create collection first
const collectionResponse = await graphlit.createCollection({
name: 'Slack Messages'
});
// Create feed with collection
const feedInput: FeedInput = {
name: 'Team Slack',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channels: slackChannels,
readMessages: true,
readThreads: true,
token: slackToken
},
collections: [{ id: collectionResponse.createCollection.id }]
};3. Sync with Entity Extraction
Extract people and topics from messages:
// Create workflow for entity extraction
const workflowResponse = await graphlit.createWorkflow({
name: 'Extract Slack Entities',
extraction: {
jobs: [{
connector: {
type: EntityExtractionServiceTypes.ModelText,
modelText: {
extractedTypes: [
ObservableTypes.Person,
ObservableTypes.Organization,
ObservableTypes.Label
]
}
}
}]
}
});
// Create feed with workflow
const feedInput: FeedInput = {
name: 'Slack with Extraction',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channels: slackChannels,
readMessages: true,
readThreads: true,
token: slackToken
},
workflow: { id: workflowResponse.createWorkflow.id }
};4. Query Synced Messages
Search through synced Slack messages:
// After feed sync completes
const results = await graphlit.queryContents({
feeds: [{ id: feedId }],
types: [ContentTypes.Message],
search: 'deployment issues',
searchType: SearchTypes.Hybrid
});
results.contents.results.forEach(msg => {
console.log(`${msg.name}: ${msg.summary}`);
});5. Multi-Channel Pattern with Filtering
Sync multiple channels and filter by date:
const feedInput: FeedInput = {
name: 'Recent Engineering Discussions',
type: FeedTypes.Slack,
slack: {
type: FeedListingTypes.Past,
channels: [
{ id: 'C001', name: '#engineering' },
{ id: 'C002', name: '#architecture' },
{ id: 'C003', name: '#code-review' }
],
readMessages: true,
readThreads: true,
token: slackToken
}
};
const response = await graphlit.createFeed(feedInput);
// Wait for sync
await waitForFeedCompletion(response.createFeed.id);
// Query only recent messages
const lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() - 7);
const recentMessages = await graphlit.queryContents({
feeds: [{ id: response.createFeed.id }],
creationDateRange: {
from: lastWeek,
to: new Date()
}
});Common Issues
Issue: Invalid token error
Solution: Ensure Slack token has required OAuth scopes. Regenerate token with correct scopes.
Issue: Channel not found
Solution: Use querySlackChannels() to get exact channel IDs. User must have access to the channel.
Issue: Feed created but no messages syncing
Solution: Check readMessages: true is set. Verify token has channels:history scope.
Issue: Missing thread messages
Solution: Ensure readThreads: true is set. Threads are separate from main messages.
Issue: Feed sync taking too long
Solution: This is normal for channels with many messages. Use isFeedDone() to poll. Initial sync can take minutes for large channels.
Production Example
Last updated
Was this helpful?