Skip to content

Slack Integration Guide

This guide explains how to configure Slack integration for sharing regulatory updates from Carver Horizon to your Slack workspace.

Overview

Carver Horizon supports two methods for Slack integration:

  1. Bot Token (Recommended): Allows users to choose which channel to share updates to
  2. Webhook URL: Shares updates to a pre-configured channel

Prerequisites

  • Access to your Slack workspace's admin settings
  • Ability to create and install Slack apps

Configuration Methods

This method allows users to select which channel to share updates to when clicking the "Share to Slack" button.

Step 1: Create a Slack App

  1. Go to https://api.slack.com/apps
  2. Click "Create New App"
  3. Select "From scratch"
  4. Enter app name: Carver Horizon (or your preferred name)
  5. Select your workspace
  6. Click "Create App"

Step 2: Configure Bot Token Scopes

  1. In your app settings, go to "OAuth & Permissions" in the left sidebar
  2. Scroll down to "Scopes" section
  3. Under "Bot Token Scopes", add the following scopes:
  4. chat:write - Send messages to channels
  5. chat:write.public - Send messages to public channels without joining
  6. channels:read - View basic channel information

Step 3: Install App to Workspace

  1. Scroll to the top of the "OAuth & Permissions" page
  2. Click "Install to Workspace"
  3. Review the permissions
  4. Click "Allow"

Step 4: Copy Bot Token

  1. After installation, you'll see the "Bot User OAuth Token"
  2. It starts with xoxb-
  3. Click "Copy" to copy the token

Step 5: Add to Environment Variables

Add the bot token to your .env file:

SLACK_BOT_TOKEN=xoxb-your-actual-bot-token-here

Step 6: Invite Bot to Channels

For the bot to post to channels, it needs to be added:

  1. Open the Slack channel where you want to receive updates
  2. Type: /invite @Carver Horizon (or your app name)
  3. Alternatively, the bot can post to public channels without being invited if you added the chat:write.public scope

Method 2: Webhook URL (Simple)

This method sends all updates to a single pre-configured channel.

Step 1: Create a Slack App

Follow steps 1-3 from Method 1 (Create a Slack App)

Step 2: Enable Incoming Webhooks

  1. In your app settings, go to "Incoming Webhooks" in the left sidebar
  2. Toggle "Activate Incoming Webhooks" to On
  3. Click "Add New Webhook to Workspace"
  4. Select the channel where updates should be posted
  5. Click "Allow"

Step 3: Copy Webhook URL

  1. You'll see your webhook URL in the format:
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXX
    
  2. Click "Copy" to copy the webhook URL

Step 4: Add to Environment Variables

Add the webhook URL to your .env file:

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL

Using Both Methods

You can configure both methods simultaneously. The system will prefer the Bot Token method when available, falling back to the webhook for simpler deployments.

Restart Services

After adding the configuration to .env, restart the backend service:

docker-compose restart backend

Testing the Integration

  1. Log in to the Carver Horizon dashboard
  2. Navigate to Regulatory Institutions
  3. Click on any institution to view recent updates
  4. Click on an update to view details
  5. Click the "Share to Slack" button

With Bot Token: - A modal will appear to select the channel - Choose your channel from the dropdown - Click "Share to Slack"

With Webhook: - The update will be shared directly to the configured channel

Message Format

Slack messages include:

  • Header: "📋 New Regulatory Update"
  • Title: Clickable link to the original source
  • Institution: Name of the regulatory institution
  • Published Date: When the update was published
  • Summary: One-line or five-point summary (if available)
  • Action Button: "View Full Article" button linking to the source

Troubleshooting

"Slack is not configured" Error

Problem: Button is disabled with message "Slack is not configured"

Solution: 1. Verify SLACK_BOT_TOKEN or SLACK_WEBHOOK_URL is set in .env 2. Restart the backend service: docker-compose restart backend 3. Check backend logs: docker-compose logs backend | grep -i slack

"channel_not_found" Error

Problem: Error when trying to share to a channel

Solution: 1. Make sure the bot is invited to the channel: /invite @Carver Horizon 2. For public channels, ensure you have the chat:write.public scope 3. Verify the bot token is correct and hasn't expired

"not_in_channel" Error

Problem: Bot cannot post to the channel

Solution: - Invite the bot to the channel: /invite @Carver Horizon

No Channels Appear in Dropdown

Problem: The channel selector is empty

Solution: 1. Ensure you're using a Bot Token (not webhook) 2. Verify the bot has channels:read scope 3. Check that the bot token is correctly set in .env 4. Restart backend: docker-compose restart backend

Security Considerations

  • Never commit tokens to git: Keep .env in .gitignore
  • Use environment variables: Don't hardcode tokens in code
  • Rotate tokens regularly: Create new tokens periodically
  • Limit scopes: Only grant the minimum required permissions
  • Monitor usage: Review Slack app activity regularly

Advanced Configuration

Custom Channel Selection

If you want to restrict which channels users can share to, you can modify the backend to filter channels:

Edit /backend/services/slack_service.py:

def get_channels(self):
    # ... existing code ...

    # Filter to specific channels
    allowed_channels = ['general', 'regulatory-updates', 'compliance']
    channels = [
        ch for ch in channels
        if ch['name'] in allowed_channels
    ]

    return {"success": True, "channels": channels}

Default Channel

To set a default channel when using Bot Token method, modify the frontend:

Edit /admin-dashboard/components/UserTopicsSubscription.tsx:

// In loadSlackConfig function
if (config.has_bot_token) {
  const channels = await slackAPI.getChannels()
  setSlackChannels(channels)
  // Set default channel
  const defaultChannel = channels.find(ch => ch.name === 'regulatory-updates')
  if (defaultChannel) {
    setSelectedSlackChannel(defaultChannel.id)
  }
}

API Reference

Backend Endpoints

POST /api/v2/feeds/slack/share

Share a feed entry to Slack.

Body:

{
  "entry_id": "uuid-of-feed-entry",
  "channel": "C1234567890" // Optional channel ID
}

Response:

{
  "success": true,
  "message": "Successfully shared to Slack"
}

GET /api/v2/feeds/slack/channels

Get list of available Slack channels.

Response:

{
  "success": true,
  "channels": [
    {
      "id": "C1234567890",
      "name": "general",
      "is_private": false
    }
  ]
}

GET /api/v2/feeds/slack/config

Get Slack configuration status.

Response:

{
  "configured": true,
  "has_bot_token": true,
  "has_webhook": false,
  "method": "bot"
}

Support

For issues or questions: 1. Check the troubleshooting section above 2. Review Slack API logs: docker-compose logs backend | grep -i slack 3. Verify app configuration at https://api.slack.com/apps 4. Contact your system administrator

Additional Resources