🚀 Bridge the gap between Slack discussions and GitHub issues
A powerful Slack integration that seamlessly exports thread conversations as formatted comments to GitHub issues. Perfect for development teams who discuss features, bugs, and decisions in Slack but need to document them in GitHub.
This Ruby Sinatra application provides a bridge between Slack and GitHub, allowing you to easily share Slack thread discussions as comments on GitHub issues. When you use the slash command with a GitHub issue URL, it will collect all messages in the current thread and post them as a formatted comment to the specified GitHub issue.
See the tool in action! This demo shows how a Slack thread conversation gets beautifully formatted and posted to a GitHub issue:
slack-github-threads-demo.mp4
📋 Live Example: Check out Issue #12 to see a real Slack thread that was exported using this tool.
Ready to get started? Here's the fastest way to set up slack-github-threads:
- Create your Slack app using our app manifest (just 2 minutes!)
- Deploy to your server or run locally with Docker
- Start exporting threads with
/ghcomment [github-issue-url]
👉 New to this? Follow our detailed setup guide for step-by-step instructions.
- 🔗 Slack Integration: Works seamlessly as a Slack slash command and shortcuts
- 📝 Thread Collection: Captures entire Slack thread conversations with user attribution
- 🐙 GitHub Integration: Posts beautifully formatted comments to GitHub issues
- ⚡ Instant Setup: One-click app creation using Slack app manifest
- 🚀 Easy Deployment: Configured for deployment with Kamal or Docker
- 🔒 Secure: Uses environment variables for sensitive tokens
- 🎯 Smart Formatting: Preserves message structure, usernames, and timestamps
- 📱 Multiple Interfaces: Slash commands, message shortcuts, and global shortcuts
- Bridge Communication Gaps: Seamlessly move Slack discussions to GitHub where they belong
- Preserve Context: Keep the conversational flow and user attribution intact
- Save Time: No more copy-pasting individual messages or losing discussion context
- Team Collaboration: Make Slack conversations accessible to your entire development team
- Ruby 3.2+
- Bundler
- A Slack app with bot token permissions
- A GitHub personal access token
- (Optional) Kamal for deployment
-
Clone the repository:
git clone https://github.com/markhallen/slack-github-threads.git cd slack-github-threads
-
Install dependencies:
bundle install
-
Set up environment variables:
cp .env.example .env # Edit .env with your tokens
-
(Optional) Set up Kamal deployment secrets:
cp .kamal/secrets.example .kamal/secrets # Edit .kamal/secrets with your deployment credentials cp config/deploy.yml.example config/deploy.yml # Edit config/deploy.yml with your deployment settings
Create a .env
file with the following variables:
SLACK_BOT_TOKEN=xoxb-your-slack-bot-token
GITHUB_TOKEN=ghp_your-github-personal-access-token
DEBUG=false # Optional: set to 'true' for debug logging
You have two options for setting up your Slack app:
- Go to Slack API
- Click "Create New App"
- Select "From an app manifest"
- Choose your workspace
- Copy the contents of
docs/app-manifest.json
and paste it into the manifest editor - Replace
https://your-domain.com
with your actual domain (e.g.,https://your-app.ngrok.io
for local development) - Review and create the app
- Go to "OAuth & Permissions" and install the app to your workspace
- Copy the "Bot User OAuth Token"
-
Go to Slack API
-
Create a new app or use an existing one
-
Go to "OAuth & Permissions"
-
Add the following bot token scopes:
channels:history
- Read messages in public channelschannels:read
- List public channelschannels:join
- Join public channels automaticallygroups:history
- Read messages in private channelsgroups:read
- List private channelsim:history
- Read direct messagesmpim:history
- Read group direct messagesusers:read
- Get user information for name resolutionchat:write
- Post reply messages
Note: Even with these scopes, the bot may still need to be added to private channels manually.
-
Set up slash commands and shortcuts:
- Go to "Slash Commands" and create
/ghcomment
pointing tohttps://your-domain.com/ghcomment
- Go to "Interactivity & Shortcuts" and:
- Enable interactivity with Request URL:
https://your-domain.com/shortcut
- Add shortcuts as defined in the app manifest
- Enable interactivity with Request URL:
- Go to "Slash Commands" and create
-
Install the app to your workspace
-
Copy the "Bot User OAuth Token"
- Go to GitHub Settings > Developer settings > Personal access tokens
- Generate a new token with the following permissions:
repo
(for private repositories) orpublic_repo
(for public repositories only)
- Copy the generated token
-
Start the server:
bundle exec thin start -R config.ru -p 3000
-
Use a tool like ngrok to expose your local server:
ngrok http 3000
-
Configure your Slack slash command to point to
https://your-ngrok-url.ngrok.io/ghcomment
If you created your app using the manifest (Option 1 above), your slash commands and shortcuts are already configured. Simply update the URLs to match your deployment domain.
If you set up your app manually (Option 2), you'll need to configure:
- Slash Commands: Create
/ghcomment
pointing tohttps://your-domain.com/ghcomment
- Interactivity & Shortcuts:
- Enable interactivity with Request URL:
https://your-domain.com/shortcut
- Add message and global shortcuts as defined in
docs/app-manifest.json
- Enable interactivity with Request URL:
In a Slack thread, use the slash command with a GitHub issue URL:
/ghcomment https://github.com/owner/repo/issues/123
The bot will:
- Collect all messages in the current thread
- Format them with usernames
- Post the formatted conversation as a comment on the specified GitHub issue
This project is configured for deployment using Kamal.
-
Install Kamal:
gem install kamal
-
Set up your secrets (see
.kamal/secrets
file) -
Configure your deployment settings in
config/deploy.yml
(copy fromconfig/deploy.yml.example
)
kamal deploy
You can also run the application using Docker:
# Build the image
docker build -t slack-github-threads .
# Run the container
docker run -p 3000:3000 --env-file .env slack-github-threads
├── app.rb # Main Sinatra application
├── config.ru # Rack configuration
├── Gemfile # Ruby dependencies
├── Dockerfile # Docker configuration
├── Rakefile # Task definitions and test runner
├── docs/ # Documentation and configuration
│ └── app-manifest.json # Slack app manifest for easy setup
├── lib/ # Application modules
│ ├── services/ # Business logic services
│ │ ├── slack_service.rb # Slack API interactions
│ │ ├── github_service.rb # GitHub API interactions
│ │ ├── text_processor.rb # Message formatting and parsing
│ │ └── comment_service.rb # Main orchestration service
│ └── helpers/ # Helper modules
│ └── modal_builder.rb # Slack modal construction
├── test/ # Test suite
│ ├── test_helper.rb # Test configuration and helpers
│ ├── test_app.rb # Integration tests
│ └── services/ # Service unit tests
│ ├── test_slack_service.rb
│ ├── test_github_service.rb
│ └── test_text_processor.rb
├── config/
│ └── deploy.yml.example # Kamal deployment configuration template
└── .kamal/
└── secrets # Kamal secrets configuration
# Show available rake tasks and quick start guide
bundle exec rake help
# Run all CI checks (recommended for development)
bundle exec rake ci
# Code quality checks
bundle exec rake lint # Run linting (syntax + rubocop)
bundle exec rake rubocop # Run RuboCop linter only
bundle exec rake syntax # Check syntax only
# Testing
bundle exec rake test # Run all tests
# Run specific test groups
bundle exec rake test_services
bundle exec rake test_app
The application includes comprehensive logging and debug capabilities:
Enable debug mode to see detailed output during development:
# Enable debug mode (shows debug logs in console + log file)
DEBUG=true ruby app.rb
# Or set in your .env file
DEBUG=true
The application automatically creates environment-specific log files:
log/development.log
- Development environment logslog/production.log
- Production environment logslog/test.log
- Test environment uses in-memory logging (no file created)
- INFO: Application startup, successful operations
- DEBUG: Detailed API interactions, debugging information (only when DEBUG=true)
- ERROR: Failures, exceptions, API errors
Example log output:
I, [2025-08-02T09:55:53.928339 #94625] INFO -- : Starting gh-commenter app (development)
D, [2025-08-02T09:56:15.123456 #94625] DEBUG -- : DEBUG: Successfully posted Slack reply
E, [2025-08-02T09:56:20.654321 #94625] ERROR -- : Failed to post comment: GitHub API rate limit exceeded
The application follows Sinatra best practices with clear separation of concerns:
- Services: Handle external API interactions and business logic
- Helpers: Provide utility functions and UI components
- Controllers: Slim route handlers that delegate to services
- Tests: Comprehensive test coverage using Minitest with WebMock for API stubbing
GET /up
- Health check endpointPOST /ghcomment
- Processes Slack slash command and posts to GitHubPOST /shortcut
- Handles Slack shortcuts (global and message) and modal submissions
- Fork the repository
- Create a feature branch
- Make your changes
- Test your changes
- Submit a pull request
This project supports multiple release workflows: automated GitHub Actions, smart Rake tasks, and interactive scripts.
Create releases directly from GitHub's web interface:
- Go to Actions tab → "Create Release" workflow
- Click "Run workflow" and choose:
auto
- Let the system analyze commits and suggest release typemajor/minor/patch
- Specify release type manuallydry_run
- Preview what would be released
- The release is created immediately - no PR needed!
- GitHub release is automatically published with changelog
# Preview changes and get version suggestion
rake release:preview
# Create releases by type (automatic version bumping)
rake release:major # Breaking changes (1.0.0 → 2.0.0)
rake release:minor # New features (1.0.0 → 1.1.0)
rake release:patch # Bug fixes (1.0.0 → 1.0.1)
# Push to trigger automated GitHub release
git push origin main && git push origin v<version>
# Interactive script with smart suggestions
./scripts/release.sh
# Or specify release type directly
./scripts/release.sh minor
- 🤖 Fully Automated: GitHub Actions handles everything including PR creation
- 🧠 Smart Version Detection: Analyzes commits to suggest appropriate version bump
- 📝 Automatic Changelog: Generates changelog from conventional commit messages
- 🚀 One-Click Releases: Complete release process with testing and validation
- 📋 Preview Mode: See what will be released before committing
- 👥 Team Friendly: PR-based workflow for team review
For optimal automatic changelog generation:
feat: add new feature
→ Added section → minor version bumpfix: resolve bug
→ Fixed section → patch version bumpfeat!: breaking change
→ Added section → major version bumpchore: update dependencies
→ Changed section → patch version bump
See docs/CONVENTIONAL_COMMITS.md for detailed commit message guidelines.
- Never commit tokens or secrets to the repository
- Use environment variables for all sensitive data
- Regularly rotate your API tokens
- Use HTTPS in production
This project is licensed under the MIT License - see the LICENSE file for details.
If you encounter any issues or have questions, please open an issue on GitHub.