jira-ai-fixer/api/routers/webhook.py

80 lines
2.2 KiB
Python

"""
Webhook handlers for JIRA and Bitbucket events.
"""
from fastapi import APIRouter, Request, HTTPException, Header
from typing import Optional
import hmac
import hashlib
import logging
logger = logging.getLogger(__name__)
router = APIRouter()
def verify_jira_signature(payload: bytes, signature: str, secret: str) -> bool:
"""Verify JIRA webhook signature."""
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
@router.post("/jira")
async def jira_webhook(
request: Request,
x_atlassian_webhook_identifier: Optional[str] = Header(None),
):
"""
Handle JIRA webhook events.
Events processed:
- jira:issue_created
- jira:issue_updated
"""
body = await request.body()
data = await request.json()
event_type = data.get("webhookEvent", "unknown")
issue = data.get("issue", {})
issue_key = issue.get("key", "unknown")
logger.info(f"📥 JIRA webhook: {event_type} - {issue_key}")
# Filter: only process Support Cases
issue_type = issue.get("fields", {}).get("issuetype", {}).get("name", "")
if issue_type != "Support Case":
logger.info(f"⏭️ Skipping non-Support Case issue: {issue_key} ({issue_type})")
return {"status": "skipped", "reason": "not a Support Case"}
# Queue for analysis
# TODO: Implement queue system
logger.info(f"📋 Queuing Support Case for analysis: {issue_key}")
return {
"status": "accepted",
"issue": issue_key,
"event": event_type,
}
@router.post("/bitbucket")
async def bitbucket_webhook(request: Request):
"""
Handle Bitbucket webhook events.
Events processed:
- repo:refs_changed (push)
- pr:merged
"""
data = await request.json()
event_type = data.get("eventKey", "unknown")
logger.info(f"📥 Bitbucket webhook: {event_type}")
if event_type == "repo:refs_changed":
# Re-index affected files
changes = data.get("changes", [])
for change in changes:
ref = change.get("ref", {}).get("displayId", "")
logger.info(f"🔄 Branch updated: {ref}")
return {"status": "accepted", "event": event_type}