send a message to the #project-blt-bacon channel when a new claim is made on the claim portal. use the slack integration for the owasp-blt org
Which claim portal ? u are talking about here
/assign
Hello @cicada0007! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.
⏰ This issue has been automatically unassigned due to 24 hours of inactivity. The issue is now available for anyone to work on again.
/assign
Hello @mahii-17! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.
⏰ This issue has been automatically unassigned due to 24 hours of inactivity. The issue is now available for anyone to work on again.
@coderabbitai what's the progress on this issue and what is being asked here? and check for conflicts with any PRs or overlapping issues if any.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Fetch the issue details
echo "=== Issue #3754 Details ==="
gh issue view 3754 --json title,body,state,labels,assignees,createdAt,updatedAt,comments
echo -e "\n=== Related PRs ==="
# Search for PRs that mention this issue
gh pr list --search "3754" --state all --json number,title,state,author,createdAt --limit 10
echo -e "\n=== Related PRs (alternative search) ==="
# Also check if any PRs are linked to this issue
gh issue view 3754 --json closedByPullRequestsReferences
echo -e "\n=== Overlapping Issues (searching for 'claim' keyword) ==="
# Search for issues related to "claim" to find overlapping issues
gh issue list --search "claim in:title" --state open --json number,title,state,createdAt --limit 10
Length of output: 5203
🏁 Script executed:
#!/bin/bash
# Check details of PR #4030
echo "=== PR #4030 Details ==="
gh pr view 4030 --json title,state,isDraft,closedAt,mergedAt,comments,reviews,mergeable --comments 5
echo -e "\n=== PR #3806 Details ==="
gh pr view 3806 --json title,state,isDraft,closedAt,mergedAt,comments,reviews,mergeable --comments 5
echo -e "\n=== Searching for 'claim portal' references in codebase ==="
# Search for existing claim portal implementations
rg -i "claim.?portal" --type py --type js -n -C 2 | head -50
echo -e "\n=== Searching for bacon claim functionality ==="
rg -i "bacon.*claim|claim.*bacon" --type py --type js -n -C 2 | head -50
echo -e "\n=== Searching for Slack integration references ==="
rg -i "slack" --type py --type js -n -C 2 | head -50
Length of output: 3225
🏁 Script executed:
#!/bin/bash
# Check details of PR #4030 with correct syntax
echo "=== PR #4030 Details ==="
gh pr view 4030 --json title,state,isDraft,closedAt,mergedAt,body,labels
echo -e "\n=== PR #3806 Details ==="
gh pr view 3806 --json title,state,isDraft,closedAt,mergedAt,body,labels
echo -e "\n=== Searching for 'bacon' references in the codebase ==="
rg -i "bacon" --type py -n -C 2 | head -80
echo -e "\n=== Searching for claim-related models and views ==="
rg -i "class.*claim" --type py -n -C 3 | head -60
echo -e "\n=== Check if there are any bacon-related models ==="
fd -e py -x grep -l "bacon" {} \;
Length of output: 12697
🏁 Script executed:
#!/bin/bash
# Search for BaconSubmission model and related views
echo "=== BaconSubmission Model and Views ==="
rg "BaconSubmission" --type py -n -C 5
echo -e "\n=== Check for bacon claim submission views ==="
rg "def.*submit|class.*Submit" --type py -n -C 3 | grep -i bacon -A 5 -B 5
echo -e "\n=== Check migration 0209 for BaconSubmission ==="
cat website/migrations/0209_baconsubmission.py 2>/dev/null || echo "File not found or not accessible"
echo -e "\n=== List all bacon-related files ==="
fd -e py | xargs grep -l "BaconSubmission" 2>/dev/null
Length of output: 15048
@Pritz395 Based on my analysis, here's the complete picture:
📋 What's Being Asked
Issue #3754 requests adding Slack notifications to the #project-blt-bacon channel whenever a user submits a new BACON token claim through the claim portal.
The "claim portal" (which confused @igennova) refers to the BaconSubmission system where users can claim BACON tokens for their contributions:
- Endpoint:
/api/bacon/submit/ - View:
BaconSubmissionViewinwebsite/views/bitcoin.py(line 84) - Users submit GitHub PR URLs with contribution details to claim BACON rewards
📊 Progress Status
Current State: Issue is OPEN and available to work on
History:
-
Assigned twice, both contributors unassigned due to 24-hour inactivity:
- @cicada0007 (Mar 4, 2025)
- @mahii-17 (Mar 22, 2025)
-
Two PRs attempted to fix it but both were CLOSED (not merged):
- PR #4030 by @mahii-17 - Most relevant attempt
- Added Slack integration using
slack_sdk.WebClient - Sent messages to #project-blt-bacon on new bacon claims
- Closed on April 5, 2025 without merging
- Added Slack integration using
- PR #3806 by @cicada0007 - Less relevant
- Focused on bug report alerts, not bacon claims
- Also claimed to close #3754 but addressed wrong feature
- Closed on March 5, 2025
- PR #4030 by @mahii-17 - Most relevant attempt
🔍 Conflicts & Overlapping Issues
✅ No conflicts found:
- No currently active PRs working on this issue
- No overlapping open issues with similar requirements
- Slack integration infrastructure already exists in
website/views/slackbot.py - Ready for a fresh implementation attempt
💡 Recommendation
The issue is clear and ready to be worked on. A contributor would need to:
- Add Slack notification logic to
BaconSubmissionView.post()method - Use existing Slack integration (SLACK_BOT_TOKEN from environment)
- Send message to #project-blt-bacon channel with claim details
- Reference PR #4030 for implementation approach (though don't copy directly)
Would you like me to help assign this to someone or create a more detailed implementation plan?
@coderabbitai the maintainer specifically mentioned "we want this to be database driven, the org already has the connection to slack through integrations". Give me the workflow of what needs to be done for this issue to be resolved.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Get all comments on issue #3754 to find maintainer's comment
echo "=== All Comments on Issue #3754 ==="
gh issue view 3754 --json comments --jq '.comments[] | "Author: \(.author.login)\nDate: \(.createdAt)\nBody: \(.body)\n---"'
echo -e "\n=== Search for Integration models ==="
rg "class.*Integration" --type py -n -C 5
echo -e "\n=== Search for Slack integration in models ==="
rg -i "slack.*integration|integration.*slack" --type py -n -C 3
echo -e "\n=== Search for notification or alert systems ==="
rg "def.*notify|class.*Notification|def.*send_alert" --type py -n -C 3 | head -100
echo -e "\n=== Check for Integration usage with BaconSubmission ==="
rg "Integration" --type py -n -C 3 | grep -i "bacon\|notification\|slack" -A 3 -B 3
Length of output: 62603
🏁 Script executed:
#!/bin/bash
# Get PR #4030 comments to find maintainer feedback
echo "=== PR #4030 Comments ==="
gh pr view 4030 --json comments --jq '.comments[] | "Author: \(.author.login)\nDate: \(.createdAt)\nBody: \(.body)\n---"'
echo -e "\n=== Check BaconSubmissionView implementation ==="
cat website/views/bitcoin.py | grep -A 50 "class BaconSubmissionView"
echo -e "\n=== Find OWASP BLT organization references ==="
rg "OWASP.?BLT" --type py -n -C 2
Length of output: 49598
@Pritz395 Perfect! I found the maintainer's feedback. Here's the complete workflow for implementing this database-driven Slack notification system:
🔄 Implementation Workflow for Issue #3754
Context: Why "Database-Driven"?
The maintainer rejected previous PRs because they used the SLACK_BOT_TOKEN environment variable directly. Instead, the codebase has an Integration system where organizations configure their Slack connections through the UI, and the tokens are stored in the database.
📋 Step-by-Step Implementation
Step 1: Understand the Database Models
Located in website/models.py:
# Organization (line 72-80)
class Organization(models.Model):
name = models.CharField(max_length=255)
# ... other fields
# Integration (line 87-102)
class Integration(models.Model):
organization = models.ForeignKey(Organization)
service_name = models.CharField() # e.g., "slack"
# SlackIntegration (line 105-126)
class SlackIntegration(models.Model):
integration = models.OneToOneField(Integration)
bot_access_token = models.CharField() # Bot token stored here
workspace_name = models.CharField()
default_channel_id = models.CharField() # Channel ID to post to
default_channel_name = models.CharField() # e.g., "project-blt-bacon"
Step 2: Locate the Target Code
File: website/views/bitcoin.py
Class: BaconSubmissionView (starting at line 84)
Method: post() method (lines 85-130)
Current behavior: Creates a BaconSubmission record, returns JSON response. No Slack notification.
Step 3: Follow Existing Patterns
The codebase already has 3 working examples of database-driven Slack:
Example 1: website/utils.py (lines 886-900)
def send_tweet_to_slack(...):
from website.models import Organization, SlackIntegration
# 1. Find OWASP BLT organization
owasp_org = Organization.objects.filter(name__icontains="OWASP BLT").first()
# 2. Get its Slack integration
slack_integration = SlackIntegration.objects.filter(
integration__organization=owasp_org
).first()
# 3. Use token and channel from database
bot_token = slack_integration.bot_access_token
channel_id = slack_integration.default_channel_id
# 4. Send message using slack_sdk
from slack_sdk import WebClient
client = WebClient(token=bot_token)
client.chat_postMessage(channel=channel_id, text=message)
Example 2: blt/mail.py (lines 54-74) - Similar pattern
Example 3: website/management/commands/slack_daily_timelogs.py (lines 19-23) - Iterates over all SlackIntegrations
Step 4: Implementation Steps
Location: website/views/bitcoin.py → BaconSubmissionView.post() method
After line 128 (after submission = BaconSubmission.objects.create(...)), add:
# Step A: Import required modules
from website.models import Organization, SlackIntegration
from slack_sdk import WebClient
import logging
logger = logging.getLogger(__name__)
# Step B: Query the database for OWASP BLT's Slack integration
try:
owasp_org = Organization.objects.filter(name__icontains="OWASP BLT").first()
if owasp_org:
slack_integration = SlackIntegration.objects.filter(
integration__organization=owasp_org
).first()
if slack_integration and slack_integration.bot_access_token:
# Step C: Get credentials from database
bot_token = slack_integration.bot_access_token
# Use default channel or find #project-blt-bacon specifically
channel_id = slack_integration.default_channel_id
# Step D: Build the message
message = (
f"🥓 *New BACON Claim Submitted!*\n\n"
f"• *User:* {request.user.username}\n"
f"• *Type:* {contribution_type}\n"
f"• *PR:* {github_url}\n"
f"• *Description:* {description}\n"
f"• *Amount:* {bacon_amount} BACON\n"
f"• *Status:* {status}"
)
# Step E: Send to Slack
client = WebClient(token=bot_token)
client.chat_postMessage(
channel=channel_id,
text=message,
unfurl_links=False
)
logger.info(f"Slack notification sent for submission {submission.id}")
else:
logger.warning("Slack integration not configured for OWASP BLT")
else:
logger.warning("OWASP BLT organization not found")
except Exception as e:
# Don't fail the submission if Slack fails
logger.error(f"Failed to send Slack notification: {e}")
Step 5: Handle Channel Configuration
The default_channel_id might not be set to #project-blt-bacon. You have two options:
Option A: Use whatever channel is configured as default (simpler)
Option B: Search for #project-blt-bacon specifically:
# If default_channel_id is not set, try to find #project-blt-bacon
if not channel_id:
client = WebClient(token=bot_token)
channels = client.conversations_list(types="public_channel")
for channel in channels['channels']:
if channel['name'] == 'project-blt-bacon':
channel_id = channel['id']
break
Step 6: Testing Considerations
- Database Setup: Ensure OWASP BLT organization exists with Slack integration configured
- Channel Exists: Verify
#project-blt-baconchannel exists in the workspace - Bot Permissions: Bot must have
chat:writescope and be invited to the channel - Error Handling: Slack failure should NOT fail the bacon submission
Step 7: Files to Modify
| File | Changes |
|---|---|
website/views/bitcoin.py |
Add Slack notification logic after BaconSubmission.objects.create() |
| (Optional) Tests | Add test for Slack notification (mock WebClient) |
🎯 Key Differences from Failed PRs
| ❌ PR #4030 Approach | ✅ Correct Database-Driven Approach |
|---|---|
Used SLACK_BOT_TOKEN env var |
Query SlackIntegration.bot_access_token from database |
| Hardcoded channel mapping | Use SlackIntegration.default_channel_id |
| Not organization-aware | Filters by organization (OWASP BLT) |
| Direct Slack SDK usage | Follows existing pattern from website/utils.py |
📦 Required Dependencies
Already in the codebase:
- ✅
slack-sdk(imported in existing code) - ✅
SlackIntegrationmodel - ✅ Slack OAuth flow for setup
🔐 Configuration Requirements
Before the code works, admins must:
- Navigate to Organization Dashboard → Integrations
- Connect Slack via OAuth (
AddSlackIntegrationView) - Select
#project-blt-baconas the default channel - Save configuration
Database will then have:
Integrationrecord withservice_name='slack'andorganization=OWASP BLTSlackIntegrationrecord withbot_access_tokenanddefault_channel_id
✅ Success Criteria
- When a user submits a BACON claim via
/api/bacon/submit/ - The submission is created successfully
- A Slack notification is sent to
#project-blt-baconchannel - Message includes: username, contribution type, PR link, description, amount
- If Slack fails, the submission still succeeds (graceful degradation)
Would you like me to generate the actual code changes using the `` tag, or would you prefer to assign this to a contributor with these detailed instructions?
⏳ Preparing changes...
/assign
Hello @Pritz395! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.
This comment was generated by OWASP BLT-Action