Slack Loader
The Slack loader pulls messaging, channel, and user data from your Slack workspace into your data warehouse. It uses Slack’s Web API and supports incremental sync for messages based on timestamps.
Prerequisites
- A Slack workspace where you have admin permissions (or the ability to install apps)
- A connected Warehouse (target warehouse) with write permissions on the target schema
Authentication
The Slack loader uses OAuth 2.0 for authentication.
OAuth 2.0 Setup
- In SignalSmith, click Add Loader and select Slack
- Click Connect with Slack
- You’ll be redirected to Slack’s authorization page
- Select the workspace you want to connect
- Review the requested permissions and click Allow
- You’ll be redirected back to SignalSmith with the connection established
SignalSmith requests the following OAuth scopes:
| Scope | Purpose |
|---|---|
channels:read | List public channels and their metadata |
channels:history | Read message history from public channels |
groups:read | List private channels the bot is a member of |
groups:history | Read message history from private channels |
users:read | Read user profiles and status |
users:read.email | Read user email addresses |
team:read | Read workspace/team information |
reactions:read | Read emoji reactions on messages |
Channel Access
The Slack bot can only read messages from channels it has been invited to. For public channels, the bot has automatic read access. For private channels, you must manually invite the SignalSmith bot to each private channel you want to sync.
To invite the bot to a private channel:
- Open the private channel in Slack
- Type
/invite @SignalSmithor click the channel name > Integrations > Add an App
Available Objects
| Object | API Name | Description | Default Sync Mode |
|---|---|---|---|
| Messages | messages | Messages from selected channels with text, author, timestamp, and thread info | Incremental |
| Channels | channels | Public and private channel metadata (name, purpose, topic, member count) | Full Refresh |
| Users | users | User profiles with name, email, title, status, and timezone | Full Refresh |
| Reactions | reactions | Emoji reactions on messages (who reacted with what) | Incremental |
| Threads | threads | Thread parent messages with reply counts and participants | Incremental |
| User Groups | user_groups | User group definitions (handle, members) | Full Refresh |
| Workspace | workspace | Workspace-level metadata (name, domain, plan) | Full Refresh |
Messages
Messages are the primary data object and are extracted per channel. Each message includes:
| Field | Description |
|---|---|
ts | Message timestamp (Slack’s unique message ID) |
channel_id | Channel where the message was posted |
user_id | User who sent the message |
text | Message text content (with Slack markup) |
thread_ts | Parent thread timestamp (null for non-threaded messages) |
reply_count | Number of thread replies (for parent messages) |
subtype | Message subtype (e.g., channel_join, channel_topic, bot_message) |
attachments | Message attachments as JSON |
blocks | Block Kit content as JSON |
edited_ts | Timestamp when the message was last edited (if applicable) |
Channel Selection
After authentication, you select which channels to sync messages from. You can select:
- All public channels — Automatically includes new public channels as they’re created
- Specific channels — Select individual public and private channels
- By prefix/pattern — Select channels matching a naming pattern (e.g.,
support-*,sales-*)
Configuration
| Setting | Description | Default |
|---|---|---|
| Channels | Which channels to sync messages from | — (you choose during setup) |
| Objects | List of objects to sync | — (you choose during setup) |
| Sync Mode | Full Refresh or Incremental (per object) | Incremental |
| Message History | How far back to go for the initial backfill | Last 90 days |
| Include Bot Messages | Whether to include messages from bots and integrations | true |
| Include Threaded Replies | Whether to extract thread replies as separate rows | true |
| Primary Key | Field(s) that uniquely identify a record | channel_id + ts (messages) |
| Target Schema | Warehouse schema for Slack tables | — (required) |
| Table Prefix | Optional prefix for table names | slack_ |
| Schedule | Sync frequency | Hourly |
Scheduling Notes
- Rate limits: Slack’s Web API enforces tier-based rate limits. Most read methods are Tier 3 (50 requests per minute) or Tier 4 (100 requests per minute). The
conversations.historyendpoint is Tier 3. SignalSmith handles rate limiting with automatic backoff. - Message volume: Active Slack workspaces can generate thousands of messages per day across channels. Select only the channels relevant to your use case to manage data volume.
- History limits: Slack’s free plan retains only the most recent 90 days of message history. Paid plans (Pro, Business+, Enterprise Grid) retain full history. The loader can only extract what’s available in Slack.
- Edited messages: When a message is edited, its
ts(timestamp) remains the same but thetextcontent changes. Incremental sync captures edits when the channel is re-scanned. - Deleted messages: Deleted messages are not available via the Slack API. If a message is deleted between syncs, it remains in your warehouse from the previous extraction. Run a periodic full refresh to detect deletions.
- File content: Message attachments and files are referenced by URL but their content is not downloaded. Only file metadata (name, type, URL) is extracted.
- Private channels: The bot must be explicitly invited to private channels. Messages from private channels the bot hasn’t joined are not accessible.
Schema Mapping
Slack field types are mapped to warehouse-compatible types:
| Slack Type | Warehouse Type | Notes |
|---|---|---|
string | VARCHAR | |
timestamp | TIMESTAMP | Slack ts (Unix epoch with microseconds) converted to UTC |
integer | BIGINT | Counts like reply_count |
boolean | BOOLEAN | |
array | JSON / VARCHAR | Attachments, blocks, reactions |
object | JSON / VARCHAR | Nested structures like profile, edited |
Slack Markup
Message text contains Slack-specific markup:
<@U123ABC>— User mentions (user ID)<#C123ABC>— Channel mentions (channel ID)<https://example.com|Display Text>— Links with display text*bold*,_italic_,~strikethrough~— Formatting
Your models can parse or strip this markup as needed.
Troubleshooting
| Issue | Solution |
|---|---|
| ”not_authed” or “invalid_auth” | Token has been revoked. Re-authenticate by clicking “Reconnect" |
| "missing_scope” | The Slack app needs additional permissions. Reconnect to re-request scopes |
| ”ratelimited” | SignalSmith handles rate limits automatically. Reduce the number of channels or sync frequency if persistent |
| No messages from private channels | The bot must be invited to private channels. Use /invite @SignalSmith in each private channel |
| Missing message history | Free Slack plans only retain 90 days of messages. Upgrade to a paid plan for full history |
| Bot messages cluttering data | Set “Include Bot Messages” to false to exclude automated messages |
| Large message volume | Select fewer channels or increase the sync interval. Consider syncing only channels relevant to your analysis |
| User emails not appearing | The users:read.email scope is required to extract email addresses. Verify the scope was granted during authorization |
Common Use Cases
| Use Case | Description |
|---|---|
| Customer support analysis | Analyze support channel response times, volume trends, and topic frequency |
| Internal communications | Track engagement across teams, channels, and topics |
| Community analytics | Measure community health in shared Slack channels |
| Feedback mining | Extract product feedback from designated channels for analysis |
| Compliance archiving | Archive messages in your warehouse for regulatory compliance |
Next Steps
- Create a model to transform your raw Slack data
- Join Slack message data with CRM data to connect customer conversations to accounts
- Build engagement metrics dashboards for your Slack workspace