-
Notifications
You must be signed in to change notification settings - Fork 918
Add GitHub and Slack webhook integrations with emoji reaction actions (and new incoming/outgoing webhooks UI) #2285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduces models, controllers, jobs, and views for integrating GitHub repositories with boards. Supports syncing pull requests, issues, comments, and reviews as cards and comments, with per-account and per-integration event toggles. Adds webhook endpoint, delivery tracking, admin UI for managing integrations, and migrations for new tables. Updates routes and recurring tasks for delivery cleanup.
Introduces a new string column 'color' with a default value to the github_integrations table to support color customization.
Introduces Slack integration models, controllers, jobs, and views to support syncing messages, thread replies, and reactions from Slack channels to cards. Adds emoji-to-action mapping for Slack reactions, global and per-integration event controls, delivery tracking, and feedback to Slack. Includes migrations, tests, and documentation for the new Slack integration features.
Refactors the webhooks index page to separate incoming and outgoing webhooks into distinct panels. Adds descriptions for each section, renders partials for incoming integrations (GitHub, Slack), and updates the outgoing webhooks list and creation button with improved layout and permissions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds comprehensive GitHub and Slack webhook integrations to Fizzy, enabling automatic card creation from GitHub pull requests/issues and Slack messages, plus emoji reaction-based workflow actions. The implementation includes webhook signature verification, async job processing, account-level settings, and extensive UI for configuration.
Key Changes:
- Webhook-based integrations for GitHub (PRs, issues, comments, reviews) and Slack (messages, threads, emoji reactions)
- Emoji reaction actions for Slack that can move cards, close, postpone, or reopen them
- Account-level and board-level event filtering
- Auto-detection of Slack bot user ID from webhook payloads
Reviewed changes
Copilot reviewed 74 out of 74 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
app/models/slack_integration.rb |
Core Slack integration logic with bot mentions, emoji actions, and thread replies |
app/models/github_integration.rb |
GitHub webhook processing for PRs and issues with HMAC verification |
app/controllers/slack/webhooks_controller.rb |
Unauthenticated Slack webhook endpoint with signature verification |
app/controllers/github/webhooks_controller.rb |
Unauthenticated GitHub webhook endpoint with HMAC-SHA256 verification |
app/jobs/slack/webhook_processor_job.rb |
Async Slack webhook processing with account owner attribution |
app/jobs/github/webhook_processor_job.rb |
Async GitHub webhook processing with system user attribution |
db/migrate/* |
Eight migrations creating integration tables and settings |
test/models/* |
Comprehensive test coverage for models and integrations |
app/views/slack_integrations/* |
UI for managing Slack integrations with emoji mapping configuration |
app/views/github_integrations/* |
UI for managing GitHub integrations with color-coded repositories |
config/recurring.yml |
Cleanup job for stale GitHub delivery records |
docs/*.md |
Detailed documentation for both integrations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| card, | ||
| script_name: account.slug, | ||
| host: Rails.application.config.action_mailer.default_url_options[:host], | ||
| protocol: 'http' |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The card_url method uses hardcoded protocol: 'http' which should typically use https in production environments. This could cause security warnings or issues when accessing the URLs from Slack.
| protocol: 'http' | |
| protocol: 'https' |
| def emoji_action_mappings | ||
| value = read_attribute(:emoji_action_mappings) | ||
| return {} if value.nil? | ||
| return value if value.is_a?(Hash) | ||
|
|
||
| # If it's a string, try to parse it (shouldn't happen with :json attribute, but defensive) | ||
| if value.is_a?(String) | ||
| begin | ||
| parsed = JSON.parse(value) | ||
| return parsed.is_a?(Hash) ? parsed : {} | ||
| rescue JSON::ParserError | ||
| Rails.logger.error "Failed to parse emoji_action_mappings: #{value}" | ||
| return {} | ||
| end | ||
| end | ||
|
|
||
| {} | ||
| end |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The emoji_action_mappings getter method has defensive error handling and logging, but returns an empty hash on JSON parse errors. Consider whether this silent failure is appropriate, or if validation should prevent invalid JSON from being stored in the first place.
| cleanup_github_integration_deliveries: | ||
| command: "GithubIntegration::Delivery.cleanup" | ||
| schedule: every 4 hours at minute 55 |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cleanup_github_integration_deliveries recurring job references GithubIntegration::Delivery.cleanup, but there's no corresponding cleanup_slack_integration_deliveries job for SlackIntegration::Delivery.cleanup, even though both delivery models implement the same cleanup method. This inconsistency could lead to unbounded growth of Slack delivery records.
northeastprince
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would create a Github and Slack namespace as opposed to starting multiple classes with the same prefix.
thanks @northeastprince -- appreciate the feedback; that's a good point. i'll refactor this PR accordingly ✌️ |
|
Thanks @shawntz, we really appreciate your work here. Integrating with third-party systems is a very interesting area of functionality for us, too. The problem here is that this is a very large change, and we have some ideas about how to implement it that would differ quite a bit regarding this proposal. The differences are too big to correct via PR reviewing so I need to close this one without merging. Sorry about that, and thanks again for your effort. |
|
Thanks @jorgemanrubia – appreciate the update and totally understand. Not sure what your current plans for implementation are, but I could envision a similar type of "open a door to" workflow like those in Basecamp. Curious to see where things go with this! |
Description
Allows boards to sync GitHub pull requests and issues to Fizzy cards via webhooks. Board admins configure webhooks directly in their GitHub repository settings—no OAuth or server-side GitHub App required. Moreover, allows boards to sync Slack messages to Fizzy cards via webhooks and control card state through emoji reactions. Board admins configure webhooks using their Slack app settings; again, no OAuth or server-side Slack App required beyond basic bot setup.
Motivation
Development teams often track work across multiple tools. This integration brings GitHub activity into Fizzy automatically, reducing manual card creation and keeping work visible in one place.
The webhook-only approach keeps setup simple: no API tokens to manage, no rate limits to worry about, and users control the integration entirely from GitHub's UI.
Furthermore, teams already discuss work in Slack. This integration captures those conversations as cards in Fizzy automatically and enables lightweight workflow control through emoji reactions, reducing context switching and keeping work discussions linked to trackable cards.
The webhook-only approach keeps setup straightforward: configure once in Slack, automatic bot user detection, and reaction-based actions provide intuitive card management without leaving Slack.
GitHub Integration
How It Works
Setup
Event Support
Card Creation
Implementation
Database
github_integrations- board-scoped repository configurations with webhook secretsgithub_items- links cards to GitHub issues/PRs (prevents duplicates)github_integration_deliveries- webhook delivery logs for debuggingaccount_github_settings- account-level event filteringControllers
Models
GithubIntegration- sync logic and event filteringGithubIntegration::Colored- color picker support (reuses existingColorpattern)GithubItem- join modelCard#add_github_commentandCard#add_github_review- extends existing card modelJobs
Github::WebhookProcessorJob- async processing via Solid QueueCurrent.userfor event callbacksSecurity
UI
Board Settings
Integration Management
Integration Detail
Tested
Limitations
Migration
Creates four tables:
github_integrations,github_items,github_integration_deliveries,account_github_settings.Slack Integration
How It Works
Setup
Message Syncing
Emoji Reaction Actions
@mentioning the bot in Slack creates a card. Bot replies with card link and emoji action instructions.
Reacting with mapped emoji triggers action. Bot confirms with "✅ Card moved to Done" message.
Configure emoji reactions to map to column moves, close, postpone, or reopen actions.
Implementation
Database
slack_integrations- board-scoped channel configurations with webhook secretsslack_items- links cards to Slack messages (prevents duplicates, enables reactions)slack_integration_deliveries- webhook delivery logs for debuggingaccount_slack_settings- account-level event filteringbot_user_idandbot_oauth_token- auto-detected from webhooks and user inputemoji_action_mappings- JSON column storing emoji→action configurationControllers
Models
SlackIntegration- sync logic, bot mention detection, emoji action executionSlackIntegration#message_mentions_bot?- checks for bot user ID in messageSlackIntegration#send_thread_reply- posts confirmation to threadSlackIntegration#send_emoji_action_feedback- posts action result to threadSlackIntegration#execute_emoji_action- handles all emoji actions with state transitionsSlackIntegration#strip_bot_mention- cleans message text for card contentSlackIntegration::Colored- color picker supportSlackItem- join model tracking message timestampCard#add_slack_commentandCard#add_slack_reaction- extends existing card modelJobs
Slack::WebhookProcessorJob- async processing via Solid QueueCurrent.userto account owner for proper attributionSecurity
Auto-Detection
authorizationsarrayCustomizable Slack channel integrations in Fizzy UI.
Bot User ID is auto-detected. Setup instructions guide through Slack app configuration with specific scopes and events.
UI
Board Settings
Integration Management
Integration Detail
Integration Edit
Account Settings
Features
Smart State Transitions
Proper Attribution
Thread Feedback
Caption: Cards created from Slack show account owner as creator, not "System".
Tested
Configuration
Required Slack App Scopes
channels:history- Receive channel messagesreactions:read- Receive emoji reactionschat:write- Send thread reply confirmationsRequired Slack App Events
message.channels- Channel messagesreaction_added- Emoji reactionsSetup Flow
/invite @BotName)Upgraded webhooks UI to separate out incoming/outgoing webhooks.
Limitations
Migration
Creates four tables:
slack_integrations,slack_items,slack_integration_deliveries,account_slack_settings.Adds
bot_user_idandbot_oauth_tokencolumns toslack_integrations.Cheers,
Shawn Schwartz (@shawntz) (ex-Slack Data)