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 configuration

  • GraphQL: createFeed mutation

  • Entity 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 feed

  • type (FeedTypes): Must be SLACK

  • slack (SlackFeedPropertiesInput): Slack-specific configuration

SlackFeedPropertiesInput (Required)

  • type (FeedServiceTypes): SLACK_CONVERSATION for channels

  • token (string): Slack OAuth token

    • Requires channels:read, channels:history, groups:read, groups:history scopes

    • Bot token format: xoxb-...

  • channels (SlackChannelInput[]): Channels to sync

    • Get channel IDs from querySlackChannels()

  • readMessages (boolean): Sync channel messages (recommended: true)

  • readThreads (boolean): Sync message threads (recommended: true)

Optional

  • correlationId (string): For tracking in production

  • collections (EntityReferenceInput[]): Auto-add synced messages to collections

  • workflow (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 channels

  • channels:history - Read public channel messages

  • groups:read - List private channels (if needed)

  • groups:history - Read private channel messages (if needed)

  • users:read - Get user information

Getting a Slack Token:

  1. Create Slack App at https://api.slack.com/apps

  2. Add OAuth scopes under "OAuth & Permissions"

  3. Install app to workspace

  4. 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 sync

Important: 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?